不能发出QThread的信号

编程入门 行业动态 更新时间:2024-10-11 19:23:42
本文介绍了不能发出QThread的信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

QT 5.1.0rc2,msvc 2010,Microsoft Visual Studio 2010

QT 5.1.0rc2 , msvc 2010 , Microsoft Visual Studio 2010

它是Qt 4.8.4,msvc 2008的工作代码

It is working code on Qt 4.8.4 , msvc 2008

我有编译错误

#if defined( HANDLE_PROCESSING_IN_MAIN_THREAD ) if(QThread::currentThread() != this) emit started(); #endif inherited::run();

#if defined( HANDLE_PROCESSING_IN_MAIN_THREAD ) if(QThread::currentThread() != this) emit finished(); #endif

错误C2660:'QThread :: started ':函数不接受0个参数 错误C2660:'QThread :: finished':函数不接受0个参数

error C2660: 'QThread::started' : function does not take 0 arguments error C2660: 'QThread::finished' : function does not take 0 arguments

$ b b

在QThread中我看到了

In QThread i have seen

Q_SIGNALS: void started( #if !defined(Q_QDOC) QPrivateSignal #endif ); void finished( #if !defined(Q_QDOC) QPrivateSignal #endif );

当我定义Q_QDOC我在QT源中有很多错误。

when I defined Q_QDOC I got many errors in QT sources.

QPrivateSignal是在宏Q_OBJECT中定义的空结构

QPrivateSignal is empty structure that defined in macro Q_OBJECT

需要一个不影响应用程序体系结构的解决方案, .8.4

Need a solution that does not affect the architecture of the application, as to be backward compatible with Qt4.8.4

有些想法?

推荐答案

自动。

您尝试使用预处理器来处理代码的两种变体:在gui线程或专用线程中处理。

You're trying to use preprocessor to handle two variants of the code: processing in the gui thread or a dedicated thread. Qt provides a very easy way of dealing with it.

  • 在一个类中实现你的处理功能,派生自 QObject 。你也可以在重新实现的 event()方法中,如果你更容易通过发布事件而不是调用槽来开始处理。

  • Implement your processing functionality in a slot in a class deriving from QObject. You could also do it in the reimplemented event() method if it's easier for you to start processing by posting an event rather than invoking a slot.

    如果你想让对象的槽在不同的线程中运行,使用 moveToThread()方法。

    If you want your object's slots to run in a different thread, use the moveToThread() method.

    您不需要从 QThread 派生。其默认实现 run()旋转本地事件循环。

    You don't need to derive from QThread. Its default implementation of run() spins a local event loop.

    与生存在GUI线程中兼容,它必须以小块进行处理并放弃控制,以使GUI不会停顿。

    If you want your object to be compatible with living in the GUI thread, it must do its processing in small chunks and relinquish control so that the GUI doesn't stall.

    下面是一个完整的示例,演示如何在GUI或单独的线程中启动worker对象,如何在线程之间安全移动它。

    Below is a complete example that demonstrates how you can start the worker object in either GUI or a separate thread, and how you can safely move it between threads.

    main.cpp

    #include <QApplication> #include <QVBoxLayout> #include <QPushButton> #include <QThread> #include <QBasicTimer> #include <QElapsedTimer> #include <QLabel> #include <QDebug> class Helper : private QThread { public: using QThread::usleep; }; class Worker : public QObject { Q_OBJECT int m_counter; bool m_busy; QBasicTimer m_timer; void timerEvent(QTimerEvent * ev); public: Worker(QObject *parent = 0) : QObject(parent), m_busy(false) {} Q_SLOT void start() { if (m_busy) return; m_counter = 0; m_busy = true; m_timer.start(0, this); } Q_SIGNAL void done(); Q_SIGNAL void progress(int); // must be called from within the working thread, so we wrap it in a slot Q_INVOKABLE void moveToThread(QThread *t) { QObject::moveToThread(t); } }; void Worker::timerEvent(QTimerEvent * ev) { const int busyTime = 50; // [ms] - longest amount of time to stay busy const int testFactor = 128; // number of iterations between time tests const int maxCounter = 10000; if (ev->timerId() != m_timer.timerId()) return; QElapsedTimer t; t.start(); while (1) { // do some "work" Helper::usleep(100); m_counter ++; // exit when the work is done if (m_counter > maxCounter) { emit progress(100); emit done(); m_busy = false; break; } // exit when we're done with a timed "chunk" of work // Note: QElapsedTimer::elapsed() may be expensive, so we call it once every testFactor iterations if ((m_counter % testFactor) == 1 && t.elapsed() > busyTime) { emit progress(m_counter*100/maxCounter); break; } } } class Window : public QWidget { Q_OBJECT QLabel *m_label; QThread *m_thread; QObject *m_worker; Q_SIGNAL void start(); Q_SLOT void showProgress(int p) { m_label->setText(QString("%1 %").arg(p)); } void moveWorkerToThread(QThread *thread) { qDebug() << QMetaObject::invokeMethod(m_worker, "moveToThread", Q_ARG(QThread*, thread)); } Q_SLOT void on_startGUI_clicked() { moveWorkerToThread(qApp->thread()); emit start(); } Q_SLOT void on_startWorker_clicked() { moveWorkerToThread(m_thread); emit start(); } public: Window(QWidget *parent = 0, Qt::WindowFlags f = 0) : QWidget(parent, f), m_label(new QLabel), m_thread(new QThread(this)), m_worker(new Worker) { QVBoxLayout * l = new QVBoxLayout(this); QPushButton * btn; btn = new QPushButton("Start in GUI Thread"); btn->setObjectName("startGUI"); l->addWidget(btn); btn = new QPushButton("Start in Worker Thread"); btn->setObjectName("startWorker"); l->addWidget(btn); l->addWidget(m_label); connect(m_worker, SIGNAL(progress(int)), SLOT(showProgress(int))); m_worker->connect(this, SIGNAL(start()), SLOT(start())); m_thread->start(); QMetaObject::connectSlotsByName(this); } ~Window() { m_thread->quit(); m_thread->wait(); delete m_worker; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); qRegisterMetaType<QThread*>("QThread*"); // for invokeMethod to work Window w; w.show(); return a.exec(); } #include "main.moc"
  • 更多推荐

    不能发出QThread的信号

    本文发布于:2023-10-09 05:32:17,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1474842.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:信号   QThread

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!