在桌面程序设计中,通常需要多个窗口进行切换,以及在切换过程中进行数据传递。比如我们在PC登陆微信的时候,扫描二维码是一个登陆窗口,手机上确认登陆后会跳转到另一个聊天的窗口,这个主窗口显示着我们登陆的那个账号的个人信息,这就是常见的一种窗口切换。
显示隐藏 #
我们现在设计一个有两个窗口的的程序,当程序启动后显示windows1窗口,点击button1后显示windows窗口2,并隐藏Windows1,当点击button2后显示windows1窗口,并隐藏windows2窗口。
其中,按钮button1是windows1窗口的组件,按钮button2是windows2窗口的组件。
新建Qt项目,类名定以为MyWindows,完成后如下。


因为windows1和windows2窗口界面布局和功能一致,所以将它们抽象为一个MyWindows类,也就是说windows1和windows2窗口是MyWindows类的两个实例化对象。
我们在MyWindows类中定义一个按钮,并且设置为中心组件,这个Mainwindow窗口只有一个按钮,为了演示方便,我们将按钮设置为public。
show()函数可以显示窗口。
hide()函数可以隐藏窗口。
close()函数可以销毁窗口。
hide()函数相当于setVisible(false)。
mywindows.h
#ifndef MYWINDOWS_H #define MYWINDOWS_H #include <QMainWindow> #include <QPushButton> class MyWindows : public QMainWindow { Q_OBJECT public: explicit MyWindows(QWidget *parent = nullptr); QPushButton button; signals: }; #endif // MYWINDOWS_H
mywindows.cpp
#include "mywindows.h" MyWindows::MyWindows(QWidget *parent) : QMainWindow(parent){ this->setCentralWidget(&button);}
我们需要在main.cpp的主函数中,实例化两个对象,分别设置窗口和按钮的标题,以方便区分。
当第一个窗口按钮点击时,需要隐藏当前窗口,并且显示第二个窗口。
当第二个窗口按钮点击时,需要隐藏当前窗口,并且显示第一个窗口。
我们将对应的信号和槽函数绑定后,就可以实现窗口的切换。
main.cpp
#include <QApplication> #include<QObject> int main(int argc, char *argv[]) { QApplication a(argc, argv); MyWindows *win1 = new MyWindows(); MyWindows *win2 = new MyWindows(); win1->setWindowTitle("windows1"); win2->setWindowTitle("windows2"); win1->button.setText("button1"); win2->button.setText("button2"); QObject::connect(&win1->button, &QPushButton::clicked, win2, &MyWindows::show); QObject::connect(&win1->button, &QPushButton::clicked, win1, &MyWindows::hide); QObject::connect(&win2->button, &QPushButton::clicked, win1, &MyWindows::show); QObject::connect(&win2->button, &QPushButton::clicked, win2, &MyWindows::hide); win1->show(); return a.exec(); }
结果演示。


堆栈窗口 #
QStackedWidget类提供了一个窗口的容器,但当前只能显示一个窗口。
我们新建项目时候,基类选择QWidget,且不生成ui文件。

在Widget类中添加一个QListWidget和QStackWidget类的对象为成员,实现点击list来切换显示stack中不同的widget。
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QListWidget> #include <QStackedWidget> #include <QLabel> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private: QListWidget *m_lw = nullptr; QStackedWidget *m_sw = nullptr; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include <QHBoxLayout> Widget::Widget(QWidget *parent) : QWidget(parent) { m_lw = new QListWidget(); m_lw->setMaximumWidth(60); m_lw->addItem("label 1"); m_lw->addItem("label 2"); m_lw->addItem("label 3"); m_sw = new QStackedWidget(); m_sw->addWidget(new QLabel("windows 1")); m_sw->addWidget(new QLabel("windows 2")); m_sw->addWidget(new QLabel("windows 3")); connect(m_lw, &QListWidget::currentRowChanged, m_sw, &QStackedWidget::setCurrentIndex); QHBoxLayout *layout = new QHBoxLayout(); layout->addWidget(m_lw); layout->addWidget(m_sw); this->setLayout(layout); } Widget::~Widget() { }
结果演示。


对话框 #
对话框是用来和主窗口交互的窗口,可以接受返回值。Qt自带对话框类有:QColorDialog, QErrorMessage, QFileDialog, QFontDialog, QInputDialog, QMessageBox, QProgressDialog, 和QWizard 。
文件对话框 #
QFileDialog 类提供了一个对话框可以使用户从本地目录选取文件。常用于打开,保存文件是选择本地文件。
代码示例。
fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)")); // "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
颜色对框框 #
QColorDialog 类提供一个可供用户选择颜色的对框框。
接下来写个程序验证,在UI上布局一个Label和PushButton,当用户点击按钮时弹出颜色选择对话框,完成后将选择的颜色设置为Label和PushButton的文字颜色。
代码示例。
#include "widget.h" #include <QVBoxLayout> #include <QLabel> #include <QColorDialog> #include <QPushButton> #include <QDebug> widget::widget(QWidget *parent) : QWidget(parent) { QLabel *label = new QLabel("hello"); QPushButton *button = new QPushButton("get color"); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(label); layout->addWidget(button); this->setLayout(layout); QColorDialog *dialog = new QColorDialog(); connect(button, &QPushButton::clicked, [=](){ QColor color = dialog->getColor(); qDebug()<<color; QPalette ple; ple.setColor(QPalette::WindowText, color); label->setPalette(ple); ple.setColor(QPalette::ButtonText, color); button->setPalette(ple); }); }
运行结果。



输入对框框 #
QInputDialog 类可以弹出对话框获取用户输出的单个值。
获取单个值类型可以为double,int,string。
核心代码。
bool ok; QString text = QInputDialog::getText(this, tr("QInputDialog::getText()"), tr("User name:"), QLineEdit::Normal, QDir::home().dirName(), &ok); if (ok && !text.isEmpty()) textLabel->setText(text);
bool ok; double d = QInputDialog::getDouble(this, tr("QInputDialog::getDouble()"), tr("Amount:"), 37.56, -10000, 10000, 2, &ok); if (ok) doubleLabel->setText(QString("$%1").arg(d));
bool ok; int i = QInputDialog::getInt(this, tr("QInputDialog::getInteger()"), tr("Percentage:"), 25, 0, 100, 1, &ok); if (ok) integerLabel->setText(tr("%1%").arg(i));
QStringList items; items << tr("Spring") << tr("Summer") << tr("Fall") << tr("Winter"); bool ok; QString item = QInputDialog::getItem(this, tr("QInputDialog::getItem()"), tr("Season:"), items, 0, false, &ok); if (ok && !item.isEmpty()) itemLabel->setText(item);
效果演示。

消息对话框 #
QMessageBox 类可以向用户发送提示信息,或者进行确认用户的操作。
通常使用该类的静态方法进行显示对话。
int ret = QMessageBox::warning(this, tr("My Application"), tr("The document has been modified.\n" "Do you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save);
效果演示。

其他常用图标如下,更多信息查看官方帮助文档。
