赞
踩
使用实际编程的方法学习 Qt 控件,可以更好地理解和掌握按钮控件的特性和应用,同时还可以提高编程技能并增强对 Qt 框架的认识。
我们将通过几篇系列文章,介绍QT常用按钮编程。
本文介绍QT常用控件的第一个按钮,Push Button按钮编程。通过这个例子,初步了解QT的信号与槽、样式表等机制,此外,我们的调试环境配置了双架构Kits
,使得编译调试可以在当前的ubuntu中进行,也可以重新编译后下载到目标arm设备中运行。
我们的编程环境为:Ubuntu64位系统(22.04),目标架构:(1)qt5 x86_64
架构,(2)qt4 32位arm
架构。
在开发环境中,我们使用的是 x86_64 架构的 Ubuntu 22.04 虚拟机,而目标设备是使用 32 位 ARM 架构的系统。为了提高开发效率,我们在调试环境中同时配置了 x86 架构的 Qt 库。这样,在进行 Qt 界面开发和调试时,我们可以在 Ubuntu 上直接进行。在满意后,切换kit,重新编译后将应用程序下载到目标设备中进行测试和运行。由于减少了下载次数,大大提高了工作效率。
虽然在 Qt5 中添加了很多新的功能和模块,但是对于常用控件,它们与 Qt4 中的版本基本相同,可以使用相同的方法和属性进行操作。
我们在 Ubuntu 22.04 虚拟机直接安装QT5和qtcreator:
sudo apt-get install build-essential
sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
sudo apt-get install qtcreator
qtcreator所有的配置采用默认。
(1)安装 lib32stdc++6 软件包来解决。
sudo apt-get install lib32stdc++6
(2)安装依赖
sudo apt-get install build-essential libfontconfig1 mesa-common-dev libglu1-mesa-dev libpulse-dev libicu-dev libsqlite3-dev libssl-dev libxcb-xinerama0-dev libxkbcommon-dev libxkbcommon-x11-dev libasound2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev
(3)安装32位 cc1组件
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install zlib1g:i386
sudo tar -zxvf gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux.tar.gz
vim ~/.bashrc
export PATH=$PATH:/opt/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/bin
source ~/.bashrc
arm-linux-gnueabihf-gcc -v
成功:
。。。
gcc version 4.7.3 20130226 (prerelease) (crosstool-NG linaro-1.13.1-4.7-2013.03-20130313 - Linaro GCC 2013.03)
我们将按照《Ubuntu64位系统(v18.04)下arm32位版本(Qt4.8.6和tslib1.4)开发环境搭建》第5节的方法完成的QT4库qt4-arm文件夹
和第4节完成的tslib-arm文件夹
压缩。
tar -czvf qt4-arm.tar.gz qt4-arm
tar -czvf tslib-arm.tar.gz tslib-arm
得到两个压缩文件:qt4-arm.tar.gz
和 tslib-arm.tar.gz
。
拷贝qt4-arm.tar.gz
和 tslib-arm.tar.gz
到当前的ubuntu系统中,解压。
tar -zxvf qt4-arm.tar.gz
tar -zxvf tslib-arm.tar.gz
注意:需要将这两个文件放在与导出ubuntu系统相同的绝对路径下。
有关这部分的详细内容,请参考前面的两篇博文《Ubuntu64位系统(v18.04)下arm32位版本(Qt4.8.6和tslib1.4)开发环境搭建》和《Ubuntu64位系统(20.04、22.04)安装32位armQT4开发环境补充说明》。
这些都是 Qt 框架中常用的按钮控件,主要用于触发交互操作。
程序完成后的执行结果如下图:
按下黄色窗口按钮,窗口显示黄色,按下粉色按钮,窗口显示粉色。
新建一个项目名称为为_qpushbutton
选择Widget基类,去掉Generate Form勾选:
QT通常使用QMainWindow作为主窗口。
QMainWindow是一个窗口风格的控件,通常会有一个窗口标题栏,并支持窗口大小调整、最大化、最小化等标准窗口管理操作。在主窗口的最中间是是一个central widget,提供主窗口的主要内容或用户交互接口,比如文本编辑器或者OpenGL视图等。QWidget通常用作窗口中的子控件或对话框等非窗口风格的控件。
如果在Qt应用程序中只需要一个窗口且不需要标准的窗口管理功能,则QWidget可以被用作主窗口。
在嵌入式应用中,由于触摸屏通常用作显示或控制,不涉及太多编辑工作,使用QWidget作为主窗口会更为适用。
- 项目生成的最初代码
1 QT += core gui 2 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 5 CONFIG += c++11 6 7 # You can make your code fail to compile if it uses deprecated APIs. 8 # In order to do so, uncomment the following line. 9 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 10 11 SOURCES += \ 12 main.cpp \ 13 widget.cpp 14 15 HEADERS += \ 16 widget.h 17 18 # Default rules for deployment. 19 qnx: target.path = /tmp/$${TARGET}/bin 20 else: unix:!android: target.path = /opt/$${TARGET}/bin 21 !isEmpty(target.path): INSTALLS += target 22 23 24 # 根据使用的 Qt 版本设置编译条件 25 greaterThan(QT_MAJOR_VERSION, 4) { 26 # 如果使用的是 Qt 5 或者更新版本 27 message("使用的是 Qt 5版本") 28 29 } else { 30 # 如果使用的是 Qt 4 或者更早的版本 31 message("使用的是 Qt 4版本") 32 DEFINES += QT_ARM_PLATFORM 33 QMAKE_CXXFLAGS += -std=c++11 34 QMAKE_CXXFLAGS += -Wno-psabi -Wno-deprecated-declarations 35 36 LIBS += -lts 37 38 }
我们在系统生成的项目文件中使用条件编译增加目标为qt4-arm时的代码:
QMAKE_CXXFLAGS += -std=c++11
就能修正这一错误。QMAKE_CXXFLAGS += -Wno-psabi -Wno-deprecated-declarations
可以帮助我们忽略掉我们不关心的警告。main.cpp
1 #include "widget.h" 2 3 #include <QApplication> 4 5 #ifdef QT_ARM_PLATFORM 6 #include <QTextCodec> 7 #endif 8 9 int main(int argc, char *argv[]) 10 { 11 QApplication a(argc, argv); 12 13 #ifdef QT_ARM_PLATFORM 14 //解决中文乱码 15 QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK")); 16 QTextCodec::setCodecForTr(QTextCodec::codecForName("system")); //若英文系统,则用GBK 17 QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); 18 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); 19 #endif 20 Widget w; 21 w.show(); 22 return a.exec(); 23 }
QTextCodec是Qt中一个用于字符编解码的类,用于将文本字符串转换为不同字符集或编码方式的二进制数据,或将二进制数据解码为文本字符串。
为了解决当程序运行在arm架构系统时,中文显示文乱码问题,根据从.pro获得的宏QT_ARM_PLATFORM判断如果系统运行在arm架构,则执行:
widget.h
1 #ifndef WIDGET_H 2 #define WIDGET_H 3 4 #include <QWidget> 5 /* 引入 QPushButton 类 */ 6 #include <QPushButton> 7 class Widget : public QWidget 8 { 9 Q_OBJECT 10 public: 11 Widget(QWidget *parent = nullptr); 12 ~Widget(); 13 private: 14 /* 声明一个 QPushButton 对象 pushButton1 */ 15 QPushButton *pushButton1; 16 /* 声明一个 QPushButton 对象 pushButton2 */ 17 QPushButton *pushButton2; 18 private slots: 19 /* 声明对象 pushButton1 的槽函数 */ 20 void pushButton1_Clicked(); 21 /* 声明对象 pushButton2 的槽函数 */ 22 void pushButton2_Clicked(); 23 }; 24 #endif // WIDGET_H
第 6 行,引入 QPushButton 类。
第 15 行和 第17 行,声明两个 QPushButton 的对象。
第 20行和 第 22 行,声明两个 QPushButton 对象的槽函数。
widget.cpp
1 #include "widget.h" 2 3 Widget::Widget(QWidget *parent) 4 : QWidget(parent) 5 { 6 /* 设置宽高为 800×480,位置在 0, 0。(0, 0)代表原点,Qt 默认最左上角的点为原点 */ 7 this->setGeometry(0, 0, 800, 480); 8 9 /* 实例化两个按钮对象,并设置其显示文本为"黄色窗口"和"粉色窗口" */ 10 pushButton1 = new QPushButton("黄色窗口", this); 11 pushButton2 = new QPushButton("粉色窗口", this); 12 13 /* 设定两个 QPushButton 对象的位置 */ 14 pushButton1->setGeometry(300,200,80,40); 15 pushButton2->setGeometry(400,200,80,40); 16 17 /* 信号槽连接 */ 18 connect(pushButton1, SIGNAL(clicked()), this, SLOT(pushButton1_Clicked())); 19 connect(pushButton2, SIGNAL(clicked()), this, SLOT(pushButton2_Clicked())); 20 } 21 22 Widget::~Widget() 23 { 24 } 25 26 /* 槽函数的实现 */ 27 void Widget::pushButton1_Clicked() 28 { 29 /* 设置主窗口的样式 1 */ 30 this->setStyleSheet("Widget { background-color: rgba(255, 255, 0, 100%); }"); 31 } 32 33 /* 槽函数的实现 */ 34 void Widget::pushButton2_Clicked() 35 { 36 /* 设置主窗口的样式 2 */ 37 this->setStyleSheet("Widget { background-color: rgba(255, 192, 203, 100%); }"); 38 }
第 7 行,设置程序窗口的显示位置和显示大小,在我们使用的硬件里,窗口占满整个屏幕。
第10行 和 第11行,实际化 QPushButton 对象。在初始化的时候可以传入 QString 类型串,作为
按钮的显示文本。
第 14 行和第15行,设置按钮的大小和位置。
第 18 行和 19 行,连接两个 QPushButton 对象的信号与槽。
第27~31行,定义第一个槽函数pushButton1_Clicked()。
第34~38行,定义第二个槽函数pushButton2_Clicked()。
pushButton1_Clicked()pushButton2_Clicked()两个函数的功能是,当点击按钮时,窗口的背景颜色按照background-color 的 rgba 设置值, 发生相应的变化。
点击窗口左边的Debug,可以选择编译运行在不同平台上的可执行文件,arm-v7为arm架构的设备,桌面则是当前ubuntu系统。
信号(Signal)和槽(Slot)是Qt中重要的一种机制。它们的作用是在对象之间进行通信和交互,使得应用程序能够响应事件并实现特定的功能。Qt的信号和槽机制是一种基于事件的编程模型,可以实现对象之间的松耦合,使得事件的处理更为简单和灵活。
简单来说,信号是对象发出的一个通知或事件,而槽则是对象接收并响应这个通知或事件的函数。一个对象可以有多个信号和槽,而且它们之间可以相互连接,使得一个对象的信号能够触发另一个对象的槽,从而实现复杂的交互功能。
Qt中的信号和槽使用connect()函数进行连接。当某个对象的信号被触发时,与之相连的槽函数会被自动调用,从而实现事件的处理,我们上面的程序中,以pushButton1为例,实现代码如下:
connect(pushButton1, SIGNAL(clicked()), this, SLOT(pushButton1_Clicked()));
pushButton1是一个QPushButton对象,点击它,会发出一个clicked()信号;
this是当前窗口对象,它定义了pushButton1_Clicked()的槽函数,用于响应clicked()信号;
connect函数将pushButton1的clicked()信号与窗口对象的pushButton1_Clicked()槽函数连接起来。
当用户点击pushButton1按钮,pushButton1_Clicked()槽函数就会被自动调用。
Qt提供了样式表(Style Sheet)机制,可以用于设置应用程序中控件的外观和布局。样式表是一种基于CSS语法的文本文件,通过设置不同的属性和值来改变控件的外观和行为。
下面一个是使用样式表来设置控件风格的例子:
QWidget{
background-color: white;
}
设置QWidget背景色为白色。
在我们的中,使用setStyleSheet()函数来将样式表应用到控件上。
this->setStyleSheet("Widget { background-color: rgba(255, 255, 0, 100%); }");
或是可以这样写:
this->setStyleSheet("background-color: yellow;");
本例程为Push Button按钮编程。通过这个例子,初步了解QT的信号与槽、样式表等机制,此外,我们的调试环境配置了双架构Kits
,使得编译调试可以在当前的ubuntu中进行,也可以重新编译后下载到目标arm设备中运行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。