复杂使用QThread -

时间:2015-05-08 18:52:34

标签: c++ qt qthread

我在QT / C ++中编写了一个应用程序。这个应用程序有多个类来管理窗口,treewidget ..和自定义类。

该应用程序的目标是在MacOSx上的QT / c ++中进行android文件传输。

目前整个应用程序正在一个线程中工作,其中包括UI管理和Android设备管理。 Android设备访问由名为DeviceManager的类管理。这个类主要是打开设备,读取它,添加/删除文件....

我想要做的是创建一个线程来处理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类定义如下

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类。

用于UI管理的大多数类都可以访问DeviceMngr类。我不知道如何使用QThread来确保所有UI类都可以访问DeviceMngr类。

我正在考虑在main.cpp中创建一个Qthread但是我没有看到如何在main.cpp中添加插槽/信号,而DeviceMngr将有信号/插槽与所有其他线程讨论。例如,主要需要打开设备并接收结果。

我是否需要在main中创建所有信号/插槽连接,或者我可以在不同的类中添加我需要的内容并在需要时创建连接。

有什么想法吗?我已经尝试过第一次实现,但它并没有真正正常工作。

由于

1 个答案:

答案 0 :(得分:2)

我建议创建工作线程并将DeviceMngr移动到它。它的槽(和整个事件循环)将在线程的上下文中运行,您必须使用Qt的信号/槽机制,以确保从其他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。