QMainWindow
QMainWindow
是 Qt 框架带来的一个预定义好的主窗口类。
主窗口,就是一个普通意义上的应用程序(不是指游戏之类的那种)最顶层的窗口。通常是由一个标题栏,一个菜单栏,若干工具栏和一个任务栏。在这些子组件之间则是我们的工作区。
通过添加动作来添加菜单和工具栏等,比如添加一个打开菜单和工具
1 QAction *openaction; 2 openaction = new QAction(QIcon(":/img/open"),tr("&Open"),this); 3 openaction->setShortcut(QKeySequence::Open); //给菜单指定快捷键 4 openaction->setStatusTip(tr("open an existing file")); //提示 5 6 //加入菜单栏的File中 7 QMenu *file = menuBar()->addMenu(tr("&File")); 8 file->addAction(openaction); 9 10 //加入工具栏 11 QToolBar *toolBar = addToolBar(tr("&File")); 12 toolBar->addAction(openaction);
QDialog
Qt 中使用QDialog
类实现对话框
QDialog
(及其子类,以及所有Qt::Dialog
类型的类)的对于其 parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent 的中心)。顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置。
1 QDialog dialog; //顶层,在任务栏显示 2 QDialog dialog(this) //子窗口,在任务栏不显示
模态和非模态
对话框分为模态对话框和非模态对话框。所谓模态对话框,就是会阻塞同一应用程序中其它窗口的输入。模态对话框很常见,比如“打开文件”功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。与此相反的是非模态对话框,例如查找对话框,我们可以在显示着查找对话框的同时,继续对记事本的内容进行编辑。
Qt 支持模态对话框和非模态对话框。其中,Qt 有两种级别的模态对话框:应用程序级别的模态和窗口级别的模态,默认是应用程序级别的模态。应用程序级别的模态是指,当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。窗口级别的模态是指,该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。
Qt 使用QDialog::exec()
实现应用程序级别的模态对话框,使用QDialog::open()
实现窗口级别的模态对话框,使用QDialog::show()
实现非模态对话框。
模态:
1 void MainWindow::open() 2 { 3 QDialog dialog; 4 dialog.setWindowTitle(tr("Hello")); 5 dialog.exec(); 6 }
非模态:注意必须用new创建否则一闪而过,这是因为,show()
函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。而用new是建立在堆上,执行完后不会消失。
不过,这样做有一个问题:如果我们的对话框不是在一个界面类中出现呢?由于QWidget
的 parent 必须是QWidget
指针,那就限制了我们不能将一个普通的 C++ 类指针传给 Qt 对话框。另外,如果对内存占用有严格限制的话,当我们将主窗口作为 parent 时,主窗口不关闭,对话框就不会被销毁,所以会一直占用内存。在这种情景下,我们可以设置 dialog 的WindowAttribute
:
1 void MainWindow::open() 2 { 3 QDialog *dialog = new QDialog; 4 dialog->setAttribute(Qt::WA_DeleteOnClose); 5 dialog->setWindowTitle(tr("Hello, dialog!")); 6 dialog->show(); 7 }
内置对话框
QColorDialog
:选择颜色;QFileDialog
:选择文件或者目录;QFontDialog
:选择字体;QInputDialog
:允许用户输入一个值,并将其值返回;QMessageBox
:模态对话框,用于显示信息、询问问题等;QPageSetupDialog
:为打印机提供纸张相关的选项;QPrintDialog
:打印机配置;QPrintPreviewDialog
:打印预览;QProgressDialog
:显示操作过程。
QMessageBox
QMessageBox
用于显示消息提示。我们一般会使用其提供的几个 static 函数:
显示关于对话框。这是一个最简单的对话框,其标题是 title,内容是 text,父窗口是 parent。对话框只有一个 OK 按钮
1 void about(QWidget * parent, const QString & title, const QString & text)
显示关于 Qt 对话框。该对话框用于显示有关 Qt 的信息
1 void aboutQt(QWidget * parent, const QString & title = QString())
显示严重错误对话框。这个对话框将显示一个红色的错误符号。我们可以通过 buttons 参数指明其显示的按钮。默认情况下只有一个 Ok 按钮,我们可以使用StandardButtons
类型指定多种按钮
1 StandardButton critical(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)
QMessageBox::information()
函数与QMessageBox::critical()
类似,不同之处在于这个对话框提供一个普通信息图标
1 StandardButton information(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)
QMessageBox::question()
函数与QMessageBox::critical()
类似,不同之处在于这个对话框提供一个问号图标,并且其显示的按钮是“是”和“否”两个
1 StandardButton question(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = StandardButtons( Yes | No ), StandardButton defaultButton = NoButton)
QMessageBox::warning()
函数与QMessageBox::critical()
类似,不同之处在于这个对话框提供一个黄色叹号图标
StandardButton warning(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)
QFileDialog文件对话框
一个txt编辑保存的实例
主窗口继承mainwindow,#include <QtWidgets> 包含了QT的常用控件(比如QTextEdit,QAction)
mainwindow.h
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 6 class QTextEdit; 7 8 class MainWindow : public QMainWindow 9 { 10 Q_OBJECT 11 12 public: 13 explicit MainWindow(QWidget *parent = 0); 14 ~MainWindow(); 15 16 private slots: 17 void openFile(); 18 void saveFile(); 19 20 private: 21 QAction *openAction; 22 QAction *saveAction; 23 24 QTextEdit *textEdit; 25 }; 26 27 #endif // MAINWINDOW_H
main.cpp
1 #include <QApplication> 2 #include "mainwindow.h" 3 4 int main(int argc, char *argv[]) 5 { 6 QApplication a(argc, argv); 7 8 MainWindow w; 9 w.show(); 10 11 return a.exec(); 12 }
mainwindow.cpp
1 #include <QtGui> 2 #include <QtWidgets> 3 #include "mainwindow.h" 4 5 MainWindow::MainWindow(QWidget *parent) : 6 QMainWindow(parent) 7 { 8 openAction = new QAction(QIcon(":/images/file-open"), tr("&Open..."), this); 9 openAction->setShortcuts(QKeySequence::Open); 10 openAction->setStatusTip(tr("Open an existing file")); 11 connect(openAction, &QAction::triggered, this, &MainWindow::openFile); 12 13 saveAction = new QAction(QIcon(":/images/file-save"), tr("&Save..."), this); 14 saveAction->setShortcuts(QKeySequence::Save); 15 saveAction->setStatusTip(tr("Save a new file")); 16 connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); 17 18 QMenu *file = menuBar()->addMenu(tr("&File")); 19 file->addAction(openAction); 20 file->addAction(saveAction); 21 22 QToolBar *toolBar = addToolBar(tr("&File")); 23 toolBar->addAction(openAction); 24 toolBar->addAction(saveAction); 25 26 textEdit = new QTextEdit(this); 27 setCentralWidget(textEdit); 28 } 29 30 MainWindow::~MainWindow() 31 { 32 } 33 34 void MainWindow::openFile() 35 { 36 QString path = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("Text Files(*.txt)")); 37 if(!path.isEmpty()) { 38 QFile file(path); 39 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { 40 QMessageBox::warning(this, tr("Read File"), tr("Cannot open file: %1").arg(path)); 41 return; 42 } 43 QTextStream in(&file); 44 textEdit->setText(in.readAll()); 45 file.close(); 46 } else { 47 QMessageBox::warning(this, tr("Path"), tr("You did not select any file.")); 48 } 49 } 50 51 void MainWindow::saveFile() 52 { 53 QString path = QFileDialog::getSaveFileName(this, tr("Save File"), ".", tr("Text Files(*.txt)")); 54 if(!path.isEmpty()) { 55 QFile file(path); 56 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { 57 QMessageBox::warning(this, tr("Write File"), tr("Cannot open file: %1").arg(path)); 58 return; 59 } 60 QTextStream out(&file); 61 out << textEdit->toPlainText(); 62 file.close(); 63 } else { 64 QMessageBox::warning(this, tr("Path"), tr("You did not select any file.")); 65 } 66 }