前言

本文介绍QT常用控件的第五个按钮,QCommandLinkButton按钮编程。通过这个例子,进一步巩固QT管理资源机制,巩固QT的信号与槽知识,本例程还使用了QListView控件显示文件列表,同时使用水平布局(QHBoxLayout)和 竖直布局(QVBoxLayout)展示如何布局界面上的控件。
本例程设计是在chatgpt的帮助下完成的,编译代码经过测试通过。

感谢朋友提供的chatgpt软件,特别是其中的gpt-box桌面工具,更是我离不开的工具。感兴趣的同仁可前往一观(apsuai.com)。

我们的调试环境仍然是双架构Kits,编译调试在当前的ubuntu(qt5)中进行,重新编译后下载到目标arm设备(qt4)中运行。
我们的编程环境为:Ubuntu64位系统(22.04),目标架构:
(1) qt5 x86_64 架构;
(2)qt4 32位arm架构。
环境配置请参见《Qt常用的按钮控件编程(一)》第1节。


7、QCommandLinkButton按钮

QCommandLinkButton是一个Qt Widget(小部件),用于在对话框和向导窗口中创建带图标和标题的带有描述和操作按钮。
QCommandLinkButton是Qt中的一个类,继承自QPushButton。相对于普通的 QPushButton,QCommandLinkButton通常具有更大的尺寸和更明显的样式,舒适性和可读性更好,适合用户直接需点击的地方,比如对话框中的按钮。

以下是一些 QCommandLinkButton 类的常见属性和方法:

  • icon:按钮上显示的图标。
  • text:按钮上使用的文本。
  • description:对于该操作的或这个阶段的进一步描述。
  • default:为true时,该按钮将是对话框上的默认按钮。
  • enabled:按钮是否处于启用状态。
  • sizeHint:计算并返回窗口部件的外部大小建议。
  • clicked:每当用户按下该button时就发出信号。

Qt widgets 与 QWidget 的关系
在Qt中,QWidget是所有用户界面类的基类。它是一个通用的窗口小部件,可用于创建各种类型的用户界面元素,例如应用程序主窗口、对话框、标签、按钮等。
Qt widgets是Qt GUI模块的一部分,是一组用于构建用户界面的C++类。它提供了多个小部件类,例如QLabel、QPushButton、QLineEdit等。这些小部件都继承自QWidget,并添加了一些特定的功能和属性,以实现特定的用户界面元素。

7.1 例程功能和程序执行效果

创建一个基于 Qt QCommandLinkButton 按钮c++例程,项目名称"_qcommandlinkbutton" ,不使用拖取控件,控件全部采用编程。主界面分为左右两部分,左边是两个QCommandLinkButton 按钮:“添加 PNG文件”和“清空列表”,右边一个QListView控件,用来显示选中的PNG文件。

  • 编译完成后生成两个同名可执行程序_qcommandlinkbutton,一个使用使用Qt4库,运行在arm架构设备,另一个使用Qt5库,运行在当前ubuntu系统。
    程序执行效果:
    (1)程序启动后效果:

在这里插入图片描述下图是选中的文件列表显示在右边的QListView控件中,点击“清空列表”,这些文件列表就消失了。
在这里插入图片描述

7.2 生成项目

打开 Qt Creator 并创建一个新的 应用程序项目_qcommandlinkbutton,选择Widget作为基类,不要勾选“Generate form”,不使用拖取控件,控件全部采用编程,将两个配置好的Kits同时选上,项目新建完成如下图。(详细的项目新建过程参见:《Qt常用的按钮控件编程(一)》)。

在这里插入图片描述

7.3 添加资源文件

在本例程的项目目录的images 文件夹的图片如下图:
在这里插入图片描述
所有图标文件都是从https://www.iconfinder.com/ 网站下载的免费图标,下载过程在《用chatgpt学习在Iconfinder网站下载png图标》一文中有详细介绍。

添加图片资源的步骤如下:

  • 在项目目录中右键点击 Resources 目录,选择 Add New… ,并选择 Qt -> Qt Resource File。
    在这里插入图片描述在这里插入图片描述- 输入资源文件文件名icon,文件名自行定义,其他默认,然后点击“下一步”。

