• 9908阅读
  • 0回复

【摘录】《KDE2/Qt编程金典》第五章:预定义对话框——5.4 QProgressDialog对话框 [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2005-12-25
QProgressDialog对话框

有时程序需要完成一项需要花费几秒钟的工作。如果耽搁的时间短,那么可以把光标的图像改变为一只表并且告诉用户,“程序正在运行,请稍等一会儿。”如果等待的时间很长(例
如,15秒钟,或者更多),那么提供更多的关于程序运行情况的有关信息将是很友好的。QProgressDialog可以用来显示一个任务完成情况的百分比,可以把它设置
成只有等待时间足够长的时候才弹出来。
 
下面的程序举例说明了使用QProgressDialog的两种方法。主窗口上含有两个按钮,它们用来弹出QProgressDialog窗口,。这个对话框通常用来显示
一些花费时间的过程,比如传输数据、处理一个大文件等等,但为了说明问题,这个程序中只是简单使用了基于计算过程的操作。
Progress Header

1 /* progress.h */
2 #ifndef PROGRESS_H
3 #define PROGRESS_H
4
5 #include <qprogressdialog.h>
6 #include <qwidget.h>
7 #include <qtimer.h>
8
9 class Progress: public QWidget
10 {
11 Q_OBJECT
12 public:
13 Progress(QWidget *parent=0,const char *name=0);
14 private:
15 QProgressDialog *progressDialog;
16 QTimer *timer;
17 private slots:
18 void slot15();
19 void slot60();
20 void timerStep();
21 };
22
23 #endif


Progress类有3个slot和1个计数器。2个slot方法slot15()和slot60()分别用来启动持续15秒和60秒的过程对话框。计数器,以及time
Step() slot用来内部记录使用的时间。
Progress

1 /* progress.cpp */
2 #include <unistd.h>
3 #include <kapp.h>
4 #include <qpushbutton.h>
5 #include <qlayout.h>
6 #include “progress.h”
7
8 int main(int argc,char **argv)
9 {
10 KApplication app(argc,argv,”progress”);
11 Progress progress;
12 progress.show();
13 app.setMainWidget(&progress);
14 return(app.exec());
15 }
16
17 Progress::Progress(QWidget *parent,const char *name)
18 : QWidget(parent,name)
19 {
20 QPushButton *button;
21 QVBoxLayout *box = new QVBoxLayout(this,12);
22
23 button = new QPushButton(“15 Seconds”,this);
24 box->addWidget(button);
25 connect(button,SIGNAL(clicked()),
26 this,SLOT(slot15()));
27
28 button = new QPushButton(“60 Seconds”,this);
29 box->addWidget(button);
30 connect(button,SIGNAL(clicked()),
31 this,SLOT(slot60()));
32
33 resize(10,10);
34 box->activate();
35 }
36 void Progress::slot15()
37 {
38 int currentStep = 0;
39 int steps = 15;
40
41 progressDialog = new QProgressDialog(
42 “Fifteen seconds..”,”Cancel”,
43 steps,this,”pgrs”,TRUE);
44 progressDialog->setCaption(“Progress”);
45 while(currentStep < steps) {
46 progressDialog->setProgress(currentStep++);
47 if(progressDialog->wasCancelled())
48 break;
49 sleep(1);
50 }
51 progressDialog->setProgress(steps);
52 delete progressDialog;
53 progressDialog = NULL;
54 }
55 void Progress::slot60()
56 {
57 int currentStep = 0;
58 int steps = 20;
59
60 progressDialog = new QProgressDialog(this,”prgs”,TRUE);
61 progressDialog->setCaption(“Progress”);
62 progressDialog->setLabelText(“Sixty seconds...”);
63 progressDialog->setCancelButtonText(“Quit”);
64 progressDialog->setTotalSteps(steps);
65 progressDialog->setMinimumDuration(3000);
66
67 timer = new QTimer(this);
68 connect(timer,SIGNAL(timeout()),
69 this,SLOT(timerStep()));
70 timer->start(3000,FALSE);
71 }
72 void Progress::timerStep()
73 {
74 int currentStep;
75 int steps = 20;
76
77 if(progressDialog == NULL)
78 return;
79
80 if(progressDialog->wasCancelled()) {
81 delete timer;
82 delete progressDialog;
83 progressDialog = NULL;
84 return;
85 }
86 currentStep = progressDialog->progress();
87 if(currentStep >= steps) {
88 delete timer;
89 delete progressDialog;
90 progressDialog = NULL;
91 } else {
92 progressDialog->setProgress(currentStep + 1);
93 }
94 }


第8行开始的主程序代码,创建了一个Progress对象并把它作为顶层窗口。顶层部件是一个Progress部件,由第17行的构造函数创建。一个竖直框用来包含两个按
钮。这两个按钮被连接到两个slot方法,即slot15()和slot60()。
 
第36行开始的slot方法slot15(),举例说明了如何在一个循环中使用过程条。过程百分比是由当前的步数相对于所有步数的比例决定的。第38行指定了当前步(起始
步)为0,第39行定义了总的步数为15。第41行的构造函数创建了QProgressDialog并且设置了总的步数。同时此构造函数也设置了部件的标题文本和名称;并
且指定值为TRUE,此对话框为模式对话框。第44行调用了setCaption(),用来指定对话框标题栏中的文本。
 
第45行开始的循环用来仿真过程条报告的活动。循环所做的就是增加当前的步数并且等上一秒。在一个真实环境下的应用程序中,可以计算下一步的值,然后用这个值调用setP
rogress()。如果用户选择了Cancel按钮,那么第47行的调用wasCancelled()将返回TRUE,因此这个循环将提前退出。通常,如果选择了Can
cel按钮,那么应该让代码在循环之内,在计数过程中放置中止部分,但由于这个程序什么也不做,因此只是简单的跳出循环。
 
第51行的调用setProgress()保证了对话框可以适当地被关闭。当一个模式的对话框开始运行的时候,它首先改变光标为表的形状。然后在它弹出之前等待一小段时间
。在当前的值每次增加时都将更新显示。一旦最后一步完成了,它恢复最初的光标,然后关闭自己。第51行调用setProgress()是必需的,因为这样循环可以在不达到
最大步数时跳出。
   
第55行开始的名为slot60()的slot方法使用了一个完全不同的方法来创建和更新QProgressDialog。第57行和第58行设置开始值为0,步数为20
。第60行创建了这个对话框,使用了一个比上面简单些的构造函数。第61行到第65行调用的方法用来指定窗口标题文本、指定显示在对话框中的标签文本、改变Cancel按
钮的文本,以及设置要完成的总步数。
   
第65行调用setMinimumDuration()设置弹出延迟时间为3000毫秒,这是对话框在弹出它自己之前要等待的时间。设置为3000毫秒可以让光标改变为表
的形状,然后什么也不做,等待3秒。采用这种方法,对于时间少于3秒的任务将不会显示对话框。
     
第67行到第70行创建了一个计数器,并让它开始运行。计数器的timeout()信号和这个类的slot方法timerStep()连接到一起,第70行的调用初始化计
数器为3秒。第2个参数被设置为FALSE,意味着这不是一个一次触发计数器--这个计数器将持续运行,每隔3秒触发一次,直到它停止。如果第2个参数设置为TRUE,那
么计数器将只触发一次。实际上,为了有一个持续运行
的计数器,这两种方式基本一样可用。如果它一直持续运行,用户可以在结尾时中止它。如果它是一个一次触发计数器,那么可以在每次它触发时重启它。
       
第72行名为timerStep()的slot在每次计数器触发的时候执行。如果用户选择了Cancel按钮来中止运行,那么第80行的wasCancelled()调用
将为TRUE。第86行的progress()调用返回当前的步数,如果第87行发现已经到达终点,那么计数器和对话框都将被删除。如果还在过程中,那么第92行的set
Progress()调用将增加当前的步数。
       
只要对话框被删除,那么命名为progressDialog的指针将设置为NULL,第77行可以测试是否为NULL。由于QTimer工作的方式,所以这个测试是必要的
。为了得到计数,QTimer向进入事件队列中插入了特殊的事件;又由于事件队列相对于应用程序是不同步的,所以当QProgressDialog()被删除时,QTim
er可能还有时间事件停留在输入队列中,这意味着slot方法timerStep()将被多执行一次。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个