跳至正文
View Categories

2 min read

在桌面程序设计中,通常需要多个窗口进行切换,以及在切换过程中进行数据传递。比如我们在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);

效果演示。

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