帮助我了解QThread的用法

帮助我了解QThread的用法,qt,qthread,Qt,Qthread,我有main窗口w窗口和testthreadtestthread作为w的成员。我知道这很简单,但我无法在testThreadthread(不在窗口线程)中运行testThread.foo()方法。换句话说:我不理解QThread的行为 请帮助更正下一个测试应用程序。有一个QProgressBar*MainWindow::ui::progressBar和QPushButton*MainWindow::ui::startButton(简单编写)。我想开始(通过startButtonclick)Tes

我有
main窗口w
窗口和
testthreadtestthread
作为
w
的成员。我知道这很简单,但我无法在
testThread
thread(不在窗口线程)中运行
testThread.foo()
方法。换句话说:我不理解QThread的行为

请帮助更正下一个测试应用程序。有一个
QProgressBar*MainWindow::ui::progressBar
QPushButton*MainWindow::ui::startButton
(简单编写)。我想开始(通过
startButton
click)
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
}
测试线程:

void TestThread::foo(int *progress) // this is a TestThread SLOT
{
    for (unsigned i = 0; i < 5; ++i) {
        sleep(1);
        ++*progress; // increment MainWindow::progress
    }
}
void TestThread::foo(int*progress)//这是一个TestThread插槽
{
for(无符号i=0;i<5;++i){
睡眠(1);
++*进度;//增量主窗口::进度
}
}
我知道,这很简单。我做错了什么:)

p.S.我想运行最简单(尽可能)的示例来理解
QThread
行为


谢谢

请参见和。

请参见和。

关键问题是让包含
foo()
-函数的对象归该线程所有,以便从正确线程的事件循环调度插槽调用

(请注意,
TestThread
对象上实际上不需要有
foo()
。您可以为
QThread
WhatEver::foo()
函数使用单独的对象。这也可能更容易,我不确定..)

IIUC,这是你必须做的:

  • 用于将包含foo函数的对象分配给TestThread(这意味着
    Qt::autoconction
    (默认)信号/插槽调用将在线程之间正确运行,并从每个线程自己的事件循环中调度)
通过将对象“拥有”给正确的线程,插槽调用将被安排在该线程的事件循环上,而不是直接执行


希望有帮助。:)

关键问题是让包含
foo()
-函数的对象归该线程所有,以便从正确线程的事件循环调度插槽调用

(请注意,
TestThread
对象上实际上不需要有
foo()
。您可以为
QThread
WhatEver::foo()
函数使用单独的对象。这也可能更容易,我不确定..)

IIUC,这是你必须做的:

  • 用于将包含foo函数的对象分配给TestThread(这意味着
    Qt::autoconction
    (默认)信号/插槽调用将在线程之间正确运行,并从每个线程自己的事件循环中调度)
通过将对象“拥有”给正确的线程,插槽调用将被安排在该线程的事件循环上,而不是直接执行


希望有帮助。:)

另一种解决方案:如果您只想在另一个线程中运行函数,而不坚持使用QThread,那么您应该查看

下面的示例将在单独的线程中运行函数foo(),并且不会阻塞调用该函数的行。当然,有一些机制可以理解函数何时结束、获得结果、等待结果以及控制执行

void foo(int &progress) {...}

int progress;
QtConcurrent::run(foo, progress);

希望这对另一种解决方案有所帮助:如果您只想在另一个线程中运行函数,而不坚持使用QThread,那么您应该查看

下面的示例将在单独的线程中运行函数foo(),并且不会阻塞调用该函数的行。当然,有一些机制可以理解函数何时结束、获得结果、等待结果以及控制执行

void foo(int &progress) {...}

int progress;
QtConcurrent::run(foo, progress);

希望这有帮助

在这个例子中我已经忘记了它们,谢谢。但是,我应该做哪些更改才能使
foo()
在单独的线程中运行?据我所知,
run()
的默认实现只调用
exec()
(即事件循环)。在我的真实代码中,我想调用
testThread
的插槽<代码>开始被调用,例如在
主窗口
构造函数中。您好,我在理解QThread时也遇到了问题。当时我做了一个测试,在这个例子中我已经忘记了,谢谢。但是,我应该做哪些更改才能使
foo()
在单独的线程中运行?据我所知,
run()
的默认实现只调用
exec()
(即事件循环)。在我的真实代码中,我想调用
testThread
的插槽<代码>开始被调用,例如在
主窗口
构造函数中。您好,我在理解QThread时也遇到了问题。当时我做了一个测试这些东西的小问题,请注意,像您这样更新进度变量不是线程安全的。它通常在像您这样的简单情况下工作得相当好,但对于更精确的需求或复杂的更新模式,请考虑使用互斥/关键部分或原子更新。(这有助于数据在线程之间保持一致…@Macke:谢谢,我知道:)我不熟悉Qt-threads类
QThread
,只想运行最简单的示例:)无法理解其用法:(小问题,请注意,像您这样更新进度变量不是线程安全的。它通常在像您这样的简单情况下工作得相当好,但对于更精确的要求或复杂的更新模式,请考虑使用互斥/关键部分或原子更新。(这有助于跨线程保持数据一致…)@Macke:谢谢,我知道:)我对Qt threads类
QThread
不熟悉,只想运行最简单的示例:)无法理解它的用法:(感谢您提供此解决方案(请记住)。但我想使用Qt本机信号插槽机制来调用
testThread
的不同插槽。感谢您提供此解决方案(请记住)。但我想使用Qt