• 15071阅读
  • 8回复

为什么我的QT多线程程序无法退出? [复制链接]

上一主题 下一主题
离线vaqeteart
 

只看楼主 正序阅读 楼主  发表于: 2009-12-09
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
我编写了一个QThread的程序,可是无法退出,为什么?代码如下:
  1. //main.cpp
  2. /*程序功能:一个多线程程序的例子,没有设置同步机制。具体可以参见官方文档:
  3. * [url]http://qt.nokia.com/doc/4.5/qthread.html#details[/url]
  4. * 具体实现的是:
  5. * 每次点击一个按钮都会启动一个线程并且执行,
  6. * 执行的内容是定时每一秒打印一个公共数字i++,和一个私有数字j++。
  7. * 每个线程执行5次就自动退出。
  8. *
  9. * 注意:线程想要链接外部信号到自己的槽则需要在run()主函数中运行exec()启动自己的事件循环。
  10. * */
  11. #include <QApplication>
  12. #include "myCallback.h"
  13. int main(int argc, char *argv[])
  14. {
  15.     QApplication app(argc, argv);
  16.     MyCallback my;
  17.     my.show();
  18.     int status = app.exec();
  19.     return status;
  20. }


  1. //myCallback.h
  2. #ifndef __MYCALLBACK_H
  3. #define __MYCALLBACK_H
  4. #include <QWidget>
  5. #include <QThread>
  6. class QPushButton;
  7. class MyThread: public QThread
  8. {
  9.     Q_OBJECT
  10.     public:
  11.     MyThread(QObject *parent = 0):QThread(parent){j = 0;}
  12.     //这个函数是在执行start调用的时候执行,作为thread的"main"来运行。
  13.     void run();
  14.     protected slots:
  15.         void myPrint(void);
  16.     private:
  17.         int j;
  18. };
  19. class MyCallback:public QWidget
  20. {
  21.     Q_OBJECT
  22.     public:
  23.         MyCallback(QWidget *parent = 0);
  24.     protected slots:
  25.         void callback(void);
  26.     private:
  27.     QPushButton *btn;
  28.     MyThread *t;
  29. };
  30. #endif


  1. //myCallback.cpp
  2. #include <QPushButton>
  3. #include <QTimer>
  4. #include "myCallback.h"
  5. #include <iostream>
  6. using std::cout;
  7. using std::endl;
  8. void MyThread::run()
  9. {//线程的主函数
  10.     QTimer::singleShot(1000, this, SLOT(myPrint()));
  11.     //启动线程自己的事件循环
  12.     exec();//没有这句话,执行不到singleShot的槽,有了循环才能执行信号和槽的链接
  13. }
  14. void MyThread::myPrint(void)
  15. {
  16.     QTimer::singleShot(1000, this, SLOT(myPrint()));//这样就实现周期调用了
  17.     static int i = 0;
  18.     cout<<"print static i:";
  19.     cout<<i++<<endl;
  20.     cout<<", private j:"<<j++<<endl;//每个线程的数据不同
  21.     if(j > 5)
  22.     {//退出线程的循环
  23.         cout<<"will quit"<<endl;
  24.         //exit(0);//不管用?
  25.         quit();//不管用?
  26.     }
  27. }
  28. MyCallback::MyCallback(QWidget *parent):QWidget(parent)
  29. {
  30.     t = NULL;
  31.     btn = new QPushButton(this);
  32.     QObject::connect(btn, SIGNAL(clicked()), this, SLOT(callback()));
  33. }
  34. void MyCallback::callback(void)
  35. {
  36.     cout<<"called callback!"<<endl;
  37.     
  38.     //启动线程
  39.     //线程调用之后立即会发送一个started信号
  40.     //结束之后会发送一个finished信号
  41.     t = new MyThread(this);//必须新建立一个线程对象实现多线程否则还是单线程
  42.     t->start();
  43. }
离线oscarboycn

只看该作者 8楼 发表于: 2010-03-31
这个周期调用不错,收藏了
http://www.21ic.com
http://bbs.eetop.cn
http://www.eetop.cn/
http://www.eet-china.com/
http://www.netyi.net/
http://www.pcbbbs.com/
http://www.pcbtech.net/
离线vaqeteart

只看该作者 7楼 发表于: 2009-12-10
引用第4楼yb824于2009-12-09 16:22发表的  :
感觉是你这句的问题~
QTimer::singleShot(1000, this, SLOT(myPrint()));
改成这样    
  QTimer *timer = new QTimer;
    connect(timer, SIGNAL(timeout()), this, SLOT(myPrint()));
.......

谢谢,确实这样就好了。多谢!
但是之前的方法不管用,是什么原因呢?
离线yb824
只看该作者 6楼 发表于: 2009-12-09
run()
{
    exec();//没有这个线程运行完就结束了
}
离线20044454
只看该作者 5楼 发表于: 2009-12-09
我也遇到一个类似的问题
我的run()
{
  exec(); //有这个这
}

stop()
{
    wait();// 有僵死 无则出现段错误
   terminate(); //

}
如果这样
run()
{
    // exec(); //没有这个这
}

stop()
{
    wait();// 在可以接收到TCP或者UDP数据时 没问题,如果没数据停止时 僵死
   terminate(); //

}
让我做一个Qt的大牛!!!!
离线yb824
只看该作者 4楼 发表于: 2009-12-09
感觉是你这句的问题~
QTimer::singleShot(1000, this, SLOT(myPrint()));
改成这样    
  QTimer *timer = new QTimer;
    connect(timer, SIGNAL(timeout()), this, SLOT(myPrint()));
    timer->start(1000);
离线vaqeteart

只看该作者 3楼 发表于: 2009-12-09
谢谢,你运行过这个程序了吗?
运行的时候点击按钮就会建立一个线程,然后屏幕不断的打印数字,打印5次之后应该就退出线程不再打印了,但是我运行了却没有退出,一直在打印数字。
离线yb824
只看该作者 2楼 发表于: 2009-12-09
quit();可以退出啊
离线vaqeteart

只看该作者 1楼 发表于: 2009-12-09
void MyThread::myPrint(void)
{
    QTimer::singleShot(1000, this, SLOT(myPrint()));//这样就实现周期调用了
    static int i = 0;
    cout<<"print static i:";
    cout<<i++<<endl;
    cout<<", private j:"<<j++<<endl;//每个线程的数据不同
    if(j > 5)
    {//退出线程的循环
        cout<<"will quit"<<endl;
        //exit(0);//不管用?
        quit();//不管用?
    }
}
里面的exit和quit都无法退出run的循环。
快速回复
限100 字节
 
上一个 下一个