vimer linux kernel 爱好者

Qt demo例子

2022-01-24
qt

Base Qt 5.9

新建控制台app

.pro文件内容

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp

main.cpp:

// Qt头文件没有.h, 头文件和类名相同
#include <QCoreApplication>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    return a.exec();
}

这个build下,就可以看见一个cmd窗口了。

新建Widget app

在构建的第三步时选择 Base class,选择QWidget class。

在选择窗口会有 .pro文件和Headers Sources Froms(ui文件)文件夹。

看下 .pro文件:

QT       += core gui
# 如果需要sql,则如下
#  QT += sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = test2
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

剩下的就是看如何操控控件了。我们先放一个 Label和 Push Button到窗体上。

  1. 打开UI文件, 在Display Widgets窗体中拖拽Label 图标放到窗体上,然后在属性编辑器上修改其属性,属性编辑器上面是对象(Object)窗体,可以看出来继承关系。

objectName表示组件的对象名称,界面上的每个组件都需要一个唯一的对象名称,以便引用。

Push Button的类名字QPushButton,objectName是btnClose.

在界面设计时,对程序需要访问的组件修改其objectName,对于其他的则可不必了。

  1. 添加信号槽 想要达到单击close按钮,窗口就退出的效果,就需要添加Signals和Slots了。

在信号与槽的窗体中(就是窗口下方,带加号、减号的那个窗体), 单击Add按钮,会出现 sender, Signal, Receiver, Slot一行输入栏。

单击Sender选择 btnClose,Signal 选择clicked(), Receiver选择窗体Widget, Slot选择close().

然后编译就可以出现app,点击close就可以关闭窗口了。

创建QDialog app

new -> project -> 第三步选择 base class QDialog,上面的类名为什么名字,就会生成什么名字的cpp,如QWDialog,则会生成qwdialog.cpp文件等(还有UI文件)。

这个demo的目的是创建一个可以修改字体的窗口。

  1. 首先在 input widgets中拖拽Plain Text Editor(类名<-QWDialog),对象名修改为txtEdit,编辑敲入文字: IT is my demo.

  2. 在Buttons窗口中取到Check Box, ObjectName为chkBoxUnder,类似拖拽三个check box。文字描述分别为 “Italic”和“BOLD”,同时修改objectName.

  3. 设置字体颜色: 在 Buttons窗口中取到 Radio Button,然后red black blue文字,并修改各自的objectName.

  4. 设置三个push button,确定 取消 退出。

objectName设置好了轻易不要改动。

  1. A 为了将这些组件排列美观,最好使用组件布局,也就是说需要使用一些容器。如 QGroupBox,使用其把上面的分成2组。这是层次关系。

  2. B 布局管理: 在UI设计中,组件面板有Layouts和Spacers两个组件面板。 比如,可以把三个PushButton的按钮放在Horizontal Layout下面,其会用红色框起来。这样 PushButton就可以完全以水平组合起来,放置在同一位置上。

C: 快速布局: 在2, 3步时使用 Group Box将三个按钮组合起来了,我们可以只点击Grouo Box,然后单击窗口上方的 水平 按钮,三个 组件 就会水平分布,并且改变外部的大小,也会改变组件的大小。

D: 然后选择最外层的窗体,单击 垂直 分布,就可以达到自动平铺的效果了。

伙伴关系和Tab顺序

伙伴关系设置快捷键的, Tab顺序控制tab的执行顺序。

信号与槽

信号 Signal就是在特定条件下被发射的事件。 如 PushButton最常见的信号就是鼠标单击发射的clicked()信号。 GUI编程的核心就是对界面上各组件的信号响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就行了。

Slot 槽就是对信号响应的函数。槽就是一个函数,和C++类似,可以定义在类的任何部分(public private protected等),可以具有任何参数,也可以被直接调用。唯一的区别就是: 槽函数可以与一个信号进行关联,当信号发射时,关联的槽函数被自动执行。

信号与槽关联使用 QObject::connect()函数进行关联的,其基本格式:

QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()))

connect()是QObject类的一个静态函数, 而QObject是所有的Qt类的基类,在实际调用时可以忽略前面的QObject限定。

sender是发射信号的对象名称, signal是信号名称, receiver是接受信号的对象名称,slot()是槽函数的名称。

目标:

过程:

单击chkBoxUnder, 右键 go to slot, 第一步是选择信号,在那个方框下,有对象chkBoxUnder的所有信号。我们选择 clicked(bool), 这样会传递一个参数, 在响应代码里是可以直接利用这个参数。也会在qwdialog.h中添加一个private slots的槽函数声明:

class QWDialog : public QDialog
{
    Q_OBJECT

public:
    explicit QWDialog(QWidget *parent = 0);
    ~QWDialog();
// 自动添加部分
private slots:
    void on_chkBoxUnder_clicked(bool checked);
    
private:
    Ui::QWDialog *ui;
};

这时,代码就会跳转到qwdialog.cpp:生成以下代码:

void QWDialog::on_chkBoxUnder_clicked(bool checked)
{
    
}

我们完善这个处理函数。

void QWDialog::on_chkBoxUnder_clicked(bool checked)
{
    QFont font = ui->txtEdit->font();
    font.setUnderline(checked);
    ui->txtEdit->setFont(font);  // 需要回置
}
  1. 同样的方式设置 Italic和Bold两个CheckBox两个方式。build后运行,发现我们可以设置字体的特性了, 说明信号与槽函数已经关联了。

这里我们自己的代码没有看到connect在哪里,是有问题吗? 不是的,可以查看编译生成的ui_qwdialog.h文件(在工程文件下,可以find usage去找一下,编辑器里是发现不了的)

setupUi里面,有一个函数是这样的:QMetaObject::connectSlotsByName(QWDialog);, 这条语句将搜索QWDialog界面上的所有组件,将信号与槽函数匹配起来,它假设的槽函数名称是:

void on_<objectName>_<signal name>(<signal parameters>)
  1. 字体颜色设计

将3个RadioButton的clicked()信号关联到一个槽函数, 在 QWDialog类的private slots部分增加一个槽函数:

void setTextFontColor();

然后在qwdialog.cpp中实现具体函数(方法是在.h的slot部分, 右击->refactor->add definition in xx.cpp)就可以了。

具体显示如下:

void QWDialog::setTextFontColor()
{
    QPalette plet = ui->txtEdit->palette(); // unknown usgae
    if (ui->rBtnBlue->isChecked())
        plet.setColor(QPalette::Text, Qt::blue);
    else if (ui->rBtnBlack->isChecked())
        plet.setColor(QPalette::Text, Qt::black);
    else if (ui->rBtnRed->isChecked())
        plet.setColor(QPalette::Text, Qt::red);
    else
        plet.setColor(QPalette::Text, Qt::black);

    ui->txtEdit->setPalette(plet);
}

由于是自定义的槽函数,并不会自动与RadioButton进行关联,需要在QWDialog的构造函数中进行手工关联,代码如下:

QWDialog::QWDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QWDialog)
{
    ui->setupUi(this);
    // 以下内容为删除部分 :
    connect(ui->rBtnBlack, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
    connect(ui->rBtnBlue, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
    connect(ui->rBtnRed, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
}

此时编译后就可以改变字体颜色了。

  1. 三个按钮的功能设计

还有 确定 取消 退出三个按钮。字如其意,最后的结果都是退出窗体。

过程: QWDialog是从QDialog继承过来的, QDialog提供了accept() reject() close()等槽函数来表示这三种状态,所以只需要将clicked()信号与相应的槽函数进行关联即可。

demo finish。


上一篇 Qt基本操作

Comments

Content