• 8845阅读
  • 6回复

新手求教Qthread线程问题!求帮忙看看code谢谢! [复制链接]

上一主题 下一主题
离线hanslh
 

只看楼主 倒序阅读 楼主  发表于: 2009-04-15
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
我是新手,第一次接触QT4,想用Qt4写一个简单的Qthread小程序,只要能实现点一下按钮就自动循环改变label里面的文字就行了,可我弄了半天,网上查了半天还是不会,请大家帮我看看我哪里错了,谢谢。

ui很简单,一个label两个按钮,一个按钮按了就循环5次改变label里面的文字,另一个按了退出
用uic自动生成的.h文件
mainform.h
  1. /********************************************************************************
  2. ** Form generated from reading ui file 'mainform.ui'
  3. **
  4. ** Created: Wed Apr 15 03:00:33 2009
  5. **      by: Qt User Interface Compiler version 4.4.3
  6. **
  7. ** WARNING! All changes made in this file will be lost when recompiling ui file!
  8. ********************************************************************************/
  9. #ifndef MAINFORM_H
  10. #define MAINFORM_H
  11. #include <QtCore/QLocale>
  12. #include <QtCore/QVariant>
  13. #include <QtGui/QAction>
  14. #include <QtGui/QApplication>
  15. #include <QtGui/QButtonGroup>
  16. #include <QtGui/QDialog>
  17. #include <QtGui/QHBoxLayout>
  18. #include <QtGui/QLabel>
  19. #include <QtGui/QPushButton>
  20. #include <QtGui/QSpacerItem>
  21. #include <QtGui/QWidget>
  22. QT_BEGIN_NAMESPACE
  23. class Ui_mainForm
  24. {
  25. public:
  26.     QLabel *label;
  27.     QWidget *widget;
  28.     QHBoxLayout *horizontalLayout;
  29.     QSpacerItem *horizontalSpacer;
  30.     QPushButton *pushButton_1;
  31.     QSpacerItem *horizontalSpacer_2;
  32.     QPushButton *pushButton_2;
  33.     QSpacerItem *horizontalSpacer_3;
  34.     void setupUi(QDialog *mainForm)
  35.     {
  36.     if (mainForm->objectName().isEmpty())
  37.         mainForm->setObjectName(QString::fromUtf8("mainForm"));
  38.     mainForm->setWindowModality(Qt::NonModal);
  39.     mainForm->resize(436, 236);
  40.     mainForm->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));
  41.     label = new QLabel(mainForm);
  42.     label->setObjectName(QString::fromUtf8("label"));
  43.     label->setGeometry(QRect(40, 20, 341, 151));
  44.     widget = new QWidget(mainForm);
  45.     widget->setObjectName(QString::fromUtf8("widget"));
  46.     widget->setGeometry(QRect(9, 195, 418, 32));
  47.     horizontalLayout = new QHBoxLayout(widget);
  48.     horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
  49.     horizontalLayout->setContentsMargins(0, 0, 0, 0);
  50.     horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
  51.     horizontalLayout->addItem(horizontalSpacer);
  52.     pushButton_1 = new QPushButton(widget);
  53.     pushButton_1->setObjectName(QString::fromUtf8("pushButton_1"));
  54.     horizontalLayout->addWidget(pushButton_1);
  55.     horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
  56.     horizontalLayout->addItem(horizontalSpacer_2);
  57.     pushButton_2 = new QPushButton(widget);
  58.     pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));
  59.     horizontalLayout->addWidget(pushButton_2);
  60.     horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
  61.     horizontalLayout->addItem(horizontalSpacer_3);
  62.     retranslateUi(mainForm);
  63.     QObject::connect(pushButton_2, SIGNAL(clicked()), mainForm, SLOT(close()));
  64.     QMetaObject::connectSlotsByName(mainForm);
  65.     } // setupUi
  66.     void retranslateUi(QDialog *mainForm)
  67.     {
  68.     mainForm->setWindowTitle(QApplication::translate("mainForm", "TCP Server", 0, QApplication::UnicodeUTF8));
  69.     label->setText(QString());
  70.     pushButton_1->setText(QApplication::translate("mainForm", "Run", 0, QApplication::UnicodeUTF8));
  71.     pushButton_2->setText(QApplication::translate("mainForm", "Exit", 0, QApplication::UnicodeUTF8));
  72.     Q_UNUSED(mainForm);
  73.     } // retranslateUi
  74. };
  75. namespace Ui {
  76.     class mainForm: public Ui_mainForm {};
  77. } // namespace Ui
  78. QT_END_NAMESPACE
  79. #endif // MAINFORM_H


