『 QT 』按钮类控件属性解析

文章目录

    • [1 QAbstractButton](#1 QAbstractButton)
    • [2 QPushButton](#2 QPushButton)
      • [2.1 添加图标与设置大小](#2.1 添加图标与设置大小)
      • [2.2 添加按钮的快捷键](#2.2 添加按钮的快捷键)
      • [2.2.1 通过绑定快捷键实现移动某个控件](#2.2.1 通过绑定快捷键实现移动某个控件)
      • [2.2.2 autoRepeat 设置连续触发](#2.2.2 autoRepeat 设置连续触发)
      • [2.2.3 autoRepeatDelay鼠标点击重复触发延迟时间 与 autoRepeatInterval鼠标点击重复触发周期](#2.2.3 autoRepeatDelay鼠标点击重复触发延迟时间 与 autoRepeatInterval鼠标点击重复触发周期)
    • [3 QRadioButton](#3 QRadioButton)
      • [3.1 toggled 信号 选择性别并显示 (更新 Label )](#3.1 toggled 信号 选择性别并显示 (更新 Label ))
      • [3.2 QButtonGroup - 利用 RadioButton 设计模拟点餐系统](#3.2 QButtonGroup - 利用 RadioButton 设计模拟点餐系统)
    • [4 QCheckBox 复选框](#4 QCheckBox 复选框)

1 QAbstractButton

Qt中通常使用QPushButton表示一个按钮, 该控件也是在前文中用到的较多的控件之一;

QPushButton类继承自QAbstractButton, 而QAbstractButton继承自QWidget;

QAbstractButton类是一个抽象类, 这个抽象类是所有按钮控件的父类;

由于各类按钮的父类为QAbstractButton类, 而QAbstractButton的父类为QWidget, 这意味着所有的按钮都可以使用前文中对QWidget所描述的属性与方法;

QAbstractButton中常用的属性有如下:

属性 说明
text 按钮中的文本
icon 按钮中的图标
iconSize 按钮中图标的尺寸
shortCut 按钮对应的快捷键
autoRepeat 长按鼠标左键时是否会出现触发: - 设置为true则将会持续产生鼠标点击事件 - 设置为false则必须释放鼠标, 再次按下鼠标时才会产生点击事件
autoRepeatDelay 重复触发的延迟时间, 按住按钮多久之后开始重复触发
autoRepeatInterval 重复触发的周期

2 QPushButton

上述介绍了QAbstractButton类的相关属性, 对应的属性设置使用QPushButton控件进行演示;


2.1 添加图标与设置大小

通常情况下, 大部分的控件都能设置对应的图标, 按钮也不例外;

采用同样的思路进行图标的设置:

  1. 使用QRC对图标资源进行存储与管理
  2. 使用QIcon对象加载图标资源
  3. 使用setIcon()函数将QIcon对象设置进QPushButton对图标进行设置
  4. 创建QSize对象设置参数大小
  5. 调用setIconSize()函数将QSize对象传入从而设置图标大小

假设存在一个这样的图标(下载自阿里巴巴矢量图库):

需要将这个图标设置进QPushButton对象中;

假设存在一个Widget类, 该类中存在一个QPushButton, 其objectNamePushButton;

按照上述步骤对QPushButton进行图标的设置:

  1. 加载图标资源至QRC

    此处如何使用QRC不进行赘述;

  2. QIcon加载图标资源

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        ui->pushButton->setText("OriginCat");
        QIcon icon(":/OriginCat.png");
    }

    创建一个QIcon对象, 将QRC资源进行加载;

  3. QPushButton设置图标

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        ui->pushButton->setText("OriginCat");
        QIcon icon(":/OriginCat.png");
        ui->pushButton->setIcon(icon);
    }

    直接调用PushButtonsetIcon()QIcon对象作为参数传入;

  4. 设置图标大小

    QPushButton中设置图标的大小通常需要单独创建一个QSize对象来存放图标所需的大小参数;

    创建对应的QSize对象后可以通过setIconSize()函数将该对象进行传入从而设置图标的大小尺寸;

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        ui->pushButton->setText("OriginCat");
        QIcon icon(":/OriginCat.png");
        ui->pushButton->setIcon(icon);
        QSize icon_size(80, 80);
        ui->pushButton->setIconSize(icon_size);
    }
  5. 运行结果


2.2 添加按钮的快捷键

Qt中, 可以调用setShortCut()方法来定义一个按钮的快捷键;

假设存在一个Widget, 在该Widget中存在一个objectNamepushButtonQPushButton按钮;

对应的text()"Pressed "K";

该按钮clicked信号对应的槽为如下:

cpp 复制代码
void Widget::on_pushButton_clicked()
{
	qDebug() << "The 'K' Clicked;  count: " << count++;
}

当需要对一个按钮设置对应的快捷键时需要调用该按钮控件的setShortCut()函数;

该函数需要传入一个QKeySequence对象, 该对象用来存储需要封装的快捷键;

通常有两种方式来实例化这个QKeySequence对象:

  • 直接采用字符形式

    QKeySequence对象支持直接使用某个键盘字符作为参数从而构造对应的对象;

    如:

    cpp 复制代码
    ui->pushButton->setShortcut(QKeySequence("Alt+K"));
    ui->pushButton->setShortcut(QKeySequence("K"));
  • 采用枚举值的形式

    在QT中枚举了关于各种按键的枚举值, QKeySequence允许使用这些枚举值来进行构造;

    如:

    cpp 复制代码
    ui->pushButton->setShortcut(QKeySequence(Qt::Key_K));
    ui->pushButton->setShortcut(QKeySequence(Qt::ALT + Qt::Key_K));

    对应的枚举值可以通过按下Ctrl键并点击对应的枚举值来查看其定义:

    cpp 复制代码
     enum Key {
            // Unicode Basic Latin block (0x00-0x7f)
            Key_Space = 0x20,
            Key_Any = Key_Space,
            Key_Exclam = 0x21,
            Key_QuoteDbl = 0x22,
            Key_NumberSign = 0x23,
            Key_Dollar = 0x24,
            Key_Percent = 0x25,
            Key_Ampersand = 0x26,
            Key_Apostrophe = 0x27,
            Key_ParenLeft = 0x28,
            Key_ParenRight = 0x29,
            Key_Asterisk = 0x2a,
            Key_Plus = 0x2b,
            Key_Comma = 0x2c,
            Key_Minus = 0x2d,
            Key_Period = 0x2e,
            Key_Slash = 0x2f,
            Key_0 = 0x30,
            Key_1 = 0x31,
            Key_2 = 0x32,
    		...
             ...
     };

    需要注意的是, 在QT中所枚举的键值类型较多, 包括但不限于:

    • 普通键

      普通的键盘, 主要用于输入字符, 数字或者符号, 通常没有其他特定的功能;

      如典型的A - Z, 0 - 9等;

    • 修饰键

      修饰键用于修改其他键的行为, 通常与其他键组合使用, 如Ctrl + c复制, 本身不产生字符, 而是改变键盘事件的修饰状态, 通过QKeyEvent::modifiers()获取;

      Qt通常区分左/右修饰键;

    • 功能键

      功能键是可编程的特殊键, 常用于应用特定命令或操作系统, 通常位于键盘顶部(F1 - F12)或扩展键盘上;

    • 编辑键

      编辑键专用于文本或内容的编辑操作, 如删除, 插入, 导航等;

      常见的有Key_Backspace(退格键), Key_Delete(删除键), Key_Insert(插入键);

    • ...

      更多其他键可以参考Qt文档;

回归话题, 此处我们调用setShortCut()来为按钮设置快捷键;

此处直接设置K键来触发对应的clicked();

对应的代码为:

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->pushButton->setShortcut(QKeySequence(Qt::Key_K));
}

结果运行为:

当按下快捷键时, 将发射clicked()信号, 对应的槽函数也被执行;


2.2.1 通过绑定快捷键实现移动某个控件

设计一个程序, 通过绑定键盘上的上下左右实现通过使用按键对某个控件进行移动操作;

假设存在一个Widget, 其控件为如下:

其中五个ButtonobjectName分别为golden(最顶端的按钮), button_up/down/left/right(上下左右的按钮);

对应的几个按钮的Icon资源分别为(载自阿里巴巴矢量图标库):

具体的步骤为如下:

  1. 初始化Button

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        // 初始化字体为空
        ui->setupUi(this);
        ui->golden->setText("");
        ui->button_up->setText("");
        ui->button_down->setText("");
        ui->button_left->setText("");
        ui->button_right->setText("");
        // 设置按钮颜色
        ui->button_up->setStyleSheet("background-color: #E9E9E9");
        ui->button_down->setStyleSheet("background-color: #E9E9E9");
        ui->button_left->setStyleSheet("background-color: #E9E9E9");
        ui->button_right->setStyleSheet("background-color: #E9E9E9");
        // 设置背景颜色
        this->setStyleSheet("background-color: #FFFFFF");
    }

    此处的初始化主要是为了图标的位置不受text()所影响, 其次调整按钮的颜色使其更美观;

    运行结果为如下:

  2. 创建QRC文件并将图片上传至QRC中进行管理

    在此之前已在当前项目的目录下创建了一个image/目录便于Icon资源的管理;

  3. 创建QIcon对象加载QRC资源

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
    	// ...
            
        // 从QRC中加载Icon资源
        QIcon golden(":/image/golden.png");
        QIcon upIcon(":/image/up.png");
        QIcon downIcon(":/image/down.png");
        QIcon leftIcon(":/image/left.png");
        QIcon rightIcon(":/image/right.png");
    }

    创建QIcon对象并传入QRC路径来加载Icon图片资源;

  4. 设置IconiconSize

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
    	// ...
              
    	// 设置Icon
         ui->golden->setIcon(golden);
         ui->button_up->setIcon(upIcon);
         ui->button_down->setIcon(downIcon);
         ui->button_left->setIcon(leftIcon);
         ui->button_right->setIcon(rightIcon);
    
         // 设置Icon大小
         ui->golden->setIconSize(QSize(80, 80));
         ui->button_up->setIconSize(QSize(50, 50));
         ui->button_down->setIconSize(QSize(50, 50));
         ui->button_left->setIconSize(QSize(30, 30));
         ui->button_right->setIconSize(QSize(30, 30));
    }

    创建QIcon对象, 并根据实际情况来调整Icon的大小;

    此时运行程序结果如下:

  5. 绑定快捷键

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
    	// ...
            
         // 绑定快捷键 - 上下左右
         ui->button_up->setShortcut(QKeySequence(Qt::Key_Up));
         ui->button_down->setShortcut(QKeySequence(Qt::Key_Down));
         ui->button_left->setShortcut(QKeySequence(Qt::Key_Left));
         ui->button_right->setShortcut(QKeySequence(Qt::Key_Right));
    }

    通过按键的枚举来绑定对应的快捷键, 此处绑定键盘中的(上下左右);

  6. 设置槽函数

    槽函数主要通过获取需要移动的geometry属性并根据当前的geometry属性根据按键的方向来设置新的geometry属性;

    cpp 复制代码
    // 槽
    void Widget::on_button_up_clicked()
    {
        QRect rect = ui->golden->geometry();
        ui->golden->setGeometry(rect.x(), rect.y()-3, rect.width(),rect.height());
        qDebug()<<ui->golden->geometry();
    }
    
    
    void Widget::on_button_down_clicked()
    {
        QRect rect = ui->golden->geometry();
        ui->golden->setGeometry(rect.x(), rect.y()+3, rect.width(),rect.height());
        qDebug()<<ui->golden->geometry();
    }
    
    void Widget::on_button_left_clicked()
    {
        QRect rect = ui->golden->geometry();
        ui->golden->setGeometry(rect.x()-3, rect.y(), rect.width(),rect.height());
        qDebug()<<ui->golden->geometry();
    }
    
    void Widget::on_button_right_clicked()
    {
        QRect rect = ui->golden->geometry();
        ui->golden->setGeometry(rect.x()+3, rect.y(), rect.width(),rect.height());
        qDebug()<<ui->golden->geometry();
    }

    此处 槽函数除了设置了新的geometry属性以外还对对应的geometry属性进行了qDebug()<<打印;

  7. 运行结果

    最终运行结果为如下:


2.2.2 autoRepeat 设置连续触发

2.2.1中设计了一个通过绑定键盘快捷键实现操控某个控件的移动;

在该程序中, 可以通过长按方向键进行一个持续性的触发, 而使用鼠标左键长按却无法实现持续触发的功能;

从该图中可以看出并不能直接通过长按鼠标左键来控制对应的连发;

通常在按钮中存在属性autoRepeat可以控制对应的连发状态, 通常情况下, 键盘的长按连续触发是默认就是支持的, 而鼠标长按的连发则为默认关闭状态, 可通过setAutoRepeat()来设置对应按钮的鼠标长按连发的开启或关闭状态;

  • 设置鼠标长按连发

    cpp 复制代码
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
    	// ...
            
    	// 设置鼠标连发       
         ui->button_up->setAutoRepeat(true);
         ui->button_down->setAutoRepeat(true);
         ui->button_left->setAutoRepeat(true);
         ui->button_right->setAutoRepeat(true);
    }

设置后的结果为:


2.2.3 autoRepeatDelay鼠标点击重复触发延迟时间 与 autoRepeatInterval鼠标点击重复触发周期

除了设置鼠标长按连击以外还可以设置重复触发的延迟时间与重复触发周期;

首先需要声明下面的参数通常是与鼠标点击的事件有关;

  • autoRepeatDelay

    这是一个设置重复触发延迟时间的参数, 可以通过setAutoRepeatDelay(int)来设置对应的属性, 其中函数中参数是int类型, 单位为ms;

    这里以button_left为例, 设置为1000ms, 即1s;

    cpp 复制代码
    ui->button_left->setAutoRepeatDelay(1000);

    运行结果为:

    从结果可以看出, 由于button_right没有设置autoRepeatDelay参数, 因此当鼠标左键点击右侧按钮时, 顶端的Button无延迟直接移动, 而当鼠标左键点击左侧按钮时, 延迟了大概一秒钟随后开始进行重复操作;

  • autoRepeatInterval

    这是一个设置重复触发周期时间的参数, 可以通过setAutoRepeatInterval(int)来设置对应的属性, 其中函数中参数是int类型, 单位为ms;

    这个参数则是控制重复触发时的时间间隔, 此处同样设置button_left进行演示;

    cpp 复制代码
    ui->button_left->setAutoRepeatInterval(3);

    运行结果为:

    从结果可以看出, 由于button_right没有设置autoRepeatInterval参数, 因此当鼠标左键点击右侧按钮时, 顶端的Button重复操作的移动速度较慢, 而当鼠标左键点击左侧按钮时, 顶端的Button迅速向左侧移动;


3 QRadioButton

该按钮控件为单选按钮控件;

QPushButton同样继承自QAbstractButton;

其对应的属性有如下:

属性 说明
checkable 是否能选中
checked 是否已经被选中, 通常情况下checkablechecked的前提条件
autoExclusive 是否排他 选中一个按钮之后是否会取消其他按钮的选中 通常对于QRadioButton而言, 默认是排他的

假设存在一个Widget, 其中分别存在三个radioButton用于选择性别;

运行结果为:

可以看出选择时的排他性;


3.1 toggled 信号 选择性别并显示 (更新 Label )

通常RadioButton所使用较多的信号为toggled信号, 该信号用来判断按钮的状态是否产生变化;

对应的信号函数为:

cpp 复制代码
 void QAction::toggled(bool checked)

同样的该信号所对应的槽也存在一个bool类型的参数;

在上文中设计了一个通过RadioButton选择性别的程序, 除此之外, 可以通过选择的选项来更新对应的Label;

对三个RadioButton设置对应的槽即可;

cpp 复制代码
void Widget::on_male_toggled(bool checked)
{
    ui->label->setText("The sex is: "+ui->male->text());
    qDebug()<<ui->male->text();
}

void Widget::on_female_toggled(bool checked)
{
    ui->label->setText("The sex is: "+ui->female->text());
    qDebug()<<ui->female->text();
}

void Widget::on_other_toggled(bool checked)
{
    ui->label->setText("The sex is: "+ui->other->text());
    qDebug()<<ui->other->text();
}

每次发生状态切换时将发送toggled()信号,

其次在这段程序中, 每进行一次状态切换都会调用qDebug()来打印一次对应RadioButton中的text();

程序运行的结果为:

可以发现Label标签的text()RadioButton的选择在不断的发生更新变化;

其中这里的状态切换为checkedtrue/false, 只要进行切换都会调用对应的槽;

此处的checked值都在根据是否选中的状态变化在truefalse来回变化, 此处可以对代码进行修改, 对某个RadioButton中的checked进行判断, 若为true则发生打印, 否则不进行qDebug()打印;

cpp 复制代码
void Widget::on_male_toggled(bool checked)
{
    ui->label->setText("The sex is: "+ui->male->text());
    if(checked)
        qDebug()<<ui->male->text();
}

只对male的槽进行修改;

运行程序后结果为:

在这个运行结果中, 只对MaleFemaleRadioButton进行切换, 可以观察到, 由于Male的槽设置为对checked进行判断后再打印, 因此只在选择后打印一次, 取消选择后的状态切换, 即checked == false时不进行打印, 而Female无论是true还是false都会进行打印;


3.2 QButtonGroup - 利用 RadioButton 设计模拟点餐系统

通常在一些点餐系统中可以看到套餐中可以自行组合一些餐点;

在第二栏中可以进行单选选项从而进行组合;

而在RadioButton中对应的按钮存在一个属性为 autoExclusive, 表示排他性;

而通常情况下该属性对于RadioButton来说是默认开启的, 同时我们需要其作为一种单选选项并不希望其取消这种排他属性;

若是将该属性应用到点餐系统上则可能出现这样的状况:

如图所示;

而在Qt中存在一个ButtonGroup类, 可对按钮进行分组处理, 包括RadioButton;

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
        
    // 创建三个组
    QButtonGroup *group1 = new QButtonGroup(this);
    QButtonGroup *group2 = new QButtonGroup(this);
    QButtonGroup *group3 = new QButtonGroup(this);

    // 每个组增加对应的 RadioButton
    group1 -> addButton(ui->radioButton_Syaplefood1);
    group1 -> addButton(ui->radioButton_Syaplefood2);
    group1 -> addButton(ui->radioButton_Syaplefood3);

    group2 -> addButton(ui->radioButton_Snack1);
    group2 -> addButton(ui->radioButton_Snack2);

    group3 -> addButton(ui->radioButton_Beverage1);
    group3 -> addButton(ui->radioButton_Beverage2);
    group3 -> addButton(ui->radioButton_Beverage3);
}

通常情况下, QButtonGroup也需要在堆上创建, 并绑定对象树, 若是在栈上创建, 由于其生命周期将在构造函数结束后随着结束, 将会在程序运行后无法的对RadioButtons进行分组, 因此需要创建在堆上;

此处修改代码后运行代码结果为:


4 QCheckBox 复选框

除了具有排他属性的单选以外, 还有复选框;

Qt中的复选框通常使用QCheckBox作为复选框, 该控件与RadioButton类似, 除了无排他性以外, 其主要相关的属性即为checkablechecked;

  • 设计一个多选的程序, 通过PushButton确认来确定所选选项并显示在label中, 当所有选项选中后, 除了显示所选选项以外还需要显示"All selected."

假设需要设计一个这样的程序, 我们需要使用多个QCheckBox与一个确认按钮QPushButton以及两个标签QLabel;

其中label显示的是"What you have selected is: ", 对应的三个checkBox分别为"A"/"B"/"C", 对应的PushButton的文本则为OK;

上文已经使用QtDesigner进行了控件的基本设计, 需要在编写功能时先对样式进行初始化;

cpp 复制代码
    ui->label->setText("What you have selected is: ");
    ui->label_2->setText("");
    ui->checkBox->setText("A");
    ui->checkBox_2->setText("B");
    ui->checkBox_3->setText("C");
    ui->pushButton->setText("OK");

PushButtonclicked信号来更新label所显示的文本, 因此需要定义槽的控件为pushButton;

cpp 复制代码
void Widget::on_pushButton_clicked()
{
    QString str("What you have selected is: "); // 定义拼接前的字符串
    
    // 对字符串进行拼接
    if(ui->checkBox->isChecked()) str = str + ui->checkBox->text() + " ";
    if(ui->checkBox_2->isChecked()) str = str + ui->checkBox_2->text() + " ";
    if(ui->checkBox_3->isChecked()) str = str + ui->checkBox_3->text();

    // 将拼接完的字符串设置进Label中
    ui->label->setText(str);
    
    // 判断是否全选
    if(ui->checkBox->isChecked()&&ui->checkBox_2->isChecked()&&ui->checkBox_3->isChecked())
        ui->label_2->setText("[ All selected. ]");
    else
        ui->label_2->setText("");
}

在这段代码中, 主要判断isChecked()来判断其是否被选中, 通常这个函数能返回checked()状态, 通常为一个bool值, true则表示被选中, false则表示未被选中;

当所有check()都为true时展示另一个标签所显示的"All selected.", 否则显示为空;

运行结果为:

相关推荐
Evand J2 小时前
【MATLAB例程】基于噪声协方差自适应的互补滤波器方法vs标准互补滤波,用于融合加速度计和陀螺仪数据,估计角度
开发语言·matlab
vvw&2 小时前
如何在 Ubuntu 上安装 PostgreSQL
linux·运维·服务器·数据库·ubuntu·postgresql
熊小猿2 小时前
RabbitMQ死信交换机与延迟队列:原理、实现与最佳实践
开发语言·后端·ruby
2301_795167202 小时前
玩转Rust高级应用 如何让让运算符支持自定义类型,通过运算符重载的方式是针对自定义类型吗?
开发语言·后端·算法·安全·rust
qq_5470261792 小时前
Canal实时同步MySQL数据到Elasticsearch
数据库·mysql·elasticsearch
梦想平凡2 小时前
情怀源代码工程实践(加长版 1/3):确定性内核、事件回放与最小可运行骨架
开发语言·javascript·ecmascript
笑我归无处3 小时前
强引用、软引用、弱引用、虚引用详解
java·开发语言·jvm
02苏_3 小时前
秋招Java面
java·开发语言