Ответ 1
Важная информация о Qt заключается в том, что вы должны работать с графическим интерфейсом Qt только из потока графического интерфейса, который является основным потоком.
Вот почему правильный способ сделать это - уведомить основной поток от рабочего, а код в основном потоке будет фактически обновлять текстовое поле, индикатор выполнения или что-то еще.
Лучший способ сделать это, я думаю, - использовать QThread вместо posix thread и использовать сигналы Qt для связи между потоками. Это будет ваш рабочий, заменитель thread_func
:
class WorkerThread : public QThread {
void run() {
while(1) {
// ... hard work
// Now want to notify main thread:
emit progressChanged("Some info");
}
}
// Define signal:
signals:
void progressChanged(QString info);
};
В вашем виджете определите слот с тем же прототипом, что и сигнал в .h:
class MyWidget : public QWidget {
// Your gui code
// Define slot:
public slots:
void onProgressChanged(QString info);
};
В .cpp выполните эту функцию:
void MyWidget::onProgressChanged(QString info) {
// Processing code
textBox->setText("Latest info: " + info);
}
Теперь в том месте, где вы хотите создать поток (при нажатии кнопки):
void MyWidget::startWorkInAThread() {
// Create an instance of your woker
WorkerThread *workerThread = new WorkerThread;
// Connect our signal and slot
connect(workerThread, SIGNAL(progressChanged(QString)),
SLOT(onProgressChanged(QString)));
// Setup callback for cleanup when it finishes
connect(workerThread, SIGNAL(finished()),
workerThread, SLOT(deleteLater()));
// Run, Forest, run!
workerThread->start(); // This invokes WorkerThread::run in a new thread
}
После того, как вы подключите сигнал и слот, слот с emit progressChanged(...)
в рабочем потоке отправит сообщение в основной поток, и основной поток вызовет слот, который подключен к этому сигналу, onProgressChanged
здесь.
<ы > P.s. Я еще не тестировал код, поэтому не стесняйтесь предлагать редактирование, если я ошибаюсь где-то