Всем доброго вечера.
Есть такая проблема: Существует окно QDialog. При загрузке этого окна происходят довольно тяжелые вычисления и, как следствие, окно замораживается. Элементов на форме 6 штук ( два QTableWidget, четыре QListWidget). Хотелось бы вынести все вычисления в отдельный поток.
Но я не понимаю, как сделать так, чтобы второй поток смог изменять Widget'ы на форме QDialog. Можно конечно в поток передавать указатели на Widget'ы, но у меня есть подозрение, что существует более красивое решение...
Что вы можете сказать по этому поводу?
Заранее спасибо.
А ещё лучше использовать сигналы и слоты.
Под красивым решением имеется ввиду... кхм... не описать, нужно прочувствовать.
Да, согласен, так скорее всего и сделаю -- передам указатель на главный объект. )
Тогда вопросик в догонку... Тут начал переносить вычисления в отдельный поток.. Переопределил customEvent(), чтобы поток ловил event'ы. Переопределил run(). запихнул туда все вычисления. В конце метода run() написал exec(), чтобы thread не завершался и ждал event'ы. Но после того, как вычисления завершаются, программа вылетает с exception... Не могу понять в чем проблема. Если exec убрать, то все нормально, но поток завершается и не ловит event'ы.
Нет никаких мыслей по этому поводу?
P.S. Скоро код выложу, чтобы понятнее было..
Что-то типа:
while(!stopped)
{
}
ИМХО.
Я так понимаю, что это от реализации программы зависит.
Чтобы имитировать сигнал никаких указателей не нужно. Вот уже где распологается коннект, это другое дело.
Все равно экземпляры класса, наследовонного от QThread, будут создаваться в "Gui_class", так и коннекты между ними лучше делять тамже.
connect(&thread, SIGNAL(thread_signal()), this, SLOT(gui_slot()));
Спасибо за ответы.
Так можно узнать почему, если я использую exec() у меня вылезает exception, а если бесконечный цикл, то все нормально?
/*
* ManageThread.h
*
* Created on: 28.03.2009
* Author: canavar
*/
#ifndef MANAGETHREAD_H_
#define MANAGETHREAD_H_
#include <QThread>
#include <QObject>
#include <QtGui>
class ManageThread : public QThread
{
Q_OBJECT
public:
ManageThread(QObject *parent = 0);
virtual ~ManageThread();
inline void SetWidgetTable(QTableWidget *tbl) { _widgetTable = tbl; };
protected:
void run();
void customEvent(QEvent *event);
private:
QTableWidget *_widgetTable;
void Load();
void add(QString a);
};
#endif /* MANAGETHREAD_H_ */
/*
* ManageThread.cpp
*
* Created on: 28.03.2009
* Author: canavar
*/
#include "ManageThread.h"
ManageThread::ManageThread(QObject *parent) : QThread(parent)
{
}
ManageThread::~ManageThread()
{
}
void ManageThread::run()
{
// Inserting start values
Load();
exec();
}
void ManageThread::Load()
{
// This function (add) is called about 1500 times...
add("aaa");
}
// TODO: Move this in other thread
void ManageThread::add(QString a)
{
if(desc.name().isEmpty() && (!desc.id().isEmpty()))
_widgetTable->addItem(desc.id());
else
_widgetTable->addItem(desc.name());
}
void ManageThread::customEvent(QEvent *event)
{
}
_mgThread = new ManageThread();
_mgThread->SetWidgetTable(ui.widgetTable);
_mgThread->start();
private:
ManageThread *_mgThread;
/*
* ManageThread.h
*
* Created on: 28.03.2009
* Author: canavar
*/
#ifndef MANAGETHREAD_H_
#define MANAGETHREAD_H_
#include <QThread>
#include <QObject>
#include <QtGui>
class ManageThread : public QThread
{
Q_OBJECT
#endif /* MANAGETHREAD_H_ */
Хорошо.
2 canavar Внимательние читайте предыдущие сообщения. Нельзя работать с виджетами в дочернем потоке.
Что такое addItem()? У QTableWidget нет такого метода. Или там должен быть QListWidget?
В дочернем потоке нужно производить вычисления, а результат высылать через сигнал. Ловить этот сигнал в Gui потоке, и в нем устанавливать значения для таблиц и списков.
Привыкаем к следущему объявлению
void add(const QString &a)
Огромное спасибо! Теперь стало понятно.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)