QThread的复杂使用——
Complex use of QThread -
我用 QT/C++ 编写了一个应用程序。此应用程序有多个 class 用于管理 window、treewidget.. 和自定义 class.
该应用程序的目标是 android 文件传输 - 类似于 MacOSx 上的 QT/c++。
目前整个应用程序在一个线程中运行,其中包括 UI 管理和 android 设备管理。 android 设备访问由名为 DeviceManager 的 class 管理。这个 class 将主要打开设备,读取它,add/delete 个文件....
我想做的是创建一个线程来处理 DeviceManager 中定义的所有方法。我希望 UI 在一个线程中,而 devicemngr 在另一个线程中。
这是我当前的代码:
main.cpp
int main(int argc, char *argv[])
{
PULS_mtp_error_t error = ERROR_GENERAL;
QThread PulsDeviceThread;
QApplication app(argc, argv);
DeviceMngr *MyMtp = new DeviceMngr;
error = MyMtp->OpenDevice();
...
MainUI MyWindow(*MyMtp);
MyWindow.show();
return app.exec();
}
MainUI class定义如下
MainUI::MainUI(DeviceMngr& device) :
m_device(device)
{
m_closing = false;
setWindowTitle(QString::fromUtf8("PULS"));
resize(800,600);
setUnifiedTitleAndToolBarOnMac(true);
/* Creation of the Top bar section */
createBackForwardButton();
createLogoSection();
createAddFolder();
QWidget *TopBarWidget = new QWidget();
TopBarWidget->setFixedHeight(61);
QHBoxLayout *TopBarLayout = new QHBoxLayout(TopBarWidget);
TopBarLayout->addWidget(BackForwardSection);
TopBarLayout->addWidget(LogoSection);
TopBarLayout->addWidget(AddFolderSection);
/* Creation of Tree View Section */
createTreeView();
/* Creation of the bottom bar section */
createInfoSection();
/*about*/
aboutAction = new QAction(tr("&About"),this);
connect(aboutAction, SIGNAL(triggered()),this ,SLOT(aboutPuls()));
QMenu *helpMenu = new QMenu("Help", this);
helpMenu->addAction(aboutAction);
menuBar()->addMenu(helpMenu);
/*Overall Layout*/
QWidget *MainWindowWidget = new QWidget();
QVBoxLayout *MainWindowLayout = new QVBoxLayout(MainWindowWidget);
MainWindowLayout->setSpacing(0);
MainWindowLayout->addWidget(TopBarWidget);
MainWindowLayout->addWidget(TreeViewSection);
MainWindowLayout->addWidget(CreateInfoSection);
setCentralWidget(MainWindowWidget);
PulsUnplugged = false;
#if 1
activeTimer = new QTimer(this);
activeTimer->setSingleShot(false);
activeTimer->setInterval(200);
connect(activeTimer, SIGNAL(timeout()), this, SLOT(PulsDetection()));
activeTimer->start();
#endif
show();
}
某些方法(例如 createTreeView)也将使用 m_device 来访问设备。
void MainUI::createTreeView()
{
TreeViewSection = new QWidget();
QVBoxLayout *TreeViewLayout = new QVBoxLayout(TreeViewSection);
MyTreeWidget = new MyNewTreeWidget(m_device, *this);
TreeViewLayout->addWidget(MyTreeWidget);
}
MyNewTreeWidget 还需要访问 DeviceMngr class。
大部分用于UI管理的class可以访问DeviceMngr class。我不知道如何使用 QThread 来确保所有 UI classes 都可以访问 DeviceMngr class.
我想在 main.cpp 中创建一个 Qthread 但我不知道如何在 main.cpp 中添加 slots/signals 并且 DeviceMngr 将有 signals/slots 讨论与所有其他线程。例如,主要需要打开设备并接收结果。
我是否需要在主连接中创建所有 signal/slot 连接,或者我可以只在不同的 class 中添加我需要的内容并在需要时创建连接。
有什么想法吗?我已经尝试了第一个实现,但它并没有真正发挥作用。
谢谢
我建议创建工作线程并将您的 DeviceMngr
移动到它。它的插槽(和整个事件循环)将 运行 在线程的上下文中,您必须使用 Qt 的 signal/slot 机制来确保从其他 QObject 线程安全地访问 DeviceMngr
。
int main(...) {
// ...
QThread MtpThread;
DeviceMngr MyMtp;
MyMtp.moveToThread(&MtpThread);
// connect signals/slots of DeviceMngr
// ...
// launch the thread
MtpThread.start();
// should you need to call slots of DeviceMngr from main use metacalls
QMetaObject::invokeMethod(&MyMtp, "nameOfSlot");
// run application
// in the end join
MtpThread.quit(); // stop event queue
MtpThread.wait(); // join the thread
}
我希望你明白了。关键是 moveToThread()
和 metacalls.
我用 QT/C++ 编写了一个应用程序。此应用程序有多个 class 用于管理 window、treewidget.. 和自定义 class.
该应用程序的目标是 android 文件传输 - 类似于 MacOSx 上的 QT/c++。
目前整个应用程序在一个线程中运行,其中包括 UI 管理和 android 设备管理。 android 设备访问由名为 DeviceManager 的 class 管理。这个 class 将主要打开设备,读取它,add/delete 个文件....
我想做的是创建一个线程来处理 DeviceManager 中定义的所有方法。我希望 UI 在一个线程中,而 devicemngr 在另一个线程中。
这是我当前的代码:
main.cpp
int main(int argc, char *argv[])
{
PULS_mtp_error_t error = ERROR_GENERAL;
QThread PulsDeviceThread;
QApplication app(argc, argv);
DeviceMngr *MyMtp = new DeviceMngr;
error = MyMtp->OpenDevice();
...
MainUI MyWindow(*MyMtp);
MyWindow.show();
return app.exec();
}
MainUI class定义如下
MainUI::MainUI(DeviceMngr& device) :
m_device(device)
{
m_closing = false;
setWindowTitle(QString::fromUtf8("PULS"));
resize(800,600);
setUnifiedTitleAndToolBarOnMac(true);
/* Creation of the Top bar section */
createBackForwardButton();
createLogoSection();
createAddFolder();
QWidget *TopBarWidget = new QWidget();
TopBarWidget->setFixedHeight(61);
QHBoxLayout *TopBarLayout = new QHBoxLayout(TopBarWidget);
TopBarLayout->addWidget(BackForwardSection);
TopBarLayout->addWidget(LogoSection);
TopBarLayout->addWidget(AddFolderSection);
/* Creation of Tree View Section */
createTreeView();
/* Creation of the bottom bar section */
createInfoSection();
/*about*/
aboutAction = new QAction(tr("&About"),this);
connect(aboutAction, SIGNAL(triggered()),this ,SLOT(aboutPuls()));
QMenu *helpMenu = new QMenu("Help", this);
helpMenu->addAction(aboutAction);
menuBar()->addMenu(helpMenu);
/*Overall Layout*/
QWidget *MainWindowWidget = new QWidget();
QVBoxLayout *MainWindowLayout = new QVBoxLayout(MainWindowWidget);
MainWindowLayout->setSpacing(0);
MainWindowLayout->addWidget(TopBarWidget);
MainWindowLayout->addWidget(TreeViewSection);
MainWindowLayout->addWidget(CreateInfoSection);
setCentralWidget(MainWindowWidget);
PulsUnplugged = false;
#if 1
activeTimer = new QTimer(this);
activeTimer->setSingleShot(false);
activeTimer->setInterval(200);
connect(activeTimer, SIGNAL(timeout()), this, SLOT(PulsDetection()));
activeTimer->start();
#endif
show();
}
某些方法(例如 createTreeView)也将使用 m_device 来访问设备。
void MainUI::createTreeView()
{
TreeViewSection = new QWidget();
QVBoxLayout *TreeViewLayout = new QVBoxLayout(TreeViewSection);
MyTreeWidget = new MyNewTreeWidget(m_device, *this);
TreeViewLayout->addWidget(MyTreeWidget);
}
MyNewTreeWidget 还需要访问 DeviceMngr class。
大部分用于UI管理的class可以访问DeviceMngr class。我不知道如何使用 QThread 来确保所有 UI classes 都可以访问 DeviceMngr class.
我想在 main.cpp 中创建一个 Qthread 但我不知道如何在 main.cpp 中添加 slots/signals 并且 DeviceMngr 将有 signals/slots 讨论与所有其他线程。例如,主要需要打开设备并接收结果。
我是否需要在主连接中创建所有 signal/slot 连接,或者我可以只在不同的 class 中添加我需要的内容并在需要时创建连接。
有什么想法吗?我已经尝试了第一个实现,但它并没有真正发挥作用。
谢谢
我建议创建工作线程并将您的 DeviceMngr
移动到它。它的插槽(和整个事件循环)将 运行 在线程的上下文中,您必须使用 Qt 的 signal/slot 机制来确保从其他 QObject 线程安全地访问 DeviceMngr
。
int main(...) {
// ...
QThread MtpThread;
DeviceMngr MyMtp;
MyMtp.moveToThread(&MtpThread);
// connect signals/slots of DeviceMngr
// ...
// launch the thread
MtpThread.start();
// should you need to call slots of DeviceMngr from main use metacalls
QMetaObject::invokeMethod(&MyMtp, "nameOfSlot");
// run application
// in the end join
MtpThread.quit(); // stop event queue
MtpThread.wait(); // join the thread
}
我希望你明白了。关键是 moveToThread()
和 metacalls.