在这里插入图片描述

  • 在 Qt Creator 中新建资源文件后,默认会进入 icon.qrc 文件编辑模式(如果关闭了,可以右键这个文件点击选择“Open in Editor”),为了方便分类管理文件,我们可以使用 Add Prefix 功能为资源文件添加前缀,前缀的格式应该为类似文件系统中的路径格式,例如 /images。
    在这里插入图片描述- 为了确保路径正确,前缀中的 / 是必需的,它在资源文件引用时是路径分隔符,起到类似 Linux 下根节点的作用,我们现在第⑪处添加了前缀/。

在这里插入图片描述

  • 添加了前缀后,我们添加资源图片,放在/images 前缀的下面。我们下载的图片文件已经存放在本项目路径 images 文件夹,添加完成需要按“Ctrl + S”保存 icon.qrc 才会看到左边的结果。添加完成如下图。

在这里插入图片描述

  • 完成资源添加后,可以看到项目文件_qcommandlinkbutton.pro增加了与资源相关的代码:

在这里插入图片描述

  • 查看icon.qrc文件内容
<RCC>
    <qresource prefix="/">
        <file>images/17442_add_smiley_icon.png</file>
        <file>images/17443_remove_smiley_icon.png</file>
        <file>images/34576_add_favorites_icon.png</file>
        <file>images/51907_delete_favorite_icon.png</file>
        <file>images/103395_image_book_remove_icon.png</file>
        <file>images/103409_text_add_book_icon.png</file>
        <file>images/103747_close_add_user_icon.png</file>
        <file>images/103763_close_user_remove_icon.png</file>
        <file>images/103767_add_full_user_follow_icon.png</file>
        <file>images/103777_user_remove_half_icon.png</file>
        <file>images/299068_add_sign_icon.png</file>
        <file>images/1564505_close_delete_exit_remove_icon.png</file>
        <file>images/3507741_add_cart_ecommerce_iconoteka_shop_icon.png</file>
        <file>images/6619484_and_cart_ecommerce_remove_shopping_icon.png</file>
        <file>images/7952168_box_logistics_shipping_package_delivery_icon.png</file>
        <file>images/7952193_box_open_cardboard_opened_delivery_icon.png</file>
        <file>images/7952197_box_wrong_incorrect_cross_delivery_icon.png</file>
        <file>images/7952199_box_delivery_add_package_buy_icon.png</file>
        <file>images/9004815_add_file_document_page_icon.png</file>
        <file>images/9004834_file_document_page_paper_icon.png</file>
        <file>images/9070671_shopping_cart_del_icon.png</file>
        <file>images/9070673_shopping_cart_add_icon.png</file>
        <file>images/10354957_layer_ui_web_icon.png</file>
        <file>images/10355027_layer_remove_icon.png</file>
    </qresource>
</RCC>

qrc文件是一种XML格式的文件,它包含了Qt资源文件的描述信息,通常使用Qt Creator编辑。在qrc文件中,可以包含多个资源,每个资源都有一个唯一的标识符和一个对应的文件路径或二进制数据。当应用程序需要使用这些资源时,可以通过Qt提供的API来访问它们。

7.4 代码编辑

7.4.1 修改项目文件 _radiobutton.pro

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += 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.0
SOURCES += \
    main.cpp \
    widget.cpp
HEADERS += \
    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
RESOURCES += \
    icon.qrc

# 根据使用的 Qt 版本设置编译条件
greaterThan(QT_MAJOR_VERSION, 4) {
    # 如果使用的是 Qt 5 或者更新版本
    message("使用的是 Qt 5版本")

} else {
    # 如果使用的是 Qt 4 或者更早的版本
    message("使用的是 Qt 4版本")
    DEFINES += QT_ARM_PLATFORM
    QMAKE_CXXFLAGS += -std=c++11
    QMAKE_CXXFLAGS += -Wno-psabi -Wno-deprecated-declarations
    LIBS += -lts
}

7.4.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"));    //若英文系统,则用GBK
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
#endif

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

7.4.3 修改 widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QCommandLinkButton>
#include <QListView>
#include <QVBoxLayout>
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void browseFiles();
    void clearFiles();
private:
    QCommandLinkButton *_addFilesBtn;
    QCommandLinkButton *_clearFilesBtn;
    QStringList _files;
    QHBoxLayout *hbox;
    QVBoxLayout *vbox;
    QListView* _listView;// 声明一个QListView指针


};
#endif // WIDGET_H

7.4.4 修改 widget.cpp

#include "widget.h"
#include <QDialog>

