窗口小部件必须在GUI线程中创建错误!如何纠正代码? [英] Widgets must be created in the GUI thread Error !. How to correct the code?

查看:335
本文介绍了窗口小部件必须在GUI线程中创建错误!如何纠正代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些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>
#includewindows.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 ::水平),slider1(Qt :: Horizo​​ntal);
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);
睡眠(100);
}
return 0;
}


解决方案

解释和解决我的问题。如果这对某人有用,或者您喜欢该方法,我会解决问题,请投票。



main.cpp:

  #include< QApplication> 
#include< QWidget>
#include< QBoxLayout>
#include< QGridLayout>
#include< QPushButton>
#include< QSpinBox>
#include< QSlider>
#include< QRadioButton>
#include< QFrame>
#include< QLCDNumber>
#include< QProgressBar>
#includeqspinstransmit.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 ::水平),slider1(Qt :: Horizo​​ntal);
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);

信号:
void valueChanged(int);

public slots:
void valuesSum();
};

#endif // QSPINSTRANSMIT_H

qspinstransmit.cpp:

  #includeqspinstransmit.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());
}


I have some experience with C++ but I'm a Qt beginner just for a few days. Look at my simple application code below, that is "main.cpp" which is only code file in the project. The problem is that when I try to run the application it returns me error that widgets must be created in the GUI thread. How to go around this ?. Is it possible to write this application that it works as I want without additional thread ?. If Yes then How ?. Please help. I can't get it working by myself.

#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 ;
}

解决方案

Below is the code which fully explain and resolve my problem. If this is usefull for someone or You like the method I resolved the problem then please vote

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()) ;
}

这篇关于窗口小部件必须在GUI线程中创建错误!如何纠正代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