我有MainWindow w
个窗口和TestThread testThread
作为w
的成员。我知道这很简单,但是我无法在testThread.foo()
线程中运行testThread
方法(不在窗口线程中)。换句话说:我不了解QThread的行为。
请帮助纠正下一个测试应用程序。有QProgressBar *MainWindow::ui::progressBar
和QPushButton *MainWindow::ui::startButton
(简单地写)。我想开始(startButton
点击)TestThread::foo(int* progress)
,每秒增加int progress
。
主窗口:
MainWindow::MainWindow(QWidget *parent) : // ...
{
// ...
ui->progressBar->setRange(0, 5);
progress = 0; // int MainWindow::progress
this->connect(ui->startButton, SIGNAL(clicked()), SLOT(startFoo()));
connect(this, SIGNAL(startFooSignal(int*)), &testThread, SLOT(foo(int*)));
// TestThread MainWindow::testThread
testThread.start();
}
// ...
void MainWindow::timerEvent(QTimerEvent *event)
{
ui->progressBar->setValue(progress);
}
void MainWindow::startFoo() // this is a MainWindow SLOT
{
startTimer(100);
emit startFooSignal(&progress);
// startFooSignal(int*) is a MainWindows SIGNAL
}
TestThread:
void TestThread::foo(int *progress) // this is a TestThread SLOT
{
for (unsigned i = 0; i < 5; ++i) {
sleep(1);
++*progress; // increment MainWindow::progress
}
}
我知道,这很简单。我做错了什么:)
P.S。我想运行最简单(尽可能)的示例来理解QThread
行为。
谢谢!
答案 0 :(得分:2)
关键问题是让包含foo()
- 函数的对象归该线程所有,以便从右线程的事件循环调度槽调用。
(请注意,foo()
对象上不需要TestThread
。您可以为QThread
和WhatEver::foo()
函数使用单独的对象。也更容易,我不确定..)
IIUC,这就是你要做的事情:
Qt::AutoConenction
(默认)signal / slots调用将在线程间正确运行,从每个线程自己的事件调度环)。 通过右侧线程使对象“拥有”,将在该线程的事件循环上调度slot调用,而不是直接执行。
希望它有所帮助。 :)
答案 1 :(得分:2)
一种替代解决方案:如果您只想在另一个线程中运行一个函数,并且不坚持使用QThread,那么您应该查看QT Concurrent Namespace.
以下示例将在单独的线程中运行函数foo(),并且不会在调用函数的行上阻塞。当然,有一些机制可以理解函数何时结束,获取结果,等待它,以控制执行。
void foo(int &progress) {...}
int progress;
QtConcurrent::run(foo, progress);
希望这有帮助
答案 2 :(得分:1)