文章目录
- 前言
- 1、 Qt常用的输入窗口控件
- 2、QFontComboBox 和 QComboBox控件编程
- 2.1 控件简介
- 2.1.1 QComboBox组合框
- 2.1.2 QFontComboBox字体组合框
- 2.2 例程功能设计
- 2.3 例程执行效果
- 2.4 生成项目
- 2.5 代码编辑
- 2.5.1 修改项目文件_qcombobox.pro
- 2.5.2 修改 `main.cpp`
- 2.5.3 修改 `widget.h`
- 2.5.4 修改 `widget.cpp`
- 2.6 切换Kit,获得运行在不同系统中的运行的执行文件
- 2.7 程序中的qt机制分析
- 2.7.1 qt4与qt5信号与槽函数的连接方式比较
- 总结
前言
从本文开始,我们系列文章开始介绍Qt输入窗口部件编程。本文介绍QComboBox组合框和 QFontComboBox字体组合框编程。通过这个例子,继续巩固QT的信号与槽知识,了解qt4与qt5信号与槽函数的连接方式的不同。
本例程设计是在chatgpt的帮助下完成的,编译代码经过测试通过。
感谢朋友提供的chatgpt软件,特别是其中的gpt-box桌面工具,更是我离不开的工具。感兴趣的同仁可前往一观( www.apsuai.com)。
我们的调试环境仍然是双架构Kits
,编译调试在当前的ubuntu(qt5)中进行,重新编译后下载到目标arm设备(qt4)中运行。
我们的编程环境为:Ubuntu64位系统(22.04),目标架构:
(1) qt5 x86_64
架构;
(2)qt4 32位arm
架构。
环境配置请参见《Qt常用的按钮控件编程(一)》第1节。
1、 Qt常用的输入窗口控件
- Comb Box:组合框
- Font Comb Box:字体组合框
- Line Edit:单行编辑框
- Text Edit:文本编辑框
- Plain Text Edit:纯文本编辑框
- Spin Box:数字旋转框
- Double Spin Box:双精度数字旋转框
- Time Edit:时间编辑框
- Date Edit:日期编辑框
- Date/Time Edit:日期时间编辑框
- Dial:数字拨盘框
- Horizontal Scroll Bar:水平滚动条
- Vertical Scroll Bar:垂直滚动条
- Horizontal Slider:水平滑动条
- Vertical Slider:垂直滑动条
- Key sequence Edit:按键序列编辑框
在以后编程示例中我们会详细介绍这些控件。
2、QFontComboBox 和 QComboBox控件编程
2.1 控件简介
2.1.1 QComboBox组合框
QComboBox是Qt中的一个控件类,用户可以从下拉列表中选择一个值。当用户点击下拉箭头,一个列表就会展开,以显示可用选项。用户可以从列表中选择一个选项,所选选项将作为组合框的当前值。
QComboBox是一个强大的组合框控件,可以用于在GUI中选择从一组值中选择的值。例如,在绘图应用中,可以使用QComboBox来选择画笔颜色、字体、线型等。QComboBox也可以用于选择文件格式、数据源等。
以下是QComboBox的一些常用函数和信号:
- addItem(text: str, userData: Any = None): 向下拉列表框中添加一个选项。
- removeItem(index: int): 从下拉列表框中移除指定的选项。
- clear(): 清除下拉列表框中的所有选项。
- currentTextChanged(text: str): 当用户选择新选项时,发出此信号。
2.1.2 QFontComboBox字体组合框
QFontComboBox是QComboBox类的一个子类,继承了QComboBox的所有功能。QFontComboBox是Qt为了方便开发者使用而提供的一个特殊控件,可以将其视为Qt的语法糖
。它大大简化开发过程,并使代码更易于理解和维护,但其实它内部实现并不简单,需要扫描操作系统中所有已安装的字体,并格式化这些字体进行显示,同时提供信号来捕获所选字体的更改。
2.2 例程功能设计
向chatgpt提出的要求如下:
“使用Qt Creator 创建一个c++例程,项目名称"_qcombobox" ,基类不选默认MainWindow类,而选择Widget作为基类,不要勾选“Generate form”,不使用拖取控件,控件全部采用编程。主窗口大小800*480。在主窗口上,放置一个 QComboBox控件控件用来选择颜色,放置一个 QFontComboBox 控件用来选择字体,选择后,用槽函数将综合选择的结果体现在一个QTextEdit控件中。“
chatgpt根据要求给出了完整的例程,经过少量调整就能满足我们的需求。
2.3 例程执行效果
在主窗口上,左上放置一个 QComboBox控件,点击后显示的下拉框可以改变下部文本框(QTextEdit控件)选中
文本的颜色,右上放置一个QFontComboBox控件,点击后出现许多中文字体可供选择,选中其中之一,文本框中的全部内容会按照选择的字体发生改变,如下图:
2.4 生成项目
使用Qt Creator 创建一个c++例程,项目名称"_qcombobox" ,不选默认MainWindow类,选择Widget作为基类,不要勾选“Generate form”,不使用拖取控件,控件全部采用编程。将两个配置好的Kits同时选上,项目新建完成如下图。(详细的项目新建过程参见:《Qt常用的按钮控件编程(一)》)。
点击左侧的Debug选项,可以看到两个编译套件Kit,可以选择编译运行在不同平台上的可执行文件,arm-v7为arm架构的设备,使用Qt4库,而桌面则是当前ubuntu系统,使用Qt5。
2.5 代码编辑
2.5.1 修改项目文件_qcombobox.pro
QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \widget.cppHEADERS += \widget.h# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target# 根据使用的 Qt 版本设置编译条件
greaterThan(QT_MAJOR_VERSION, 4) {# 如果使用的是 Qt 5 或者更新版本message("使用的是 Qt 5版本")} else {# 如果使用的是 Qt 4 或者更早的版本message("使用的是 Qt 4版本")DEFINES += QT_ARM_PLATFORMQMAKE_CXXFLAGS += -std=c++11QMAKE_CXXFLAGS += -Wno-psabi -Wno-deprecated-declarationsLIBS += -lts}
2.5.2 修改 main.cpp
#include "widget.h"#include <QApplication>
#ifdef QT_ARM_PLATFORM
#include <QTextCodec>
#endif
int main(int argc, char *argv[])
{QApplication a(argc, argv);#ifdef QT_ARM_PLATFORM//解决Qt4中文乱码QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));QTextCodec::setCodecForTr(QTextCodec::codecForName("system")); //若英文系统,则用GBKQTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
#endifWidget w;w.show();return a.exec();
}
2.5.3 修改 widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QFontComboBox>
#include <QTextEdit>class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void setColor(int index);void setFont(const QFont &font);private:QComboBox *colorComboBox;QFontComboBox *fontComboBox;QTextEdit *textEdit;QHBoxLayout *comboLayout;QVBoxLayout *layout;};
#endif // WIDGET_H
2.5.4 修改 widget.cpp
#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent)
{setWindowTitle("ComboBox Example");resize(800, 480);colorComboBox = new QComboBox;
#ifdef QT_ARM_PLATFORM
/*对于 Qt4,其中的 C++11 功能实现是不完整的,因此很多 C++11 的新特性是无法使用的,比如必须使用分离引用声明方式初始化 QString 对象 QStringList。*/QStringList colors;colors << "Red" << "Green" << "Blue";
#else
/*在 Qt5 的连接语法中,我们可以使用分离引用声明方式({}语法)来初始化 QObject 的对象或其子类。*/QStringList colors = {"Red", "Green", "Blue"};
#endifcolorComboBox->addItems(colors);fontComboBox = new QFontComboBox;fontComboBox->setWritingSystem(QFontDatabase::SimplifiedChinese);textEdit = new QTextEdit("你好 Qt 例程!!!!");textEdit->setFont(QFont("宋体", 28));comboLayout = new QHBoxLayout();comboLayout->addWidget(colorComboBox);comboLayout->addWidget(fontComboBox);layout = new QVBoxLayout();layout->addLayout(comboLayout);layout->addWidget(textEdit);this->setLayout(layout);#ifdef QT_ARM_PLATFORMconnect(colorComboBox, SIGNAL(activated(int)), this, SLOT(setColor(int)));connect(fontComboBox, SIGNAL(currentFontChanged(QFont)), this, SLOT(setFont(QFont)));
#elseconnect(colorComboBox, QOverload<int>::of(&QComboBox::activated), this, &Widget::setColor);connect(fontComboBox, &QFontComboBox::currentFontChanged, this, &Widget::setFont);#endif}Widget::~Widget()
{
}void Widget::setColor(int index)
{switch (index) {case 0:textEdit->setTextColor(Qt::red);break;case 1:textEdit->setTextColor(Qt::green);break;case 2:textEdit->setTextColor(Qt::blue);break;}
}void Widget::setFont(const QFont &font)
{QFont font1=font;font1.setPointSize(28);textEdit->setFont(font1);
}
2.6 切换Kit,获得运行在不同系统中的运行的执行文件
点击窗口左边的Debug,可以选择编译运行在不同平台上的可执行文件,arm-v7为arm架构的设备,使用Qt4库,而桌面则是当前ubuntu系统,使用Qt5。(参见2.4节)
Qt5编译完成的可执行程序_qcombobox
,存放在项目目录的build-_qcombobox-unknown-Debug/
文件夹下,Qt4编译完成的同名可执行程序_qcombobox
,存放在项目目录的build-_qcombobox-arm_v7-Debug/
文件夹下。
将程序下载到多台设备arm设备上测试,大多数设备上Font Comb Box能够正常工作,而某些设备则出现触摸完全无效的情况,这是由于很多输入窗口控件在Qt4、tslib环境下工作不正常所致,如果希望彻底解决问题,最好将系统升级到Qt5。
2.7 程序中的qt机制分析
2.7.1 qt4与qt5信号与槽函数的连接方式比较
在前面的代码中,qt4的连接方式:
connect(colorComboBox, SIGNAL(activated(int)), this, SLOT(setColor(int)));connect(fontComboBox, SIGNAL(currentFontChanged(QFont)), this, SLOT(setFont(QFont)));
而在qt5中,代码如下:
connect(colorComboBox, QOverload<int>::of(&QComboBox::activated), this, &Widget::setColor);
connect(fontComboBox, &QFontComboBox::currentFontChanged, this, &Widget::setFont);
在 Qt4 中,我们使用 SIGNAL 和 SLOT 宏来连接信号和槽函数,需要在编译时进行字符串匹配,这种方式存在以下几个限制:
- 一些字符串的名字不容易重构或改写,对翻译的支持也不够良好;
- 对于多重重载函数,必须手动将参数写成字符串,并且和函数实际的参数类型及个数完全匹配;
- 必须写出 Qt 提供的信号和槽函数的名称,反射机制不够灵活。
而在 Qt5 中,我们可以使用更安全、类型安全的函数指针连接两个对象的信号和槽函数,避免了字符串相关的限制和风险,提供了更加完善和方便的信号槽组合。使用 QOverload 来连接重载的信号和槽函数,它具有以下优势:
- 可以在 compile time(编译时间) 保证参数类型和数目正确,避免了类型安全问题;
- 可以通过函数指针灵活地选择任何重载,不必指定参数类型字符串;
- 更稳健、更高效、更具有可读性。
“compile time”(编译时间),是指程序的编译期间,也就是源代码被编译器编译成可执行文件之前的时间段。这个阶段的操作包括词法分析、语法分析、语义分析、代码生成、优化等,可以将源代码转换为机器代码或字节码等。
“runtime”(运行时)是指程序的执行期间,也就是可执行文件开始执行到结束的时间段。这个时间段的操作包括栈和堆的分配、变量赋值、函数调用、I/O 操作等与计算机硬件和操作系统相关的的操作。
总结
本文介绍QComboBox组合框和 QFontComboBox字体组合框编程。例程的设计是在chatgpt的帮助下完成的。
AI 技术的快速发展将深刻地改变我们生活的各个方面。chatgpt 的自动代码生成功能给予了程序员一个全新的编程体验,只需要清晰地描述需求,chatgpt 就可以为我们提供相应的代码建议,极大地提高了开发效率和准确性。只需要少量的修改和调整,便可以轻松地将它们应用于实际项目中。
当前的chatgpt由于对篇幅的限制,目前还不能做比较大的项目,但已经能够为我们提供很多的代码模块,大大减轻了开发强度和难度。