繁体   English   中英

在QT4中使用自定义事件

[英]Using Custom Events in QT4

我有一个应用程序,它有一个进度条并产生一个工作线程来做一些工作并报告进度。 对话框类重写了customEvent方法,以便我可以处理通过工作线程传递给gui线程的事件。 在我使用QThread派生类作为工作线程之前,我将其更改为使用带有静态函数的ACE_Thread_Manager-> spawn()。

当我运行应用程序并按下按钮以便工作人员产生并开始工作时,问题就出现了。 当它发送信号以递增进度条时,我将以下错误记录到std out。

QPixmap:在GUI线程之外使用pixmaps是不安全的

这似乎发生在调用progressBar-> setValue()时。 所以似乎进度条的设置发生在与主gui线程不同的线程中。 我不清楚这是怎么可能的。 我的印象是我有一个主要的gui线程,它有我的gui和customEvent方法在同一个线程上,而worker正在它自己的线程上。 这个假设是错的吗? 使用QThread派生类与静态run_svc方法有什么区别吗?

任何帮助,将不胜感激。 下面是customEvent处理程序,run_svc和按钮处理程序代码的代码片段,并附加了代码。

void MyDlgEx::customEvent(QEvent * e)
{
    if (e->type() == IdNumOperations)
    {
        NumOperations* pEvt = static_cast<NumOperations*>(e); 
        _steps = 0; 
        cout << "Num Operations = " << pEvt->operations() << endl; 
    }
    else if (e->type() == IdStep)
    {
        if (_steps % 10 == 0)
        {
            cout << "Step++ = " << _steps << endl; 
        }

        _steps++;  
        _progressBar->setValue(_steps); 
    }
}

void* MyDlgEx::run_svc(void* args)
{
    auto_ptr<ThreadArgs> thread_args(static_cast<ThreadArgs*>(args)); 
    QApplication::sendEvent((QObject*)thread_args->m_pDlg, new NumOperations(300)); 

    // does some work that takes time -- ommitted for clarity 
    // called in a loop
    QApplication::sendEvent((QObject*)thread_args->m_pDlg, new Step());

    QApplication::sendEvent((QObject*)thread_args->m_pDlg, new Completed()); 

    return 0; 
}

按钮处理程序注释掉我使用从QThread派生的QT类的行。 使用ACE必须产生线程已经发现了这个问题。

void MyDlgEx::btnShowProgress_clicked()
{
    //_pProc = new ProcessThread(this); 
    //_pProc->run();

    auto_ptr<ThreadArgs> thread_args(new ThreadArgs(this));
    if (ACE_Thread_Manager::instance()->spawn(
                MyDlgEx::run_svc,
                static_cast<void*>(thread_args.get()), 
                THR_DETACHED | THR_SCOPE_SYSTEM) == -1)
        cout << "Failed to spawn thread." << endl; 

    thread_args.release(); 
}

尝试调用QApplication :: postEvent(...)而不是QApplication :: sendEvent()。 文档说sendEvent直接发送事件,这意味着它直接从另一个线程调用customEvent()函数。 postEvent()将事件添加到事件队列中,稍后可以通过主GUI事件循环将事件调度到customEvent()。

仅仅因为customEvent()函数是在主GUI线程中创建的对象的成员并不意味着另一个线程无法调用该函数。 我相信当你从另一个线程调用QApplication :: sendEvent()时会发生这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM