gpt4 book ai didi

qt4 - 在没有连接的情况下调用槽方法?

转载 作者:行者123 更新时间:2023-12-02 20:36:24 25 4
gpt4 key购买 nike

我有一个通过以下方式实现的事件对象。它用于在后台执行长时间任务。主线程通过向公共(public)槽(即 doTask)发送信号来调用任务。这是一个精简的示例(未经测试)。

class MyTask : public QObject
{
Q_OBJECT

public:
MyTask();
~MyTask();

public slots:
void doTask( int param );

private slots:
void stated();

signals:
void taskCompleted( int result );

private:
QThread m_thread;
};


MyTask::MyTask()
{
moveToThread(&m_thread);
connect( &m_thread, SIGNAL(started()), this, SLOT(started()));
m_thread.start();
}

MyTask::~MyTask()
{
// Gracefull thread termination (queued in exec loop)
if( m_thread.isRunning() )
{
m_thread.quit();
m_thread.wait();
}
}

void MyTask::started()
{
// initialize live object
}

void MyTask::doTask( int param )
{
sleep( 10 );
emit taskCompleted( param*2 );
}

只要 doTask() 被信号调用,这(应该)会按预期工作。但是如果主线程直接调用doTask(),那么它将由主线程执行。对于某些任务,我想强制由事件对象的线程执行,即使直接调用 slot 方法也是如此。

我可以在 doTask() 前面添加代码来检查当前线程是否是 m_thread,在这种情况下它会执行该方法。如果不是,我希望 doTask() 向“this”发出信号,以便 doTask() 的调用在 m_thread exec 循环中排队并尽快由它执行。

我怎样才能做到这一点?

编辑:根据建议的答案,这是新代码。 doTask 方法现在委托(delegate)事件对象的线程执行,即使是由主线程直接调用也是如此。通过信号调用仍然可以按预期工作。

class MyTask : public QObject
{
Q_OBJECT

public:
explicit MyTask( QObject *parent = 0 );
~MyTask();

public slots:
void doTask( int param );

private slots:
void doTaskImpl( int param );

signals:
void taskCompleted( int result );

private:
QThread m_thread;
};

MyTask::MyTask( QObject *parent) : QObject(parent)
{
moveToThread(&m_thread);
m_thread.start();
}

MyTask::~MyTask()
{
// Gracefull thread termination (queued in exec loop)
if( m_thread.isRunning() )
{
m_thread.quit();
m_thread.wait();
}
}

void MyTask::doTask( int param )
{
QMetaObject::invokeMethod( this, "doTaskImpl", Q_ARG( int, param ) );
}

void MyTask::doTaskImpl( int param )
{
// Do the live oject's asynchronous task
sleep( 10 );
emit taskCompleted( param*2 );
}

这是我能找到的支持在单独线程中执行异步方法的最简单的实现。 doTask() 方法的调用将在线程启动后立即排队并进行处理。当从对象线程调用时,它将立即执行(不排队)。

请注意,started() 信号仅在线程启动时发出。这意味着在线程启动之前排队的 doTask() 方法调用将在调用started() 方法槽之前执行。这就是我从最初的实现中删除它的原因。因此,对象初始化最好在构造函数中执行。

最佳答案

您要调用QMetaObject::invokeMethod去做这个。在你的情况下,它看起来像

MyTask *task;
int param;
// ...
// Will automatically change threads, if needed, to execute
// the equivalent of:
// (void)task->doTask( param );
QMetaObject::invokeMethod( task, "doTask", Q_ARG( int, param ) );

关于qt4 - 在没有连接的情况下调用槽方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3297456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com