必须在GUI线程Error!中创建小部件。如何更正代码?

时间:2013-05-09 19:38:55

标签: c++ multithreading events user-interface qt4

我有一些C ++的经验,但我只是几天的Qt初学者。看看我下面的简单应用程序代码,即“main.cpp”,它只是项目中的代码文件。问题是,当我尝试运行应用程序时,它返回错误,必须在GUI线程中创建小部件。怎么绕过这个?是否可以编写这个应用程序,它可以在没有额外线程的情况下工作?如果是,那么如何?请帮忙。我不能自己动手。

#include <QApplication>
#include <QWidget>
#include <QBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QSpinBox>
#include <QSlider>
#include <QRadioButton>
#include <QFrame>
#include <QLCDNumber>
#include <QProgressBar>
#include "windows.h"

DWORD WINAPI trd1Entry(LPVOID lpParam) ;

int main(int argc, char **argv)
{
    QApplication app(argc, argv) ;
    QWidget *window = new QWidget() ;
    window->resize(500, 400) ;

    QHBoxLayout *layout0 = new QHBoxLayout() ;
    QGridLayout *layout1 = new QGridLayout() ;
    QVBoxLayout *layout2 = new QVBoxLayout() ;
    QVBoxLayout *layout3 = new QVBoxLayout() ;

    QSlider slider0(Qt::Horizontal), slider1(Qt::Horizontal) ;
    QLCDNumber lcd0, lcd1 ;
    QRadioButton rb0, rb1, rb2 ;
    QPushButton pb0("Reset"), pb1("Quit") ;
    QProgressBar progress0 ;
    QSpinBox spin0, spin1 ;

    spin0.setRange(-100, 100) ;
    spin1.setRange(-100, 100) ;
    slider0.setRange(-100, 100) ;
    slider1.setRange(-100, 100) ;

    rb0.setText("reset first") ;
    rb1.setText("reset second") ;
    rb2.setText("reset both") ;

    layout1->addWidget(&slider0, 0, 0) ;
    layout1->addWidget(&spin0, 0, 1) ;
    layout1->addWidget(&spin1, 1, 0) ;
    layout1->addWidget(&slider1, 1, 1) ;
    layout1->addWidget(&lcd0, 2, 0) ;
    layout1->addWidget(&lcd1, 2, 1) ;

    layout2->addWidget(&rb0) ;
    layout2->addWidget(&rb1) ;
    layout2->addWidget(&rb2) ;
    layout2->addWidget(&pb0) ;
    layout2->addWidget(&pb1) ;

    layout0->addLayout(layout1) ;
    layout0->addLayout(layout2) ;

    QFrame *frame = new QFrame() ;
    frame->setLayout(layout0) ;

    layout3->addWidget(frame) ;
    layout3->addWidget(&progress0) ;

    frame->setFrameShape(QFrame::Box) ;
    frame->setFrameShadow(QFrame::Raised) ;
    frame->setLineWidth(1) ;
    frame->move(10, 10) ;

    progress0.setRange(-200, 200) ;

    QObject::connect(&spin0, SIGNAL(valueChanged(int)), &slider0, SLOT(setValue(int))) ;
    QObject::connect(&spin1, SIGNAL(valueChanged(int)), &slider1, SLOT(setValue(int))) ;
    QObject::connect(&slider0, SIGNAL(valueChanged(int)), &spin0, SLOT(setValue(int))) ;
    QObject::connect(&slider1, SIGNAL(valueChanged(int)), &spin1, SLOT(setValue(int))) ;
    QObject::connect(&spin0, SIGNAL(valueChanged(int)), &lcd0, SLOT(display(int))) ;
    QObject::connect(&spin1, SIGNAL(valueChanged(int)), &lcd1, SLOT(display(int))) ;

    QObject::connect(&pb1, SIGNAL(clicked()), &app, SLOT(quit())) ;

    QObject *objs[3] = {&spin0, &spin1, &progress0} ;

    HANDLE trd1Handle = CreateThread(NULL, 0, trd1Entry, objs, 0, NULL) ;
    if(trd1Handle == NULL)
    ExitProcess(0) ;

    window->setLayout(layout3) ;

    window->show() ;
    return app.exec() ;
}

DWORD WINAPI trd1Entry(LPVOID lpParam)
{
    QObject **objs = static_cast<QObject**>(lpParam) ;
    QSpinBox *spin0 = static_cast<QSpinBox*>(objs[0]) ;
    QSpinBox *spin1 = static_cast<QSpinBox*>(objs[1]) ;
    QProgressBar *progress = static_cast<QProgressBar*>(objs[2]) ;
    HANDLE trd1Handle = GetStdHandle(STD_OUTPUT_HANDLE) ;
    if(trd1Handle == INVALID_HANDLE_VALUE)
    return -1 ;
    int total = 0 ;
    while(1)
    {
        total = spin0->value() + spin1->value() ;
        progress->setValue(total) ;
        Sleep(100) ;
    }
    return 0 ;
}

