Russian Qt Forum
Июнь 01, 2024, 12:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: "The program has unexpectedly finished" где ошибка? ((  (Прочитано 8483 раз)
Белый пони
Гость
« : Ноябрь 28, 2009, 01:11 »

имеется виджет с четырьмя QLabel'ами. Из потока в виджет поступают числа int. И надо чтобы они по очереди записывались в  1-ый, 2-ой, 3-ий, 4-ый, 1-ый и т.д. label'ы. Для этого я собрал лабелы в массив и сделал переменную которая задаёт номер лейбла куда записыват текущее число, полученное из цикла.

Вот главный виджет:
blinkWidget.h:
Код:
#include <QtGui/QWidget>
#include "mythread.h"

 namespace Ui
{
    class blinkWidgetClass;
}

class blinkWidget : public QWidget
{
    Q_OBJECT

public:
    blinkWidget(QWidget *parent = 0);
    ~blinkWidget();
    int currentRow;

public slots:
   void changeRow( int newRow);

private:
    Ui::blinkWidgetClass *ui;
    MyThread* mythread;
};

blinkWidget.cpp:
Код:
#include "blinkwidget.h"
#include "ui_blinkwidget.h"


blinkWidget::blinkWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::blinkWidgetClass)
{
    //currentRow = 2;
    ui->setupUi(this);
    QLabel* LabelArray[4] = { ui->myLab0, ui->myLab1, ui->myLab2, ui->myLab3 };
    mythread = new MyThread(parent);
    connect(ui->myGoBut, SIGNAL(clicked()), mythread, SLOT(start()));
    connect(ui->myStopBut, SIGNAL(clicked()), mythread, SLOT(terminate()));
    connect(mythread, SIGNAL(update_row(int)),  this, SLOT(changeRow(int)));
    connect(mythread, SIGNAL(update_hex(QString)), LabelArray[ currentRow ], SLOT(setText(QString)));
}

blinkWidget::~blinkWidget()
{
    delete ui;
}

void blinkWidget::changeRow( int newRow)
    {
    currentRow = newRow;
    }

Ну и поток на всякий случай:

mythread.h:
Код:
#include <QThread>

class MyThread : public QThread
 {

    Q_OBJECT

 public:
    MyThread(QObject* o):QThread(o) {     }
     void run();

 signals:
   void update_row(int);
   void update_hex( QString);

 };

mythread.cpp:
Код:
#include "mythread.h"

void MyThread::run()
 {
 int i = 0;
 int row = 2;

 while( i < 100)
     {
     i++;
     msleep(30);
     emit update_row( row );
     emit update_hex( QString::number(i, 16).toUpper() );
     row++;
     if(row == 4){row = 0;}
     }
  }


При компиляции никаких ошибок и предупреждений не находит((
Программа запускается и сразу останавливается.
Application output:
Цитировать
Starting /qtest/zikl array of labels/zikl...

The program has unexpectedly finished.

/qtest/zikl array of labels/zikl exited with code 0

Что же делать?(
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Ноябрь 28, 2009, 01:27 »

А что это за коннект такой?


Цитировать
connect(mythread, SIGNAL(update_hex(QString)), LabelArray[ currentRow ], SLOT(setText(QString)));

currentRow индекс  нигде неинициализирован, соответсвенно в нем мусор. При помощи этого мусора ты получаешь указатель неизвено куда - отсюда и вылет.

ЗЫ:

Цитировать
connect(ui->myStopBut, SIGNAL(clicked()), mythread, SLOT(terminate()));

Неисспользуй terminate(), это не есть нормальным завершением потока.

Цитировать
Warning: This function is dangerous and its use is discouraged. The thread can be terminate at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to cleanup after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Белый пони
Гость
« Ответ #2 : Ноябрь 28, 2009, 01:36 »

А что это за коннект такой?

Цитировать
connect(mythread, SIGNAL(update_hex(QString)), LabelArray[ currentRow ], SLOT(setText(QString)));

currentRow индекс  нигде неинициализирован, соответсвенно в нем мусор. При помощи этого мусора ты получаешь указатель неизвено куда - отсюда и вылет.

Я пытался его инициализировать в blinkWidget.cpp - закомментенная строка "currentRow = 2;", но в этом случае все числа записываются только в этот элемент Label под номером 2. Надо где-то в другом месте инициализировать? Или я объявил не там где надо? Непонимающий


Цитировать
Неисспользуй terminate(), это не есть нормальным завершением потока.

Да, читал(( Попробовал сначала quit(), но он сходу не заработал. Отложил эту проблему на потом)
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Ноябрь 28, 2009, 02:52 »

Как по мне, 2 сигнала ненужно, достаточно одного:

Код
C++ (Qt)
class MyThread : public QThread
{
...
signals:
  void update_row(int, const QString &text);
};

Код
C++ (Qt)
void MyThread::run()
{
...
    while( i < 100)
    {
         ...
        emit update_row( row, QString::number(i, 16).toUpper()  );
        ....
    }
....
}
 
Код
C++ (Qt)
class blinkWidget : public QWidget
{
...
public slots:
  void updateRow(int newRow, const QString &text);
...
};

Код
C++ (Qt)
connect(mythread, SIGNAL(update_row(int, const QString &)),  this, SLOT(updateRow(int, const QString &)));
 

Код
C++ (Qt)
void blinkWidget::updateRow( int newRow, const QString &text)
{
   QLabel *label = LabelArray[newRow];
   label->setText(text);
}
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Белый пони
Гость
« Ответ #4 : Ноябрь 28, 2009, 12:08 »

Спасибо! Улыбающийся
Сделал так.
А где объявлять и инициализировать массив LabelArray в этом случае?

пробовал в blinkWidget.h:
Код:
class blinkWidget : public QWidget
{
    Q_OBJECT

public:
    blinkWidget(QWidget *parent = 0);
    ~blinkWidget();
    int currentRow;
    QLabel* LabelArray[4];
...
Выдаётся две ошибки:
/qtest/zikl array of labels/blinkwidget.h:20: error: ISO C++ forbids declaration of ‘QLabel’ with no type
/qtest/zikl array of labels/blinkwidget.h:20: error: expected ‘;’ before ‘*’ token

Потом попробовал в ui_blinkWidget.h:
Код:
class Ui_blinkWidgetClass
{
public:
    QPushButton *myQuitBut;
    QPushButton *myGoBut;
    QPushButton *myStopBut;
    QLabel *myLab0;
    QLabel *myLab1;
    QLabel *myLab2;
    QLabel *myLab3;
QLabel* LabelArray[4];
...
Тут нормально объявилось. ( хотя я и не понял в чём разница)

Дальше пробую инициализировать в blinkWidget.cpp.
Если так:
Код:
blinkWidget::blinkWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::blinkWidgetClass)
{
    currentRow = 2;
    ui->setupUi(this);
    ui->LabelArray = { ui->myLab0, ui->myLab1, ui->myLab2, ui->myLab3 };
...

то выдаётся 2 ошибки:
/qtest/zikl array of labels/blinkwidget.cpp:10: error: expected primary-expression before ‘{’ token
/qtest/zikl array of labels/blinkwidget.cpp:10: error: expected `;' before ‘{’ token

А если так:
Код:
blinkWidget::blinkWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::blinkWidgetClass)
{
    ui->setupUi(this);
   
    ui->LabelArray[0] = ui->myLab0;
    ui->LabelArray[1] = ui->myLab1;
    ui->LabelArray[2] = ui->myLab2;
    ui->LabelArray[3] = ui->myLab3;
...
то всё работает как надо.

В принципе, программа работает. Но в будущем label'ов будет больше 4-ых, и в ручную из инициализировать будет долго.

Хочется на будущее понять, почему одно и то же объявелние в одним .h - файле работает, а в другом - нет? И как правильно инициализировать массив типа такого?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #5 : Ноябрь 28, 2009, 13:27 »

Сделай так:

Код
C++ (Qt)
#include <QList>
 
class QLabel;
 
class blinkWidget : public QWidget
{
   Q_OBJECT
 
public:
   blinkWidget(QWidget *parent = 0);
   ~blinkWidget();
 
   int currentRow;
   QList<QLabel *> LabelArray;
..
}

Код
C++ (Qt)
blinkWidget::blinkWidget(QWidget *parent)
   : QWidget(parent), ui(new Ui::blinkWidgetClass)
{
   ui->setupUi(this);
 
   LabelArray.append(ui->myLab0);
   LabelArray.append(ui->myLab1);
   LabelArray.append(ui->myLab2);
   LabelArray.append(ui->myLab3);
...
}

Доступ к i-му лейблу:

Код
C++ (Qt)
QLabel *label = LabelArray.at(i);
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Белый пони
Гость
« Ответ #6 : Ноябрь 29, 2009, 00:40 »

Понятно! Спасибо за помощь! Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.172 секунд. Запросов: 19.