然后是main.cpp
  1. #include <QApplication>
  2. #include "TCPServer.h"
  3. int main(int argc, char **argv)
  4. {
  5.     QApplication app(argc, argv);
  6.     TCPServer *tcpserver= new TCPServer;
  7.     return tcpserver->exec();
  8. }      


TCPServer.h
  1. #ifndef DLG_H
  2. #define DLG_H
  3. #include <QDialog>
  4. #include <mainform.h>
  5. #include <qthread.h>
  6. class TCPServer : public QDialog
  7. {
  8. Q_OBJECT
  9. public:
  10.     TCPServer();
  11. public slots:
  12.     void runtcp();
  13. private:
  14.     Ui::mainForm ui;
  15. };
  16. class MyThread : public QThread
  17. {
  18. public:
  19.     virtual void run();
  20. private:
  21.     Ui::mainForm ui;
  22. };
  23. #endif


TCPServer.cpp
  1. #include "TCPServer.h"
  2. TCPServer::TCPServer()
  3. {
  4.     ui.setupUi(this);
  5.     QObject::connect(ui.pushButton_1, SIGNAL(clicked()), this, SLOT(runtcp()));
  6.     QObject::connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(close()));
  7. }
  8. void TCPServer::runtcp()
  9. {
  10. MyThread a;
  11. a.start();
  12. }
  13. void MyThread::run()
  14. {
  15. QString strResult;
  16.     for( int count = 0; count < 5; count++ ) {
  17.             sleep( 1 );
  18.             strResult.sprintf("Ping%d!\n",count);
  19.             ui.label->setText(strResult);
  20.         }
  21. }


谢谢大家帮我看看哪里错了,编译没有问题,就是运行没反应,有的时候一点按钮就退出了。
离线foxyz

只看该作者 1楼 发表于: 2009-04-15
class TCPServer : public QDialog
{
Q_OBJECT
public:
    TCPServer();
    //1.加一个函数
    Ui::mainForm * getUiPtr() {return &ui;}
public slots:
    void runtcp();
private:
    Ui::mainForm ui;
};

class MyThread : public QThread
{
public:
   //3.加一个构造函数
    MyThread(Ui::mainForm * pui  = 0)  : QThread() , ui(pui ) {};
    virtual void run();
private:
    //2.改成指针
    Ui::mainForm* ui;
};

void TCPServer::runtcp()
{
//4.下边的改成
MyThread a(getUiPtr());
a.start();
}


void MyThread::run()
{
QString strResult;

    for( int count = 0; count < 5; count++ ) {
            sleep( 1 );
            strResult.sprintf("Ping%d!\n",count);
            //5.加个判断
      if(ui != 0)
                ui->label->setText(strResult);
        }
}
离线hanslh

只看该作者 2楼 发表于: 2009-04-15
你好,太谢谢你了,但是还是没反应,然后再点一下程序就退出了



如上面的图,我点一下Run程序就退出了。
[ 此帖被hanslh在2009-04-15 11:15重新编辑 ]
离线jorneyr

只看该作者 3楼 发表于: 2009-04-15
只要在线程的run方法中不停的发身信号(如wantToChangeText(const QString &)), 然后在主界面中写一个糟函数(changeText(const QString &)), 在里面修改标签的文字就可以了.
离线hanslh

只看该作者 4楼 发表于: 2009-04-15
引用第3楼jorneyr于2009-04-15 13:13发表的  :
只要在线程的run方法中不停的发身信号(如wantToChangeText(const QString &)), 然后在主界面中写一个糟函数(changeText(const QString &)), 在里面修改标签的文字就可以了.


恩,谢谢,我想到过这个办法,但是有一个问题,我试了试似乎QThread无法调用UI的槽函数,好像无法把信号传给槽,就算有个中介可以传递信息,但是无法触发槽运行,还是不行,因为我想要QThread每进行一次消息循环,label就要改变,或增加。

我查了查似乎QThread对UI界面的消息循环无能为力,他只能进行于UI无关的线程,是这样吗?

那么Qt还有别的可以实现我这个愿望的多线程办法吗?为什么QT这么难亚,诶.
离线wbyqy

只看该作者 5楼 发表于: 2009-04-21
在线程类里面加上Q_OBJECT就可以跟UI发信号了
离线huliyaya
只看该作者 6楼 发表于: 2009-06-03
快速回复
限100 字节
 
上一个 下一个