Russian Qt Forum
Ноябрь 25, 2024, 00:03 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [QT4] как нормально связать GUI с Thread  (Прочитано 14616 раз)
IgorbIgorev
Гость
« : Декабрь 24, 2007, 14:50 »

приложение работает, но через раз!, сообщая о выполненной невыполнимой операции:)(пытается отправить отчет в микрософт)
код:
Код:
class MyThread : public QThread
{
    QTextEdit* textEdit;
    volatile int val;
  public:
    void set_textEdit(QTextEdit* p){textEdit=p;}
    void set_val(const int v){val=v;}
    void run();
};
class dlgTest: public QDialog, public Ui_dlgTest
{
    Q_OBJECT
    MyThread thread;
  public: 
    dlgTest(QWidget *parent=0); 
  public slots:
    void  on_pbSetThread_clicked();
};
dlgTest::dlgTest(QWidget *parent):QDialog(parent)
{
  setupUi(this);
  thread.set_textEdit(textEdit);
}
void dlgTest::on_pbSetThread_clicked()
{
  thread.set_val( spinBox->value() );
  thread.start();
}
void MyThread::run()
{
  int x;
  for (int i = 0; i <val; ++i)
  {
    x=i*2;
    textEdit->insertHtml ("test №"+QString::number(x)+" completed");
  }
}
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Декабрь 24, 2007, 14:54 »

Ошибка в том, что вы обращаетесь к гуёвым компонентам с негуёвого потока. Так делать нельзя! Используйте сигнал\слот или эвенты для передачи данных между потоками.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
IgorbIgorev
Гость
« Ответ #2 : Декабрь 24, 2007, 16:56 »

Ошибка в том, что вы обращаетесь к гуёвым компонентам с негуёвого потока. Так делать нельзя! Используйте сигнал\слот или эвенты для передачи данных между потоками.
у textEdit кокраз insertHtml и является слотом!
если эт неверно, то тогда как туда передавать данные во время выполнения потока?
Записан
Emc
Гость
« Ответ #3 : Декабрь 24, 2007, 17:27 »

всё что связано с paintEvent'ом (а вставка текста вызывает перерисовку textEdit'a) не может исполняться в другом потоке
Записан
IgorbIgorev
Гость
« Ответ #4 : Декабрь 24, 2007, 17:37 »

всё что связано с paintEvent'ом (а вставка текста вызывает перерисовку textEdit'a) не может исполняться в другом потоке
да нет же, неможет этого быть, есть много всяких программ где это КАКТО работает,
например в программе по распаковке ati драйверов catalist там и сообщения выводятся(при нажатии showprogress) в list или в ещё какойто бокс и окно адекватно реагирует на перемещение указателя и scrollbox'а.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #5 : Декабрь 24, 2007, 17:46 »

у textEdit кокраз insertHtml и является слотом!
если эт неверно, то тогда как туда передавать данные во время выполнения потока?

Повторяю ещё раз! Так делать нельзя! Вы обращаетесь напрямую к гуевому элементу с негуювого потока. Создайте сигнал дял потока, сконнектите этот сигнал со слотом вашего виджета, незабыв про параметр Qt::QueuedConnection. Испустите сигнал с данными из вашего второго потока. Или используйте эвенты для передачи данных между потоками.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #6 : Декабрь 24, 2007, 17:53 »

да нет же, неможет этого быть, есть много всяких программ где это КАКТО работает,

Может! Это так и есть! Давайте код всяких программ, заценим
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #7 : Декабрь 24, 2007, 17:56 »

Читаем внимательнее Thread Support in Qt:

Цитировать
In GUI applications, the main thread is also called the GUI thread because it's the ONLY thread that is allowed to perform GUI-related operations.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Emc
Гость
« Ответ #8 : Декабрь 24, 2007, 18:03 »

почувствуй разницу
Код:
void MyThread::run()
{
  int x;
  for (int i = 0; i <val; ++i)
  {
    x=i*2;
    //textEdit->insertHtml ("test №"+QString::number(x)+" completed");  -- ERROR
    emit sig_toTextEdit_insertHtml("test №"+QString::number(x)+" completed"); -- GOOD
  }
}
Записан
IgorbIgorev
Гость
« Ответ #9 : Декабрь 24, 2007, 18:22 »

если я правильно понял то:
Код:
class MyThread : public QThread
{
    QTextEdit* textEdit;
    volatile int val;
  public:
    void set_textEdit(QTextEdit* p){textEdit=p;}
    void set_val(const int v){val=v;}
    void run();
  signals:
    void sendData(const QString &s);
};
class dlgTest: public QDialog, public Ui_dlgTest
{
    Q_OBJECT
    MyThread thread;
  public: 
    dlgTest(QWidget *parent=0); 
  public slots:
    void  on_pbSetThread_clicked();
};
dlgTest::dlgTest(QWidget *parent):QDialog(parent)
{
  setupUi(this);
  thread.set_textEdit(textEdit);
  QObject::connect(&thread,  SIGNAL( sendData(const QString &)   ),
                   textEdit,   SLOT( insertHtml(const QString &) ),
                   Qt::QueuedConnection
                   );
}
void dlgTest::on_pbSetThread_clicked()
{
  thread.set_val( spinBox->value() );
  thread.start();
}
void MyThread::run()
{
  int x;
  for (int i = 0; i <val; ++i)
  {
    x=i*2;
    sendData("test №"+QString::number(x)+" completed");
  }
}
но эта штука неверно работает, отображает первых 2 записи останавливается(не отвечает в это время на запросы) и через нек-е время отображает все сразу!
« Последнее редактирование: Декабрь 24, 2007, 18:25 от IgorbIgorev » Записан
ритт
Гость
« Ответ #10 : Декабрь 24, 2007, 18:34 »

emit где?
Записан
Emc
Гость
« Ответ #11 : Декабрь 24, 2007, 18:35 »

просто задача которую ты решаешь довольно бессмысленная
вынести в thread умножение на число - ради чего?
построчное появление html документа -- можно, но чтоб было красиво -- придется вводить задержку (смысл это городить?
если важна скорость -- сначала сформируй документ потом вставь целиком в  textEdit
Записан
IgorbIgorev
Гость
« Ответ #12 : Декабрь 24, 2007, 18:37 »

emit где?
Код:
void MyThread::run()
{
  int x;
  for (int i = 0; i <val; ++i)
  {
    x=i*2;
    emit sendData("test №"+QString::number(x)+" completed"); //ничего не меняет
  }
}
все также, отображает несколько первых записей->зависает->выводит все остальное!
Записан
IgorbIgorev
Гость
« Ответ #13 : Декабрь 24, 2007, 18:41 »

вынести в thread умножение на число - ради чего?
просто типа пример для меня
построчное появление html документа -- можно, но чтоб было красиво -- придется вводить задержку (смысл это городить?
нет задержки не надо, реальные данные итак будут медленно грузиться.
если важна скорость -- сначала сформируй документ потом вставь целиком в  textEdit
это понятно но нужно чтоб пользователь видел что он получает чтоб в случае чего мог отменить загрузку ненужного ему документа!
Записан
ритт
Гость
« Ответ #14 : Декабрь 24, 2007, 19:44 »

сделал такой же тест - отображает несколько первых записей->зависает->выводит все остальное
в то время, как и без того нешустрый кутекстэдит добавляет текст, ты тред его просит докинуть ещё текста - и так по кругу
попробуй после каждой итерации делать мслип(500)
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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