1 个答案:

答案 0 :(得分:2)

以下是完全解释和解决我的问题的代码。如果这对某人有用或者您喜欢我解决问题的方法,那么请投票

main.cpp中:

#include <QApplication>
#include <QWidget>
#include <QBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QSpinBox>
#include <QSlider>
#include <QRadioButton>
#include <QFrame>
#include <QLCDNumber>
#include <QProgressBar>
#include "qspinstransmit.h"

int main(int argc, char **argv)
{
    QApplication app(argc, argv) ;
    QWidget *window = new QWidget() ;
    window->resize(500, 400) ;

    QHBoxLayout *layout0 = new QHBoxLayout() ;
    QGridLayout *layout1 = new QGridLayout() ;
    QVBoxLayout *layout2 = new QVBoxLayout() ;
    QVBoxLayout *layout3 = new QVBoxLayout() ;

    QSlider slider0(Qt::Horizontal), slider1(Qt::Horizontal) ;
    QLCDNumber lcd0, lcd1 ;
    QRadioButton rb0, rb1, rb2 ;
    QPushButton pb0("Reset"), pb1("Quit") ;
    QProgressBar progress0 ;
    QSpinBox spin0, spin1 ;
    QSpinsTransmit *transmit = new QSpinsTransmit(&spin0, &spin1) ;

    spin0.setRange(-100, 100) ;
    spin1.setRange(-100, 100) ;
    slider0.setRange(-100, 100) ;
    slider1.setRange(-100, 100) ;

    rb0.setText("reset first") ;
    rb1.setText("reset second") ;
    rb2.setText("reset both") ;

    layout1->addWidget(&slider0, 0, 0) ;
    layout1->addWidget(&spin0, 0, 1) ;
    layout1->addWidget(&spin1, 1, 0) ;
    layout1->addWidget(&slider1, 1, 1) ;
    layout1->addWidget(&lcd0, 2, 0) ;
    layout1->addWidget(&lcd1, 2, 1) ;

    layout2->addWidget(&rb0) ;
    layout2->addWidget(&rb1) ;
    layout2->addWidget(&rb2) ;
    layout2->addWidget(&pb0) ;
    layout2->addWidget(&pb1) ;

    layout0->addLayout(layout1) ;
    layout0->addLayout(layout2) ;

    QFrame *frame = new QFrame() ;
    frame->setLayout(layout0) ;

    layout3->addWidget(frame) ;
    layout3->addWidget(&progress0) ;

    frame->setFrameShape(QFrame::Box) ;
    frame->setFrameShadow(QFrame::Raised) ;
    frame->setLineWidth(1) ;
    frame->move(10, 10) ;

    progress0.setRange(-200, 200) ;

    QObject::connect(&spin0, SIGNAL(valueChanged(int)), &slider0, SLOT(setValue(int))) ;
    QObject::connect(&spin1, SIGNAL(valueChanged(int)), &slider1, SLOT(setValue(int))) ;
    QObject::connect(&slider0, SIGNAL(valueChanged(int)), &spin0, SLOT(setValue(int))) ;
    QObject::connect(&slider1, SIGNAL(valueChanged(int)), &spin1, SLOT(setValue(int))) ;
    QObject::connect(&spin0, SIGNAL(valueChanged(int)), &lcd0, SLOT(display(int))) ;
    QObject::connect(&spin1, SIGNAL(valueChanged(int)), &lcd1, SLOT(display(int))) ;

    QObject::connect(&pb1, SIGNAL(clicked()), &app, SLOT(quit())) ;

    QObject::connect(transmit, SIGNAL(valueChanged(int)), &progress0, SLOT(setValue(int))) ;

    window->setLayout(layout3) ;

    window->show() ;
    return app.exec() ;
}

qspinstransmit.h:

#ifndef QSPINSTRANSMIT_H
#define QSPINSTRANSMIT_H

#include <QSpinBox>

class QSpinsTransmit: public QObject
{

    Q_OBJECT

    private:
    QSpinBox *spin0, *spin1 ;

    public:
    QSpinsTransmit(QSpinBox *spin0 = NULL, QSpinBox *spin1 = NULL) ;

    signals:
    void valueChanged(int) ;

    public slots:
    void valuesSum() ;
} ;

#endif // QSPINSTRANSMIT_H

qspinstransmit.cpp:

#include "qspinstransmit.h"

QSpinsTransmit::QSpinsTransmit(QSpinBox *spin0, QSpinBox *spin1)
{
    this->spin0 = spin0 ;
    this->spin1 = spin1 ;
    connect(spin0, SIGNAL(valueChanged(int)), SLOT(valuesSum())) ;
    connect(spin1, SIGNAL(valueChanged(int)), SLOT(valuesSum())) ;
}

void QSpinsTransmit::valuesSum()
{
    emit valueChanged(spin0->value() + spin1->value()) ;
}