#include <QFileDialog>
#include <QStringListModel>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    /* 主窗体设置位置和显示的大小 */
    this->setGeometry(0, 0, 800, 480);

    vbox =  new QVBoxLayout();
    hbox =  new QHBoxLayout();
    _addFilesBtn = new QCommandLinkButton("添加 PNG 文件", "请选择您需要添加的PNG文件", this);
    _addFilesBtn->setIcon(QIcon(":/images/17442_add_smiley_icon.png"));
    _clearFilesBtn = new QCommandLinkButton("清空列表", "单击此按钮以清除文件列表", this);
    _clearFilesBtn->setIcon(QIcon(":/images/17443_remove_smiley_icon.png"));

    vbox->addWidget(_addFilesBtn);
    vbox->addWidget(_clearFilesBtn);

    _listView =new QListView();
    QStringListModel *model = new QStringListModel;
    QStringList list;
    model->setStringList(list);
    _listView->setModel(model);
    hbox->addLayout(vbox);
    hbox->addWidget(_listView);
    this->setLayout(hbox);

    connect(_addFilesBtn, SIGNAL(clicked()), this, SLOT(browseFiles()));
    connect(_clearFilesBtn, SIGNAL(clicked()), this, SLOT(clearFiles()));

}

Widget::~Widget()
{
}

void Widget::browseFiles()
{

    QStringList files = QFileDialog::getOpenFileNames(
                this,
                "选择要添加到列表中的 PNG 文件",
                 QDir::currentPath() + "/images",
                 "PNG 文件 (*.png)"
                );

    _files.append(files);

    QStringListModel* model = qobject_cast<QStringListModel*>(_listView->model());
    model->setStringList(_files);

}


void Widget::clearFiles()
{
    _files.clear();

    QStringListModel* model = qobject_cast<QStringListModel*>(_listView->model());
    model->setStringList(_files);
}

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

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

7.6 程序中的qt机制

7.6.1 水平布局(QHBoxLayout)和 竖直布局(QVBoxLayout)

水平布局 QHBoxLayout 和竖直布局 QVBoxLayout 是 Qt 中常用的两种布局方式,它们可以用来配置窗口中的控件摆放位置。

QHBoxLayout 类在水平方向(x 轴)布置控件,其中的控件按从左到右的顺序排列。它通常用于“两侧对齐”等窗口中需要横向排列几个控件的情形。可以通过 QHBoxLayoutaddWidget() 方法将控件加入到布局中。

例如,下面的代码将创建一个按钮和一个文本框控件,将它们按左右排列并加入到 QHBoxLayout 布局对象中:

button = QPushButton('Button')
edit = QLineEdit()
layout = QHBoxLayout()
layout.addWidget(button)
layout.addWidget(edit)

类似地,QVBoxLayout 在竖直方向(y 轴)布置控件,其中的控件按从上到下的顺序排列。它通常用于需要竖向排列几个控件的窗口中。也是使用 addWidget() 方法将控件加入到布局中。

例如,下面的代码将创建一个列表框和一个文本标签控件,将它们按顺序垂直排列并加入到 QVBoxLayout 中:

listbox = QListBox()
label = QLabel('Message:')
layout = QVBoxLayout()
layout.addWidget(listbox)
layout.addWidget(label)

当将一个子控件添加到水平或竖直布局中时,该控件会占据所在方向上的全部空间,直到被其他控件或布局排列覆盖。常用的参数选项还有 addStretch(),它会在控件之间添加间隔。

例如,下面的代码将在两个按钮间添加一些弹簧以建立间距:

layout.addWidget(button1)
layout.addStretch()
layout.addWidget(button2)

7.6.2 _qcommandlinkbutton程序中控件布局

在我们的程序中,两个QCommandLinkButton 上下排列放在窗口左边,QListView 列表放在主窗口最右边。
代码创建了一个垂直布局管理器 vbox(QVBoxLayout ) ,将两个 QCommandLinkButton 分别添加到其中。然后,我们创建一个水平布局管理器 hbox(QHBoxLayout ),使用 hbox在窗体中包含了 vbox 和 QListView,实现了该应用程序要求的主窗体界面。

总结

本文介绍QT常用控件QCommandLinkButton按钮编程。通过这个例子,进一步巩固QT管理资源机制,巩固QT的信号与槽知识,本例程还使用了QListView控件显示文件列表,同时使用水平布局(QHBoxLayout)和 竖直布局(QVBoxLayout)展示如何布局界面上的控件。
本例程设计是在chatgpt的帮助下完成的,编译代码经过测试通过。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