Qt常用的按钮控件编程(二)-- Tool Button按钮


前言

本文介绍QT常用控件的第二个按钮,Tool Button按钮编程。通过这个例子,初步了解QToolBar容器控件,项目演示了如何将Tool Button按钮放置到QToolBar容器控件中。此外通过这个项目能够进一步熟悉QT的信号与槽机制,特别是连接函数connect()函数在Qt4和Qt5中的使用。
我们的调试环境仍然是双架构Kits,编译调试在当前的ubuntu(qt5)中进行,重新编译后下载到目标arm设备(qt4)中运行。
我们的编程环境为:Ubuntu64位系统(22.04),目标架构:(1)qt5 x86_64 架构,(2)qt4 32位arm架构。
环境配置请参见《Qt常用的按钮控件编程(一)》第1节。


4、Tool Button 按钮编程

Tool Button 是 Qt 框架中常用的一个按钮控件,可以显示图标和文本标签。
ToolButton通常是作为动作控件使用的,可以与其他容器控件配合使用,例如QToolBar或QWidget等,以完成应用程序的布局和UI设计。ToolButton可以提供快捷方式和操作接口,可以方便用户快速访问和使用程序的功能,提高用户体验和操作的便捷性。
QToolBar是一个预定义的容器控件,常用来放置常用的或特定功能的ToolButton按钮。它通常位于主窗口MainWindow的顶部或底部,与主窗口相互协调,可以提供用户更好的操作体验。

4.1 程序完成后的执行结果

  • 最终程序实现的效果如下。将自定义的设置工具按钮嵌入工具栏中。
    图1
  • 按下按钮,跳出警告消息框:
    图2

4.2 生成项目

  • 打开 Qt Creator 并创建一个新的 应用程序项目_qtoolbutton:
    在这里插入图片描述
  • 默认继承QMainWindow 类,(在上个项目_qpushbutton中,选择了Widget基类),不要勾选“Generate form”:
    在这里插入图片描述- 将两个配置好的Kits同时选上(后期我们会通过条件编译进行选择):
    在这里插入图片描述
  • 其他界面使用默认设置,项目生成的最初代码:
    图11

4.3 完成代码编辑

4.3.1 修改项目文件 _qpushbutton.pro

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		mainwindow.cpp
14
15	HEADERS += \
16		mainwindow.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	# 根据使用的 Qt 版本设置编译条件
24	greaterThan(QT_MAJOR_VERSION, 4) {
25		# 如果使用的是 Qt 5 或者更新版本
26		message("使用的是 Qt 5版本")
27
28	} else {
29		# 如果使用的是 Qt 4 或者更早的版本
30		message("使用的是 Qt 4版本")
31		DEFINES += QT_ARM_PLATFORM
32		QMAKE_CXXFLAGS += -std=c++11
33		QMAKE_CXXFLAGS += -Wno-psabi -Wno-deprecated-declarations
34
35		LIBS += -lts
36
37	}

我们在系统生成的项目文件中使用条件编译增加目标为qt4-arm时的代码:

  • 第32行:定义预处理器宏 QT_ARM_PLATFORM,这个宏将被传递给编译器和链接器,用来在程序中做条件编译,判定当前编译的代码是否运行在arm。
  • 第32行:由于最新版本的 Qt Creator 默认使用了 C++11 标准。所以在自动生成的代码中会使用 C++11 新增的关键字 nullptr,但是我们的编译器并不认识它,会导致编译失败。增加QMAKE_CXXFLAGS += -std=c++11就能修正这一错误。
    第33行:
    QMAKE_CXXFLAGS += -Wno-psabi -Wno-deprecated-declarations 可以帮助我们忽略掉我们不关心的警告。
    第34行:LIBS += -lts 指令用于链接触摸屏 tslib的库文件。

4.3.2 修改 main.cpp

1 	#include "mainwindow.h"
2 
3 	#include <QApplication>
4 	//引入 QPushButton
5 	#ifdef QT_ARM_PLATFORM
6 	#include <QTextCodec>
7 	#endif
8 	int main(int argc, char *argv[])
9 	{
10		QApplication a(argc, argv);
11
12	#ifdef QT_ARM_PLATFORM
13		//解决中文乱码
14		QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
15		QTextCodec::setCodecForTr(QTextCodec::codecForName("system"));    //若英文系统,则用GBK
16		QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
17		QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
18	#endif
19
20		MainWindow w;
21		w.show();
22		return a.exec();
23	}

为了解决当程序运行在arm架构系统时,中文显示文乱码问题,根据从.pro获得的宏QT_ARM_PLATFORM作为编译条件,判断如果系统运行在arm架构,则程序包含文本字符串转换。

4.3.3 修改 mainwindow.h

1 	#ifndef MAINWINDOW_H
2 	#define MAINWINDOW_H
3 
4 	#include <QMainWindow>
5 	/* 引入 QToolButton 类 */
6 	#include <QToolButton>
7 	/* 引入 QToolBar 类 */
8 	#include <QToolBar>
9 	class MainWindow : public QMainWindow
10	{
11		Q_OBJECT
12
13	public:
14		MainWindow(QWidget *parent = nullptr);
15		~MainWindow();
16
17	private:
18	/* 声明一个 QToolButton 对象 */
19	 QToolButton *toolButton;
20	 /* 声明一个 QToolBar 对象 */
21	 QToolBar *toolBar;
22
23	private slots:
24		/* 声明对象 toolBar 的槽函数 */
25		void onToolButtonClicked();
26
27	};
28	#endif // MAINWINDOW_H

第 19 和 21 行,声明 QToolButton 对象和 QtoolBar 对象。
第 25行,声明一个 QToolButton 对象的槽函数,用来响应对toolButton按钮的点击。

4.3.4 修改 mainwindow.cpp

1 	#include "mainwindow.h"
2 	#include <QApplication>
3 	#include <QStyle>
4 	#include <QMessageBox>
5 	#include <QTextCodec>
6 
7 	MainWindow::MainWindow(QWidget *parent)
8 		: QMainWindow(parent)
9 	{
10		/* 设置主窗体的位置和大小 */
11		this->setGeometry(0, 0, 800, 480);
12		/* 实例化 QToolBar 对象 */
13		toolBar = new QToolBar(this);
14		/* 设置 toolBar 的位置和大小 */
15		toolBar->setGeometry(0, 0, 800, 80);
16		/* 实例化 QStyle 类对象,用于设置风格,调用系统类自带的图标 */
17		QStyle *style = QApplication::style();
18		/* 使用 Qt 自带的标准图标,可以在帮助文档里搜索 QStyle::StandardPixmap */
19		//QIcon icon =  style->standardIcon(QStyle::SP_TitleBarContextHelpButton);
20		QIcon icon =  style->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton);
21		/* 实例化 QToolButton 对象 */
22		toolButton = new QToolButton();
23		/* 设置图标 */
24		toolButton->setIcon(icon);
25		/* 设置要显示的文本 */
26		toolButton->setText("设置");
27		/* 调用 setToolButtonStyle()方法,设置 toolButoon 的样式,设置为文本置于图标下方 */
28		toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
29		//连接槽函数
30		
31	#ifdef QT_ARM_PLATFORM
32		//   在 Qt 4 中,我们使用 QObject::connect() 函数来连接信号和槽:
33		connect(toolButton, SIGNAL(clicked()), this, SLOT(onToolButtonClicked()));
34	#else
35		//   在 Qt 5 中,由于新的信号和槽语法已被引入,可以使用关键字 connect的函数指针参数语法来连接信号和槽:
36		connect(toolButton, &QToolButton::clicked, this, &MainWindow::onToolButtonClicked);
37	#endif
38		
39		/* 最后将 toolButton 添加到 ToolBar 里 */
40		toolBar->addWidget(toolButton);
41	}
42
43	MainWindow::~MainWindow()
44	{
45	}
46
47	/* 槽函数的实现 */
48	void MainWindow::onToolButtonClicked()
49	{
50		//弹出警告框
51		QMessageBox::warning(this, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("设置成功"), QMessageBox::Ok);
52		
53	}

这段代码实现了一个工具栏 toolbar 和一个工具按钮 toolButton,工具按钮上面有一个 Qt 自带的图标并有一个设置文本,点击该按钮会弹出一个警告框显示 “设置成功” 的文字。

  • 第11行:首先设置主窗体的位置和大小为 (0,0) 和 (800,480);
  • 第13行和第15行:实例化一个 QToolBar 工具栏对象,设置位置为主窗口顶部,并占据整个界面的一行,高度为80;
  • 第17行:使用 QApplication 的 style() 函数获取当前应用程序的样式;
  • 第20行:使用 QStyle::standardIcon() 函数来获取一个标准图标,这里获取的是一个水平扩展的工具栏图标;
  • 第22行:实例化一个 QToolButton 对象;
  • 第24行:设置上面的工具按钮的图标为上一步获取的图标;
  • 第26行:设置工具提示文本为 “设置”;
  • 第28行:设置工具按钮的样式,设置为文本置于图标下方;
  • 第33行:如果编译是在 Qt 4 中进行,则使用旧的 QObject::connect() 函数来将工具按钮的 clicked(点击) 信号连接到主窗口类的 onToolButtonClicked 槽函数;
  • 第36行:如果编译是在 Qt5 中进行,使用新的 connect 函数指针参数语法来将工具按钮的 clicked (点击) 信号连接到主窗口类的 onToolButtonClicked 槽函数;
  • 第40行 使用 QToolBar 的 addWidget() 函数将工具按钮添加到工具栏中。

4.4 切换Kit,获得运行在不同系统中的运行的执行文件

点击窗口左边的Debug,可以选择编译运行在不同平台上的可执行文件,arm-v7为arm架构的设备,使用Qt4库,而桌面则是当前ubuntu系统,使用Qt5。
在这里插入图片描述Qt5编译完成的可执行程序_qtoolbutton,存放在项目目录的build-_qtoolbutton-unknown-Debug/文件夹下,Qt4编译完成的可执行程序_qtoolbutton,存放在项目目录的build-_qtoolbutton-arm_v7-Debug/文件夹下。

4.5 程序中的qt机制

4.5.1 信号与槽的解耦功能介绍、connect()在Qt4和Qt5中使用分析

在程序中,不同对象之间的耦合度越低,就越容易维护和扩展。例如,当一个类的内部发生变化时,只会影响到该类的实现和使用,而不会对其他类造成太大的影响。这种低耦合度的设计可以使程序更加灵活和易于修改,从而更好地适应需求变化。
解耦(Decoupling)是指在软件设计中,降低不同模块、组件或对象之间的依赖关系,从而提高软件的可维护性和可扩展性。
信号与槽机制就是一种解耦方式,通过信号与槽之间的连接,解除了不同对象之间的直接依赖关系。当某个对象发送了信号时,其他对象只需要在槽函数中捕获该信号,而不需要直接调用该对象的方法。这样,不同对象之间的耦合度就降低了,从而更容易维护和扩展程序。信号与槽就是用connect()函数连接起来的。connect函数的参数包括四个:

  1. 发射信号的对象指针
  2. 发射信号的信号函数
  3. 接收信号的对象指针
  4. 接收信号的槽函数
    在我们上面的_qpushbutton项目中,将toolButton按钮的 clicked 信号连接到主窗口定义的槽函数onToolButtonClicked()上:
  • Qt4:
connect(toolButton, SIGNAL(clicked()), this, SLOT(onToolButtonClicked()));
  • Qt5:
connect(toolButton, &QToolButton::clicked, this, &MainWindow::onToolButtonClicked);

第一句是旧版方式,在Qt4中使用,信号与槽之间使用的是字符串,即 SIGNAL 和 SLOT 宏,例如 SINGAL(clicked) 和 SLOT(onToolButtonClicked())。
第二句是 Qt5 中新引入的方式。在这种方式中,信号和槽的连接使用了一个新的语法,即直接使用信号和槽的函数指针。例如 &QToolButton::clicked 表示 QToolButton 类的 clicked() 信号,&MainWindow::onToolButtonClicked 表示 MainWindow 类的 onToolButtonClicked() 槽函数。Qt5 中引入这种新的连接方式,可以带来以下一些好处:

  1. 编译时检查:由于信号和槽的连接使用的是函数指针,因此编译器可以在编译时就检查连接的有效性,避免了在运行时才能发现的错误。
  2. 更安全:使用函数指针的方式,可以避免一些潜在的问题,例如字符串的拼写错误、槽函数不存在等。
  3. 更加简洁:相较于字符串,函数指针的语法更加简洁和易于理解。

需要注意的是,Qt5 中的新连接语法不完全兼容 Qt4 的旧语法。因此,在将 Qt4 程序迁移到 Qt5 时,也需要将相应的信号和槽的连接方式进行更新。

4.5.2 QToolBar

QToolBar 是一个容器控件。它提供了一种在主窗口中快速创建工具栏的方式,可以方便地创建、添加和管理工具栏以及工具按钮等控件。QToolBar 默认是可以拖拽的,也就是说,用户可以将工具栏拖动到窗口的任意位置。QToolBar 可以被添加到 QMainWindow 或其他以QWidget为基类的容器窗口中。
在我们上面的_qtoolbutton项目中,简单介绍了QToolBar和Tool Button 的使用,我们创建了一个 QToolBar 对象,并将其添加到了主窗口中。接着,我们创建了一个 Tool Button 按钮,并设置对应的文本和工具提示,然后通过 addWidget 方法将其添加到了 QToolBar 中。

在实际应用中,QMenu 和 QToolBar 经常一起使用,可以在菜单栏中创建菜单,用于对应用程序进行一些基本的操作,例如打开或保存文件,或进行一些设置选项。同时,可以在 QToolBar 中添加相同的操作按钮或其他工具按钮(例如下拉框、复选框等),以便用户可以更快速、方便地访问这些操作命令。这种方式不仅更方便用户操作,还能够使应用程序的用户界面看起来更加整洁和专业。
当 QMenu 和 QToolBar 一起使用时,通常需要添加 QAction 才能将菜单项和工具栏按钮关联起来,从而使得这些控件的行为一致。这是因为,QAction 不仅可以添加到 QMenuBar 和 QToolBar 中,还可以添加到 QMenu、QSystemTrayIcon 等其他控件中,因此可以实现控件之间的交互。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值