1、QDialog派生对话框
除了QDialog外,Qt中还提供了一些从QDialog派生的Dialog,如:
①、颜色对话框QColorDialog用来显示和获取用户选择的颜色,QColor为颜色类。
//QColorDialog::getColor显示一个模态颜色对话框并获得用户选择的颜色 QColor clr(255/*r*/, 255/*g*/, 255/*b*/, 255/*alpha*/); clr = QColorDialog::getColor(Qt::red/*初始颜色*/, this/*父窗口*/, QString::fromUtf8("颜色对话框")/*标题*/, QColorDialog::ShowAlphaChannel/*显示透明度设置,可选*/); qDebug() << clr; //输出为:QColor(ARGB 1, 1, 0, 0)
②、文件对话框QFileDialog用来显示一个选择文件/文件夹、保存文件功能的对话框。
QFileDialog::getOpenFileName显示一个文件选择模态对话框,QFileDialog::getOpenFileNames显示一个多文件选择模态对话框 QFileDialog::getExistingDirectory显示一个目录选择模态对话框,QFileDialog::getSaveFileName显示一个保存文件对话框或文件另存为对话框 QString str = QFileDialog::getOpenFileName(this/*父窗口*/, QString::fromUtf8("文件对话框")/*标题*/, "C:"/*初始打开目录*/, QString::fromUtf8("图片文件(*png *jpg);;文本文件(*txt)")/*文件类型,可选*/); qDebug() << str; //输出为"C:/condition_select_btn_normal.png"
③、字体对话框QFontDialog提供了一个可以选择字体的对话框。
//QFontDialog::getFont显示一个模态字体对话框并获得用户选择的字体 bool bOk; QFont font = QFontDialog::getFont(&bOk/*是否点击了ok按钮*/, this/*父窗口*/); if(bOk) ui->pushButton->setFont(font); //设置按钮字体
④、输入对话框QInputDialog提供了一个接收和获取用户输入的对话框,并且可以设置只接收用户输入text或int或double。QInputDialog还可以提供具有一个下拉列表供用户选择的对话框。
QInputDialog::getText显示一个字符串输入对话框 QInputDialog::getInt显示一个输入整型数值的对话框 QInputDialog::getDouble显示一个输入浮点型数值的对话框 bool bOk; QString str = QInputDialog::getText(this/*父窗口*/, QString::fromUtf8("输入字符串对话框")/*标题*/, QString::fromUtf8("请输入用户名")/*说明文字*/, QLineEdit::Normal/*还有Password等输入显示模式*/, "admin"/*默认文本*/, &bOk/*是否点击了确认按钮*/); int value = QInputDialog::getInt(this/*父窗口*/, ""/*标题*/, ""/*说明*/, 100/*默认显示*/, -1000/*最小值*/, 1000/*最大值*/, 10/*使用箭头按钮,数值每次变化10*/, &bOk/*是否点击了确认按钮*/); QStringList items = {"item1", "item2"}; QString item = QInputDialog::getItem(this, "", "", items, 0/*默认显示第一个条目*/, true/*条目可以修改*/, &bOk);
⑤、消息提示对话框QMessageBox提供一个模态对话框来显示信息和提示用户,使用如下:
//问题对话框 int ret1 = QMessageBox::question(this, "question dialog", "Do you understand Qt?", QMessageBox::Yes, QMessageBox::No); if(ret1 == QMessageBox::Yes) qDebug() << "I understand Qt."; //提示对话框 int ret2 = QMessageBox::information(this, "information dialog", "this is Qt", QMessageBox::Ok); if(ret2 == QMessageBox::Ok) qDebug() << "Ok Qt."; //警告对话框 int ret3 = QMessageBox::warning(this, "warning dialog", "Qt Warning!", QMessageBox::Abort); if(ret3 == QMessageBox::Abort) qDebug() << "Warning."; //错误对话框 int ret4 = QMessageBox::critical(this, "error dialog", "Qt error!", QMessageBox::YesAll); if(ret4 == QMessageBox::YesAll) qDebug() << "error."; //关于对话框 QMessageBox::about(this, "about dialog", "this is about dialog");
如果想使用自己的图标或自定义按钮,那么可以自己创建QMessageBox对象,然后调用相关函数来进行操作:
QMessageBox box(QMessageBox::Question, "title", "text", QMessageBox::Yes/* | QMessageBox::No*/); QPushButton btn("No"); box.addButton(&btn, QMessageBox::NoRole); int select = box.exec(); if(select == QMessageBox::Yes) qDebug() << "select Yes"; else if(select == QDialog::Rejected) qDebug() << "select No";
⑥、进度对话框QProgressDialog提供了一个进度条来显示进度,使用如下:
void MainWindow::on_pushButton_clicked() { //最小值和最大值之差指定了进度总步数,总步数越大进度从0到100%时间越长 int minValue = 0; int maxValue = 100000; //十万的步数进度从0到100%大概为三四秒 QProgressDialog* dialog = new QProgressDialog("current progress", "cancel", minValue, maxValue, this); dialog->setWindowTitle("ProgressDialog"); dialog->setModal(true); dialog->setAutoClose(false); dialog->setAutoReset(false); dialog->show(); for(int i=0; i< maxValue + 1; i++) { dialog->setValue(i); //移动进度到指定位置 QApplication::processEvents();//防止用户界面冻结 if(dialog->wasCanceled())//判断用户是否点击了取消按钮 break; } }
上面的QApplication::processEvents()用来处理消息队列中的未决事件,因为整个循环操作很有可能会持续一段时间,而这时候QProgressDialog界面会无响应,所以可以调用这个方法来处理未决的消息事件。
因为模态的QProgressDialog的setValue方法中会调用QApplication::processEvents,所以我们使用QProgressDialog的时候需要注意,比如不能在paintEvent方法中使用QProgressDialog,否则可能产生递归崩溃(paintEvent中调用setValue,setValue中产生paint event,processEvents中调用paintEvent)。
虽然模态的QProgressDialog的setValue方法中也会调用QApplication::processEvents,但个人猜测也许是由于setValue中的QApplication::processEvents并不是必然调用或者其它原因,我们需要再次手动调用QApplication::processEvents()来防止QProgressDialog界面冻结。
⑦、错误信息对话框QErrorMessage可以用来显示错误信息:
void MainWindow::on_pushButton_clicked() { QErrorMessage* pMsg = new QErrorMessage(this); pMsg->setWindowTitle(QString::fromStdWString(L"向导对话框 ")); pMsg->showMessage(QString::fromWCharArray(L"错误信息")); }
⑧、向导对话框QWizard提供了一个设计向导界面的框架,简单使用如下所示,Qt示例中有三个使用QWizard深成向导对话框的例子:Class Wizard、License Wizard、Trivial Wizard。
void MainWindow::on_pushButton_clicked() { QWizardPage* page1 = new QWizardPage; page1->setTitle(QString::fromUtf8("对话框")); QWizardPage* page2 = new QWizardPage; page2->setTitle(QString::fromUtf8("用户选择信息页面")); QWizardPage* page3 = new QWizardPage; page3->setTitle(QString::fromUtf8("结束页面")); QWizard w(this); w.setWindowTitle(QString::fromStdWString(L"向导对话框 ")); w.setTitleFormat(Qt::PlainText); w.addPage(page1); w.addPage(page2); w.addPage(page3); w.exec(); }
⑨、还有几个跟打印有关的对话框:QPageSetupDialog页面设置对话框、QPrintDialog打印对话框、QPrintPreviewDialog打印预览对话框。
2、QFrame
QFrame边框类是带有边框部件的基类,QFrame的子类有QLabel、QLCDNumber、QStackedWidget、QToolBox和QAbstractScrollArea等。QAbstractScrollArea类是所有带有滚动条类的抽象基类,QTextEdit文本编辑器类就是QAbstractScrollArea的子类。我们可以在设计模式下对这些部件的边框属性(frameShape、frameShadow、lineWidth、midLineWidth)进行修改设置,以达到不同的边框和界面效果,如下所示:
下面是对一个QLabel(frameShadow默认为palin),lineWidth设为1,midLineWidth设为0,frameShape进行不同的设置的效果:
下面手对一个QFrame的frameShape、frameShadow、midLineWidt进行不同设置的效果:
也可以在代码中使用QFrame的方法来对边框进行设置:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //ui为设计类对象指针,frame为QFrame对象指针 ui->frame->setFrameShape(QFrame::Box); ui->frame->setFrameShadow(QFrame::Sunken); ui->frame->setLineWidth(5); ui->frame->setMidLineWidth(1); }
3、QLabel
QLabel可以用来显示文本或图片。可以设置其alignment属性修改显示方式,如水平选择AlignHCenter,垂直选择AlignVCenter,这样就能在正中间显示。
显示图片的方法为先添加头文件<QPixmap>,然后添加以下代码:
MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); ui->label_2->setPixmap(QPixmap("F:/logo.png")); }
显示gif动态图片的方法为先添加头文件<QMovie>,然后添加以下代码:
MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); QMovie* movie = new QMovie("F:/logo.gif"); ui->label_2->setMovie(movie); movie->start(); }
4、QLCDNumber
QLCDNumber部件可以显示类似LCD液晶屏一样效果的数字或特定字母,通过修改部件属性来设置该部件:smallDecimalPoint设置显示小数点,digitCount设置显示数字个数,mode设置十进制(Dec)、十六进制(Hex)、二进制(Bin)等显示,segmentStyle设置数码显示样式,value设置要显示的数值,也可以通过方法display()来设置显示的数值。它可以显示部分与数值相关的字符如A、B、C、D、E、F、g,还可以显示度符号(输入时使用单引号来替代)。效果如下所示:
5、QStackedWidget
QStackedWidget是一个能提供具有多个Widget界面的部件,但当前显示的只有一个Widget界面,可以设置当前显示哪一个Widget界面。在界面设计下可以通过QStackedWidget控件右上角的箭头来选择当前显示的页面,也可以在代码中通过setCurrentIndex方法来设置。
我们可以在当前窗口的QStackedWidget部件下放置一个button,然后点击右上角的箭头切换到另一个页面再放置一个Label,然后在这个窗口下添加一个QListWidget,通过list的选择来设置当前QStackedWidget页面的显示,方法是在设计模式下进入信号/槽编辑模式,拖动QListWidget到QStackedWidget,将QListWidget的currentRowChanged信号和QStackedWidget的setCurrentIndex槽关联起来,代码实现关联的话就是使用connect方法:QObject::connect(listWidget, SIGNAL(currentRowChanged(int)), stackedWidget, SLOT(setCurrentIndex(int)))。
6、QToolBox
QToolBox是一个可以显示一列层叠窗口部件,就像QQ联系人列表一样的多个列表展示界面,只有一个列表可以被当前展开。我们在设计模式下将一个QToolBox放到当前窗口下(frameShape选择Box),可以看到默认有两个窗口页面,当前页面为Page1,点击Page2后当前页面为Page2,通过currentItemText属性来设置当前页面的标题名,我们将他俩改成“好友”、“陌生人”之后再右击QToolBox选择插入页,再设置其名称为“黑名单”,再运行程序就会看到以下显示效果:
7、Button
QAbstractButton是按钮部件的抽象基类,QPushButton、QRadioButton、QCheckBox等Button部件都是从其派生而来的。
①、QPushButton
如图,Button1是一个普通的QPushButton。们可以右键按钮->转到槽->选择clicked()信号 来添加信号/槽。
Button2是在设计模式下将其checked属性设置,这样点击Button就会有选中和取消的效果。我们可以右键按钮->转到槽->选择clicked(bool)信号 来添加信号/槽,其中bool表示是否checked。
Button3是在设计模式下将其flat属性设置,使其没有了边框。
Button4是一个设置了图标的QPushButton,实现方法见下。
Button5是一个附加下拉菜单的按钮,类似comboBox控件,实现方法见下方:
MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); ui->pushBtn4->setIcon(QIcon("F:/img.png")); QMenu* menu = new QMenu(this); menu->addAction(QIcon("F:/log.png"), "item1"); menu->addAction(QIcon("F:/log.png"), "item2"); ui->pushBtn5->setMenu(menu); }
QToolButton也可以实现带一个下拉菜单的效果:
QMenu* menu = new QMenu(this); menu->addAction("item1"); menu->addAction("item2"); ui->toolButton->setMenu(menu); ui->toolButton->setPopupMode(QToolButton::MenuButtonPopup);
②、QCheckBox和QRadioButton
复选按钮QCheckBox和单选按钮QRadioButton一般是放到QGroupBox中来使用,如下图所示:
对于QCheckBox我们可以在设计模式下右击->转到槽->选择stateChanged(int)信号来 定义信号/槽,其参数int可以表示选择状态。
对于QRadioButton我们可以在设计模式下右击->转到槽->选择clicked(bool)信号来 定义信号/槽,其参数bool可以表示是否选中。
在代码中我们可以使用QButtonGroup类来管理QCheckBox、QRadioButton按钮:
QButtonGroup group; group.addButton(ui->radioButton); ui->radioButton_2->setChecked(true); group.addButton(ui->radioButton_2); group.setExclusive(true); auto pBtn = group.checkedButton(); assert(pBtn == ui->radioButton_2);
8、QLineEdit
QLineEdit是一个单行编辑器,它还自动提供了剪切、复制、黏贴、撤销的功能。
①、可以在设计模式下修改QLineEdit的echoMode属性,其中Normal为正常输入,NoEcho为不显示输入,Password为密码输入样式,PasswordEchoOnEidt为在编辑时显示正常字符,其它情况下为密码样式。
②、可以通过设置inputMask(输入掩码)属性来限制输入的内容,掩码含义如下,比如设置成A为只能输入A-Z,a-z,X为只能输入0-9,>AA-!A表示应该输入4个字符,第三个字符为'-',字符'-'之前的应该为大写,前两个字符应该为字母,第四个字符为'A':
③、可以通过QValidator验证器来进一步限制QLineEdit的输入,比如限制输入100-999之间的数字使用QIntValidator,如下示例,限制输入浮点型数值的话使用QDoubleValidator验证器。
MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); QValidator* validator = new QIntValidator(100, 999, this); ui->lineEdit->setValidator(validator); }
如果想要设置一般的字符约束,就要使用QRegexpValidator正则表达式验证器了,如以下实现了在开头输入'-'或者不输入,然后再可以输入最多三个数字:
MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); QRegExp rx("-?\d{1,3}"); QValidator* validator = new QRegExpValidator(rx, this); ui->lineEdit->setValidator(validator); }
④、还可以通过QCompleter实现自动补全功能:
QCompleter* com = new QCompleter({"qt", "qt_list", "qtTest", this); com->setCaseSensitivity(Qt::CaseInsensitive); //设置大小写不敏感 ui->lineEdit->setCompleter(com);
⑤、在设计模式下右击QLineEdit->转到槽->可以看到有textChanged()、returnPressed()等信号,可以对其实现槽函数。
9、数值设定框
QTimeEdit、QDateEdit、QDateTimeEdit提供了对时间和日期的修改,QSpinBox和QDoubleSpinBox分别可以用来设置整数和浮点数,如下图所示:
将QTimeEdit属性dispalyFormat设置为hh:mm:ss.zzz表示00:00:00.000(24小时),h:m:sA表示0:0:0(12小时)。设置QDateEdit的calendarPopup属性就可以使用弹出的日历部件来设置日期。也可以使用代码来设置QDateTimeEdit:
ui->dateTimeEdit->setDateTime(QDateTime::currentDateTime()); ui->dateTimeEdit->setDisplayFormat(QString::fromStdWString(L"yyyy年mm月dd日 ddd hh时mm分ss秒"));
在设计模式下还可以对QSpinBox、QDoubleSpinBox的一些属性进行设置,比如suffix后缀属性可以设置成%可以用于显示百分数,prefx前缀属性设置成¥可以用来表示人民币,还可以设置其最大值maximum、最小值minimum、单步值singleStep、小数位数decimals等。
10、Slider滑块部件
QAbstractSlider是一个虚基类,QScrollBar滚动条、QSlider进度控制、QDial刻度表盘等部件都是从它派生的。
设计模式下QDial的notchesVisible属性用来设置是否显示刻度,notchTarget属性用来设置刻度之间的间隔,wrapping属性用来设置是否首尾相连。
设计模式下QScrollBar的minimum和maximum属性分别用来设置最小和最大值,singleStep属性是按下←和→方向键后的增加或减少值,pageStep属性是按下↑或↓方向键后增加或减少的值,value和sliderPosition属性是当前值,tracking属性设置是否跟踪(就是在拖动滑块时,每移动一个刻度就会发射valueChanged()信号,如果不设置的话只有拖动滑块释放时才发射该信号),orientation属性设置部件是水平还是垂直方向,invertedAppearance属性用来设置滑块所在的位置,invertedControls属性用来设置反向控制。
设计模式下QSlider的tickPosition属性用来设置是否显示刻度及刻度位置,tickInterval属性用来设置刻度间隔。
我们在设计模式下加入一个Dial部件、一个Vertical Scroll Bar部件,一个Horizontal Slider部件。设置Dial的notchesVisible属性,使其显示刻度。然后进入编辑信号/槽模式,将Dial的sliderMoved(int)信号分别与其它两个部件的setValue(int)槽相关联, 然后运行程序可以看到当拖动Dial的滑块的时候,其它四个部件也随之滑动,如下图所示:
11、ProgressBar进度条
QProgressBar是进度条类,其成员函数setRange用来设置进度范围,setValue()用来设置当前进度,setFormat()用来设置进度条上文字,setOrientation()用来设置水平或垂直方向。
12、QMdiArea 部件提供一个可以显示MDI多文档界面的区域,用来有效的管理多个窗口。QMdiArea中的子窗口是QMdiSubWindow类型,它包含一个标题栏和中心区域,可以向它的中心区域添加部件。如下代码是在按钮点击事件方法中向一个QMdiArea添加子窗口,子窗口上是一个编辑器:
void MainWindow::on_pushButton_clicked() { QTextEdit* edit = new QTextEdit; QMdiSubWindow* child = ui->mdiArea->addSubWindow(edit); child->setWindowTitle("child window"); child->show(); }
13、QDockWidget 部件可以停靠在窗口中,也可以悬浮起来作为桌面顶级窗口,类似工具栏,它也包含一个标题栏和内容区域,float属性设置可以在窗口内悬浮,features属性设置是否可以关闭、移动、悬浮等,allowedArea属性设置可以停靠的区域。如下是一个包含QPushButton和QFontComboBox的Dock部件,它可以在窗口外悬浮或者在窗口内停靠: