如何让程序忙时保持界面响应

来源: http://m.blog.csdn.net/blog/wangyifei0822/2456147   http://hi.baidu.com/chb_seaok/item/98f8c130c9c662b0633aff0b

 

在GUI编程中,一个老生常谈的问题是,如何在程序繁忙的时候仍然保证程序能够响应用户输入。当一个信号处理函数在进行长时间的处理的时候,界面的确是无 法响应或者重绘的,这个是QT本身的机制决定的。例如,用户点击了“保存文件”的菜单,程序进入了保存的历程,这个过程往往会比较耗时,如果碰上IO问题 那么程序很可能就卡住无法响应了,而用户此时可能会试图取消这个保存的过程。这个问题在QT-4中可以有如下的几种解决方式:

1 调用QApplication::processEvents()。在信号处理函数中多调用几次这个静态函数,强制应用程序响应和重绘,例如:
  void btn_Clicked() {
    // 一些处理……
    QApplication::processEvents();
    // 继续进行另外一些处理……
    QApplication::processEvents();
    // 继续……
  }
  这个方法的好处是简单易用,缺点是不能实时响应改变,有一定的小延时,而且开发人员要时刻想到调用这个方法。

2 使用QThread类进行多线程处理操作,这个方法的优点很明显,就是实时性好,但是实现起来可能会比较麻烦。

3 使用QTimer类,响应计时器事件来重绘界面。这个方法的原理是应用程序不会一直在工作,可能时不时地会有空闲时间,那么可以利用定时器的方式,在程序 空闲的时候重绘界面,只要将定时器的倒数时间定为0就可以了,这样只要程序一空闲,就会响应定时器事件,重绘界面。这个方法的优点是把界面重绘工作交给应 用程序去做无需编程人员干预,缺点也很明显,实时性不高,不一定什么时候应用程序会空闲,能够响应定时器时间。

4 使用QProgressDialog类。这个Dialog是专门为了耗时长的操作定制的,它可以显示一个带有进度条和一个Cancel按钮的小对话框,在操作进行的同时显示进度,并且允许用户退出,具体API情参考 Class QProgressDialog.

 

在qt程序中,我们经常会遇到计算密集型操作或者存在大量I/O操作的时候,GUI就会发生冻结现象,并且会无法响应.仔细分析一下为什么会出现这种情况:因为GUI是一个主线程,而我们如果把计算密集型或者I/O操作放到主线程中去执行,(换句话说我们采用单一线程方案),那我们只能等待事件执行完之后GUI才能进行响应。

      1 有种比较简单的办法是调用QApplication::processEvents(),但是属于治标不治本的方法。这个函数的作用主要就是处理qt在计算事件中处理某个点悬挂的事件。

      qt文档中有句话影响比较深刻:In event you are running a local loop which calls this function continuously, without an event loop, the DeferredDelete events will not be processed.

      2 从单一线程的方式改为多线程的方式。

      qt应用程序中,多线程的操作实现是非常简单的:只需要子类化QThread,实现他的run()函数即可。但是多线程如果在单个CPU中运行相对单线程可能会慢点,多个CPU的话其优势会展现出来。下面我就实现一个多线程的简单案例:

//Thread.h

#ifndef THREAD_H
#define THREAD_H

#include <QThread>
#include<QDebug>

class Thread : public QThread
{
 Q_OBJECT

public:
 Thread(int _type);
 ~Thread();
 void run();  
private:

 int type;         //线程类型1或2
 
};

#endif // THREAD_H

 

//Thread.cpp

#include "Thread.h"

Thread::Thread(int _type)
:type(_type)
{

}

Thread::~Thread()
{

}

void Thread::run()
{
 int count=5;

 while(count>0)
 {
  qDebug()<<"Thread"<<type;           //循环5次打印类型
  count--;
 }
}

 

//main.cpp     main函数中调用

#include <QtCore/QCoreApplication>
#include "Thread.h"

int main(int argc, char *argv[])
{
 QCoreApplication a(argc, argv);

 Thread *pThread1=new Thread(1);    //线程1

 pThread1->start();

 Thread *pThread2=new Thread(2);    //线程2

 pThread2->start();

 

 return a.exec();
}

 

两次运行结果:


                               

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值