《KDE2/Qt编程金典》第四章:显示弹出式对话框——4.8 由KDialogBase派生而来的KMessageBox对话框
由KDialogBase派生而来的KMessageBox对话框 非常普遍的一种对话框是只显示一行或者两行文本,用户用简单的"是"或者"不是"来响应对话框,或者简单地点击按钮关闭对话框.KDialogBase类有一个构造函数特别适用于编写消息对话框,KMessageBox类使用这种特殊的构造函数来实现一组经常使用的消息对话框. 这些消息对话框都是模式对话框,模式对话框等待用户做出响应,在没有响应之前用户不能离开.具体地讲,也就是每个对话框都是由简单的函数调用弹出的,在用户响应并且关闭对话框之前,程序一直处于阻塞状态(没有返回给调用者).这样简化了编程,因为只是向静态函数中的任意点简单地插入一个调用而已. 下面的例子举例说明了9个对话框.在窗口的下部,有一条标签,无论何时有来自对话框的响应,标签的文本就会被更新Mainline1 /* main.cpp */2 #include <kapp.h>3 #include <kcmdlineargs.h>4 #include “mboxes.h”56 int main(int argc,char **argv)7 {8 KCmdLineArgs::init(argc,argv,”mboxes”,9 “Message Boxes”,”0.0”);10 KApplication app;11 Mboxes mboxes;12 mboxes.show();13 app.setMainWidget(&mboxes);14 return(app.exec());15 }主程序创建了一个MBoxs对象,将它设置为应用程序的主窗口.MBoxes Header1 /* mboxes.h */2 #ifndef MBOXES_H3 #define MBOXES_H45 #include <qwidget.h>6 #include <qlabel.h>78 class Mboxes: public QWidget9 {10 Q_OBJECT11 public:12 Mboxes(QWidget *parent=0,const char *name=0);13 private:14 QLabel *label;15 private slots:16 void button1();17 void button2();18 void button3();19 void button4();20 void button5();21 void button6();22 void button7();23 void button8();24 void button9();25 };2627 #endif类的定义中针对9个按钮中的每一个都安排了一个slot,并且包含了将显示在窗口下部的标签.MBoxes1 /* mboxes.cpp */2 #include “mboxes.h”3 #include <qpushbutton.h>4 #include <kmessagebox.h>5 #include <qlayout.h>67 Mboxes::Mboxes(QWidget *parent,const char *name)8 : QWidget(parent,name)9 {10 QPushButton *button;11 QVBoxLayout *layout = new QVBoxLayout(this,3);1213 button = new QPushButton(“Question Yes No”,this);14 layout->addWidget(button);15 connect(button,SIGNAL(clicked()),this,SLOT(button1()));1617 button = new QPushButton(“Question Yes No List”,this);18 layout->addWidget(button);19 connect(button,SIGNAL(clicked()),this,SLOT(button2()));2021 button = new QPushButton(“Warning Yes No”,this);22 layout->addWidget(button);23 connect(button,SIGNAL(clicked()),this,SLOT(button3()));2425 button =26 new QPushButton(“Warning Continue Cancel”,this);27 layout->addWidget(button);28 connect(button,SIGNAL(clicked()),this,SLOT(button4()));2930 button = new QPushButton(“Warning Yes No Cancel”,this);31 layout->addWidget(button);32 connect(button,SIGNAL(clicked()),this,SLOT(button5()));3334 button = new QPushButton(“Error”,this);35 layout->addWidget(button);36 connect(button,SIGNAL(clicked()),this,SLOT(button6()));3738 button = new QPushButton(“Sorry”,this);39 layout->addWidget(button);40 connect(button,SIGNAL(clicked()),this,SLOT(button7()));4142 button = new QPushButton(“Information”,this);43 layout->addWidget(button);44 connect(button,SIGNAL(clicked()),this,SLOT(button8()));4546 button = new QPushButton(“About”,this);47 layout->addWidget(button);48 connect(button,SIGNAL(clicked()),this,SLOT(button9()));4950 label = new QLabel(“-”,this);51 layout->addWidget(label);52 resize(10,10);53 }54 void Mboxes::button1()55 {56 int result = KMessageBox::questionYesNo(this,57 “Are you sure you want to delete\nall “58 “the files in this directory?”,59 “questionYesNo”);60 switch(result) {61 case KMessageBox::Yes:62 label->setText(QString(“Yes”));63 break;64 case KMessageBox::No:65 label->setText(QString(“No”));66 break;67 }68 }69 void Mboxes::button2()70 {71 QStringList list;72 list.append(“fork”);73 list.append(“spoon”);74 list.append(“knife”);75 int result = KMessageBox::questionYesNoList(this,76 “Are you sure you want to delete\nall “77 “the items shown in the list?”,78 list,79 “questionYesNoList”);80 switch(result) {81 case KMessageBox::Yes:82 label->setText(QString(“Yes”));83 break;84 case KMessageBox::No:85 label->setText(QString(“No”));86 break;87 }88 }89 void Mboxes::button3()90 {91 int result = KMessageBox::warningYesNo(this,92 “Reset all status codes?”,93 “warningYesNo”);94 switch(result) {95 case KMessageBox::Yes:96 label->setText(QString(“Yes”));97 break;98 case KMessageBox::No:99 label->setText(QString(“No”));100 break;101 }102 }103 void Mboxes::button4()104 {105 int result = KMessageBox::warningContinueCancel(this,106 “Overwrite the existing file?”,107 “warningContinueCancel”,108 QString(“Overwrite”));109 switch(result) {110 case KMessageBox::Continue:111 label->setText(QString(“Continue”));112 break;113 case KMessageBox::Cancel:114 label->setText(QString(“Cancel”));115 break;116 }117 }118 void Mboxes::button5()119 {120 int result = KMessageBox::warningYesNoCancel(this,121 “Quitting without saving the file could result\n”122 “in loss of data. Save before quitting?”,123 “warningYesNoCancel”);124 switch(result) {125 case KMessageBox::Yes:126 label->setText(QString(“Yes”));127 break;128 case KMessageBox::No:129 label->setText(QString(“No”));130 break;131 case KMessageBox::Cancel:132 label->setText(QString(“Cancel”));133 break;134 }135 }136 void Mboxes::button6()137 {138 KMessageBox::error(this,139 “Unable to save configuration data.”);140 }141 void Mboxes::button7()142 {143 KMessageBox::sorry(this,144 “The file you specified contains no data.”);145 }146 void Mboxes::button8()147 {148 KMessageBox::information(this,149 “Pressing Esc will clear the window.”);150 }151 void Mboxes::button9()152 {153 KMessageBox::about(this,154 “This is a simple about-box that can\n”155 “contain several lines of text”);156 } 这个被用作主窗口的部件创建了9个按钮和一个标签,并且把它们全部都放置到一个垂直框中.每个按钮的clicked()按钮都连接到一个相对应的局部slot,这些slot将创建和显示每个信息框. 在第11行创建了一个垂直框.第13行到第51行创建了9个按钮和一个标签,它们共同组成主窗口. 第13行到第15行创建了一个按钮,在第54行将它与button1()slot连接到一起.第56行调用了方法questionYesNo(),他来弹出消息框,然后等待用户的响应.第59行的字符串参数作为消息框的标题.函数返回的值由按下哪个按钮来决定.所有消息框返回的值都在KMessageBOx类中进行定义. 第61行的开关语句判断来自questionYesNo()返回的值是来自Yes或者No.在主窗口下部的标签将被一个代表返回结果的字符串所更新. 对于所有的消息框来说,显示的大小和外观都是由用户来控制的,因为用户可以决定文本行的长度,以及显示行的数量.第57行和第58行指定了questionYesNo()消息框的文本.文本定义为一个字符串,中间插入了"\u"字符,在插入此字符的地方文本将被断开为两行.C++能够把分开的两行连接成一个大的字符串,这样在当面中可以更轻松的编写文本. 第17行到第19行创建了一个按钮,并把它和第69行开始的button2()slot连接到一起.这个消息框,在第75行创建,像前面程序一样询问Yes还是No,同时它还包含一个显示列表项的窗口.当需要提出和一组选项相关的问题时,就可以使用这个消息框.用户并没有办法增加或者删除项目--只能全部支持或者全部所有的列表选项. 显示的列表是在第71行创建的QStringList对象,在第72行到第74行插入了3个字符串.这个字符串列表在第78行被用作参数,在第79行的字符串指定了窗口的标题. 第21行到第23行创建了一个按钮,并把它和第89行开始的button3()slot连接到一起.第91行调用warningYesNo()和第56行调用questionYesNo()非常相似,只不过图形显示以及文本不一样. 第25行到第28行创建了一个按钮,并把它和第103行开始的button4()slot连接在一起.warningContinueCancel()消息框的设计是让用户知道将要进行 一些动作,使用户能够决定是否应当继续执行还是停止.这个例子,警告用户继续执行将会覆盖一个已经存在的文件. 一些消息框允许用户重写按钮标签,在这例子中,第108行将QString用作一个参数,把按钮的标签由默认的Continue改变为Overwrite.在按钮上改变标签并不改变返回值--第110行的语句将对应的值命名为Continue,它由标签名为Overwrite的按钮返回. 有时候简单地回答是或者不是不能满足用户的需求.第30行到第32行创建了一个按钮,并把它和第118行开始的button5()slot连接在一起.这种情况相当常见.例如考虑这样一条消息,"准备删除文件.你希望也删除子目录么?"用户需要能够指定删除的路径和文件,路径被保留,或者删除所有的一切. 第34行到第36行创建了一个按钮,并把它和第136行开始的button6()slot连接到一块,第138行的调用error()创建了一个消息框,这个消息框没有返回值,因为这个消息框一般只用在程序不能完成它本应当能完成的工作的情况下. 第38行到第40行创建了一个按钮,并把它和第141行开始的button7()slot连接到一起.第143行调用sorry()函数,这个消息框一般用在程序不能继续执行的情况下,但起因来自程序控制之外(例如丢失一个文件等等). 第42行到第44行创建了一个按钮,并把它和第146行开始的button8()slot连接到一起.第148行调用了函数information(),这个消息框包含了不影响处理过程的消息,但这些消息用户有必要知道. 第46行到第48行创建了一个按钮,并把它和第151行开始的button9()slot连接到一起,这个消息框是所有消息框中最简单的,它没有图形修饰,也不返回值.第153行调用了about()函数,创建了此消息框,函数命名为about()是暗示它可以用作非常简单的About消息框.