控件【QT】

news2025/3/10 18:34:24

文章目录

  • 控件
  • QWidget
    • enabled
    • geometry
    • setGeometry
  • qrc
  • windowOpacity
  • QPixmap
  • font
  • toolTip
  • focusPolicy
  • styleSheet
  • QPushButton
  • Radio Buttion
  • Check Box
  • 显示类控件
  • QProgressBar
  • calendarWidget

控件

Qt中已经提供了很多内置的控件了(按钮,文本框,单选按钮,复选按钮,下拉框…)

Qt中的各种控件都是继承自Qwidget类

QWidget

enabled

API :

isEnabled() , 获取到控件的可用状态

setEnabled , 设置控件是否可使用, true表示可用,false表示禁用.

enabled : 描述了一个控件是否处于“可用”状态.

所谓“禁用”指的是该控件不能接收任何用户的输入事件,并且外观上往往是灰色的。如果一个 widget 被禁用,则该 widget 的子元素也被禁用

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public slots:
    void  handle() ;
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton * button = new QPushButton(this) ;
    button->setText("按钮");
    //将按钮设置为禁用状态
    button->setEnabled(false) ;
    //禁用和是否连接槽函数无关
    connect(button, &QPushButton::clicked ,this , &Widget::handle);

}

Widget::~Widget()
{
    delete ui;
}

void Widget::handle()
{
    qDebug() <<"handle";
}


切换第一个按钮的禁用状态

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

    void on_pushButton_enable_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

Widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

//槽函数
void Widget::on_pushButton_clicked()
{
       qDebug() <<"执行了槽函数";
}

void Widget::on_pushButton_enable_clicked()
{
    //切换第一个按钮的禁用状态
  bool enable=   ui->pushButton->isEnabled();
  if(enable == true)
  {
       ui->pushButton->setEnabled(false) ;
  }
  else
  {
      //禁用
      ui->pushButton->setEnabled(true) ;
  }
}

geometry

API:

geometry ,获取到控件的位置和尺寸.返回结果是一个QRect,包含了x, y, width, height.其中x, y是左上角的坐标.

geometry视为是四个属性(x,y,width,height)的统称

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

geometry(),获取到控件的位置和尺寸.返回结果是一个QRect,包含了x, y, width, height.其中x, y是左上角的坐标.

例如:

setGeometry

move只是修改位置

setGeometry既可以修改位置,又可以修改尺寸

setGeometry(QRect) , 设置控件的位置和尺寸。可以直接设置一个QRect,也可以分四个属性单独设置。
setGeometry(int x, int y, int width, int height)

例如 : 平移一个按钮

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
   // void on_pushButton_clicked();


    void on_pushButton_up_clicked();

    void on_pushButton_down_clicked();



    void on_pushButton_left_clicked();

    void on_pushButton_right_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_up_clicked()
{
    //获取target本身的geometry
             QRect rect     =  ui->pushButton_target->geometry();
            qDebug() <<rect ;
//            //将y-5
//            rect.setY(rect.y() -5);
//             ui->pushButton_target->setGeometry(rect);


             //平移
               ui->pushButton_target->setGeometry(rect.x() , rect.y()-5 ,rect.width(),rect.height() );

}

void Widget::on_pushButton_down_clicked()
{
    //获取target本身的geometry
             QRect rect     =  ui->pushButton_target->geometry();
            qDebug() <<rect ;
//            //将y-5
//            rect.setY(rect.y() +5);
//            ui->pushButton_target->setGeometry(rect);



            //平移
              ui->pushButton_target->setGeometry(rect.x() , rect.y()+5 ,rect.width(),rect.height() );
}

void Widget::on_pushButton_left_clicked()
{
    //获取target本身的geometry
             QRect rect     =  ui->pushButton_target->geometry();
            qDebug() <<rect ;
//            //将x-5
//            rect.setX(rect.x() -5);
//            ui->pushButton_target->setGeometry(rect);


            //平移
              ui->pushButton_target->setGeometry(rect.x()-5 , rect.y() ,rect.width(),rect.height() );


}

void Widget::on_pushButton_right_clicked()
{
    //获取target本身的geometry
             QRect rect     =  ui->pushButton_target->geometry();
            qDebug() <<rect ;
//            //将x+5
//            rect.setX(rect.x() +5);
//            ui->pushButton_target->setGeometry(rect);

            //平移
              ui->pushButton_target->setGeometry(rect.x()+5 , rect.y() ,rect.width(),rect.height() );
}

label 的使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

widget.h :

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_accepted_clicked();

    void on_pushButton_reject_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp :

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    srand(time(nullptr));
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_accepted_clicked()
{
        ui->label->setText("是");

}

//鼠标点击后触发
void Widget::on_pushButton_reject_clicked()
{


}


//鼠标按下就触发
void Widget::on_pushButton_reject_pressed()
{
    ui->label->setText("否");

    //获取到当前程序窗口的尺寸
      int  width =this->geometry().width();
      int  height =  this->geometry().height();
    //重新生成按钮的位置
     int x = rand()%width;
      int y = rand()%height;
    //移动按钮的位置
      ui->pushButton_reject->move(x,y);
}


window frame:

如果 widget 作为一个窗口(带有标题栏,最小化,最大化,关闭按钮),那么在计算尺寸和坐标的时候就有两种算法,包含 window frame 和不包含 window frame。 其中 x(), y(), frameGeometry(), pos(), move() setFrameGeometry()都是按照包含 window frame 的方式来计算的。

其中 geometry(), width(), height(), rect(), size() setGeometry() 则是按照不包含 window frame 的方式来计算的。 当然,如果一个不是作为窗口的 widget,上述两类方式得到的结果是一致的

例如:

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);



   QPushButton * mybutton = new QPushButton(this) ;
   mybutton->setText("按钮");
   mybutton->move(100,100) ;
   connect(mybutton , &QPushButton::clicked ,this , &Widget::handle );

}

Widget::~Widget()
{
    delete ui;
}

void Widget::handle()
{
    QRect  rect1 =  this->geometry();
    QRect  rect2 =  this->frameGeometry();
    qDebug() <<rect1;
     qDebug() <<rect2;
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public slots:
    void handle () ;
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

API :

windowTitle () ,获取到控件的窗口标题

setWindowTitle (const Qstring& title) , 设置控件的窗口标题

windowTitle属性,只能针对顶层窗口这样的QWidget才有效

例如:

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("这是窗口标题");
     QPushButton * button = new QPushButton(this) ;
     button->setText("按钮");

}

Widget::~Widget()
{
    delete ui;
}

API:

windowlcon : 获取到控件的窗口图标.返囱Qlcon对象

setWindowlcon(const Qlcon& icon) 设置控件的窗口图标.

这两个 api类似于windowTitle只能针对顶层窗口使用

例如:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QIcon>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置图标
    //通过绝对路径访问
    QIcon icon("D:/rose/rose-flower-pictures-beautiful-roses-love-rose-flower-beautiful-flowers-wallpapers-ai-generated-free-photo.jpg") ;
    this->setWindowIcon(icon) ;

}

Widget::~Widget()
{
    delete ui;
}


qrc

qrc机制:

给 Qt 项目引入一个额外的 xml 文件(后缀名使用 .qrc 表示)
在这个 xml 中把要使用的图片资源给导入进来,并且在 xml 中进行记录。
Qt 在编译项目的时候,就会根据 qrc 中描述的图片信息,找到图片内容,并且提取出图片的二进制数据,把这些二进制数据转成 C++ 代码,最终编译到 .exe 里。

qrc 缺点:无法导入太大的资源文件

qrc机制,解决两个问题:

  1. 确保你的图片所在的路径在目标用户机器上存在。
  2. 确保你的图片不会被用户搞没了

qrc使用方式

1.在项目中创建一个qrc 文件,文件名不要带中文和特殊符号.

2把图片导入到qrc文件中

2.1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将prefix的前缀改成/即可

2.2 把刚才使用rose.jpg这个图片给导入到资源文件中.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意:导入图片时,需要确保导入的图片必须在resource.qrc 文件的同级目录,或者同级目录中的子目录

把需要的图片拷贝到resource.qrc 文件的同级目录,或者同级目录中的子目录

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

当代码中需要访问qrc 中管理的文件时,就需要在路径上带有:前缀

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QIcon>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置图标
    //访问qrc
    //前缀 + 文件名 ,前缀就是:
    QIcon icon(":rose/rose.jpg") ;
    this->setWindowIcon(icon) ;

}

Widget::~Widget()
{
    delete ui;
}




外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

windowOpacity

windowOpacity() , 获取到控件的不透明数值.返回float,取值为0.0 ->1.0其中0.0表示全透明,1.0表示完全不透明

setWindowOpacity(float n) , 设置控件的不透明值

例如;

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_add_clicked()
{
    //增加透明度
    float opacity =this->windowOpacity();
    if(opacity >=1.0)
    {
        return ;
    }
    opacity += 0.1;
    this->setWindowOpacity(opacity) ;
}

void Widget::on_pushButton_sub_clicked()
{
    //减少透明度
    float opacity =this->windowOpacity();
    if(opacity <=0.0)
    {
        return ;
    }
    opacity -= 0.1;
    this->setWindowOpacity(opacity) ;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_add_clicked();

    void on_pushButton_sub_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

2.7 cursor

API说明
cursor()获取到当前 widget 的 cursor 属性,返回 QCursor 对象。当鼠标悬停在该 widget 上时,就会显示出对应的形状。
setCursor(const QCursor& cursor)设置该 widget 光标的形状,仅在鼠标停留在该 widget 上时生效。
QGuiApplication::setOverrideCursor(const QCursor& cursor)设置全局光标的形状,对整个程序中的所有 widget 都会生效,覆盖上面的 setCursor 设置的内容。

setOverrideCursor: 设置全局光标(程序内的全局,而不是系统级别的全局

cursor() ,setCursor()widget级别的,一个界面中,不同的控件可以设成不同的光标

代码示例:在 Qt Designer 中设置按钮的光标

  1. 在界面中创建一个按钮

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QCursor>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QCursor cursor (Qt::WaitCursor) ;
    ui->pushButton->setCursor(cursor) ;
    // this->setCursor(cursor);
}

Widget::~Widget()
{
    delete ui;
}


QPixmap

Qt允许我们通过自定义的图片来设置光标

QPixmap通过这个对象就表示一个图片

1、先准备一个图片,把图导入到项目中(qrc管理)
2、代码中访问到这个图片,基于这个图片构造出光标对象并设置

例如:

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPixmap>
#include<QCursor>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //访问图片中文件
    QPixmap pixmap (":/dragon.jpg");
    //构造光标对象
    QCursor cursor(pixmap ,10,10) ;

    //设置光标
    this->setCursor(cursor) ;
}

Widget::~Widget()
{
    delete ui;
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

font

API说明
font()获取当前 widget 的字体信息,返回 QFont 对象。
setFont(const QFont& font)设置当前 widget 的字体信息。

关于 QFont

属性说明
family字体家族,比如 “楷体”, “宋体”, “微软雅黑” 等。
pointSize字体大小。
weight字体粗细,以数值方式表示粗细程度,取值范围为 [0, 99],数值越大,越粗。
bold是否加粗。设置为 true,相当于 weight 为 75。设置为 false 相当于 weight 为 50。
italic是否倾斜。
underline是否带有下划线。
strikeOut是否带有删除线。

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QLabel>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QLabel * label = new QLabel(this) ;
    label->setText("文本");

    //创建字体对象
    QFont font;
    font.setFamily("仿宋");
    font.setPixelSize(30) ;
    font.setBold(true) ;

     font.setItalic(true) ;
      font.setUnderline(true) ;
       font.setStrikeOut(true) ;

       //把font 对象设置到label中
       label->setFont(font) ;

}

Widget::~Widget()
{
    delete ui;
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

toolTip

2.9 toolTip

API说明
setToolTip设置提示内容。鼠标悬停在该 widget 上时会有提示说明。
setToolTipDuration设置 toolTip 提示的时间,单位 ms。时间到后 toolTip 自动消失。

toolTip 只是给用户看的,在代码中一般不需要获取到 toolTip。

代码示例:设置按钮的 toolTip

  1. 在界面上拖放两个按钮,objectName 设置为 pushButton_yes 和 pushButton_no

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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



private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->pushButton_yes->setToolTip("这是一个yes按钮");
      ui->pushButton_yes->setToolTipDuration(3000);
      ui->pushButton_no->setToolTip("这是一个no按钮");
        ui->pushButton_no->setToolTipDuration(7000);
}

Widget::~Widget()
{
    delete ui;
}



focusPolicy

设置控件获取到焦点的策略。比如某个控件能否用鼠标选中或者能否通过tab键选中

所谓“焦点”,指的就是能选中这个元素。接下来的操作(比如键盘操作),就都是针对该焦点元素进行的了。这个对于输入框,单选框,复选框等控件非常有用。

—般来说一个控件获取到焦点,主要是两种方式

1.鼠标点击
2.键盘的tab

API说明
focusPolicy()获取该 widget 的 focusPolicy,返回 Qt::FocusPolicy
setFocusPolicy(Qt::FocusPolicy policy)设置 widget 的 focusPolicy。

Qt::FocusPolicy 是一个枚举类型,取值如下:

  • Qt::NoFocus:控件不会接收键盘焦点
  • Qt::TabFocus:控件可以通过 Tab 键接收焦点
  • Qt::ClickFocus:控件在鼠标点击时接收焦点
  • Qt::StrongFocus:控件可以通过 Tab 键和鼠标点击接收焦点(默认值)
  • Qt::WheelFocus:类似于 Qt::StrongFocus,同时控件也通过鼠标滚轮获取到焦点(新增的选项,一般很少使用)。

代码示例:理解不同的 focusPolicy

  1. 在界面上创建四个单行输入框(Line Edit)

styleSheet

通过 CSS 设置 widget 的样式。

CSS (Cascading Style Sheets 层叠样式表) 本身属于网页前端技术,主要就是用来描述界面的样式。所谓 “样式”,包括不限于大小、位置、颜色、间距、字体、背景、边框等。我们平时看到的丰富多彩的网页,就都会用到大量的 CSS。

Qt 虽然是做 GUI 开发,但实际上和网页前端有很多异曲同工之处。因此 Qt 也引入了对于 CSS 的支持。

CSS 中可以设置的样式属性非常多,基于这些属性 Qt 只能支持其中一部分,称为 QSS (Qt Style Sheet)。具体的支持情况可以参考 Qt 文档中 “Qt Style Sheets Reference” 章节。

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPlainTextEdit>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_light_clicked()
{
    // 设置窗口的样式
  this->setStyleSheet("background-color: rgb(240,240,240);");
    // 设置输入框的样式
    ui->plainTextEdit->setStyleSheet("background-color: white; color: black;");
    // 设置按钮的样式
    ui->pushButton_light->setStyleSheet("color: black;");
    ui->pushButton_dark->setStyleSheet("color: black;");
}

void Widget::on_pushButton_dark_clicked()
{
    // 设置窗口的样式
    this->setStyleSheet("background-color: black;");
    // 设置输入框的样式
    ui->plainTextEdit->setStyleSheet("background-color: black; color: white;");
    // 设置按钮的样式
    ui->pushButton_light->setStyleSheet("color: white;");
    ui->pushButton_dark->setStyleSheet("color: white;");
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_light_clicked();

    void on_pushButton_dark_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

QPushButton

属性说明
text按钮中的文本
icon按钮中的图标
iconSize按钮中图标的尺寸
shortCut按钮对应的快捷键
autoRepeat按钮是否会重复触发。当鼠标左键按住不放时,如果设为true,则会持续产生鼠标点击事件;如果设为false,则必须释放鼠标,再次按下鼠标时才能产生点击事件。(相当于游戏手柄上的"连发"效果)
autoRepeatDelay重复触发的延时时间。按住按钮多久之后,开始重复触发。
autoRepeatInterval重复触发的周期。

给按钮设置图标

1 、 使用qrc添加图片

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建图标对象
    QIcon icon(":/doge.png");

    //设置图标
    ui->pushButton->setIcon(icon) ;
    //设置图标尺寸
     ui->pushButton->setIconSize(QSize(50,50)) ;
}

Widget::~Widget()
{
    delete ui;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

实现带有快捷键的按钮

1、创建qrc 文件,导入资源

2、编辑ui文件,创建界面

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //设置这些按钮的图标
    ui->pushButton_target->setIcon(QIcon(":/image/doge.png"));

    ui->pushButton_target->setIconSize(QSize(120, 120));

    ui->pushButton_up->setIcon(QIcon(":/image/up.png"));
    ui->pushButton_up->setIconSize(QSize(50, 50));

    ui->pushButton_down->setIcon(QIcon(":/image/down.png"));
    ui->pushButton_down->setIconSize(QSize(50, 50));

    ui->pushButton_left->setIcon(QIcon(":/image/left.png"));
    ui->pushButton_left->setIconSize(QSize(50, 50));

    ui->pushButton_right->setIcon(QIcon(":/image/right.png"));
    ui->pushButton_right->setIconSize(QSize(50, 50));

//    //第一种写法设置快捷键

//    ui->pushButton_up->setShortcut(QKeySequence("w"));
//    ui->pushButton_down->setShortcut(QKeySequence("s"));
//    ui->pushButton_left->setShortcut(QKeySequence("a"));
//    ui->pushButton_right->setShortcut(QKeySequence("d"));



    //第二种写法(推荐): 还可以通过按键的枚举来设置按键快捷键。
    ui->pushButton_up->setShortcut(QKeySequence(Qt::Key_W));
    ui->pushButton_down->setShortcut(QKeySequence(Qt::Key_S));
    ui->pushButton_left->setShortcut(QKeySequence(Qt::Key_A));
    ui->pushButton_right->setShortcut(QKeySequence(Qt::Key_D));
    
    //组合键
    //ui->pushButton_up->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W));
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_up_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x(), rect.y() - 5,rect.width(), rect.height());
}

void Widget::on_pushButton_down_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5,rect.width(), rect.height());
}


void Widget::on_pushButton_right_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x() +5, rect.y() ,rect.width(), rect.height());
}


void Widget::on_pushButton_left_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x() -5, rect.y() ,rect.width(), rect.height());
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_up_clicked();

    void on_pushButton_left_clicked();

    void on_pushButton_right_clicked();

    void on_pushButton_down_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

自动连发

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //设置这些按钮的图标
    ui->pushButton_target->setIcon(QIcon(":/image/doge.png"));

    ui->pushButton_target->setIconSize(QSize(120, 120));

    ui->pushButton_up->setIcon(QIcon(":/image/up.png"));
    ui->pushButton_up->setIconSize(QSize(50, 50));

    ui->pushButton_down->setIcon(QIcon(":/image/down.png"));
    ui->pushButton_down->setIconSize(QSize(50, 50));

    ui->pushButton_left->setIcon(QIcon(":/image/left.png"));
    ui->pushButton_left->setIconSize(QSize(50, 50));

    ui->pushButton_right->setIcon(QIcon(":/image/right.png"));
    ui->pushButton_right->setIconSize(QSize(50, 50));

//    //第一种写法设置快捷键

//    ui->pushButton_up->setShortcut(QKeySequence("w"));
//    ui->pushButton_down->setShortcut(QKeySequence("s"));
//    ui->pushButton_left->setShortcut(QKeySequence("a"));
//    ui->pushButton_right->setShortcut(QKeySequence("d"));



    //第二种写法(推荐): 还可以通过按键的枚举来设置按键快捷键。
   // ui->pushButton_up->setShortcut(QKeySequence(Qt::Key_W));
    ui->pushButton_down->setShortcut(QKeySequence(Qt::Key_S));
    ui->pushButton_left->setShortcut(QKeySequence(Qt::Key_A));
    ui->pushButton_right->setShortcut(QKeySequence(Qt::Key_D));

    //组合键
    ui->pushButton_up->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W));




    // 开启鼠标点击的连发功能(键盘的连发默认就是支持的)
    ui->pushButton_up->setAutoRepeat(true);
    ui->pushButton_down->setAutoRepeat(true);
    ui->pushButton_left->setAutoRepeat(true);
    ui->pushButton_right->setAutoRepeat(true);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_up_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x(), rect.y() - 5,rect.width(), rect.height());
}

void Widget::on_pushButton_down_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5,rect.width(), rect.height());
}


void Widget::on_pushButton_right_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x() +5, rect.y() ,rect.width(), rect.height());
}


void Widget::on_pushButton_left_clicked()
{
    //获取target的位置
  QRect rect = ui->pushButton_target->geometry();

    //修改位置
    ui->pushButton_target->setGeometry(rect.x() -5, rect.y() ,rect.width(), rect.height());
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_up_clicked();

    void on_pushButton_left_clicked();

    void on_pushButton_right_clicked();

    void on_pushButton_down_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

Radio Buttion

QRadioButton 是单选按钮 作为QAbstractButton 和 QWidget 的⼦类, 上⾯介绍的属性和⽤法,对于QRadioButton
同样适⽤

属性说明
checkable是否能选中
checked是否已经被选中。checkable 是 checked 的前提条件。
autoExclusive是否排他。选中一个按钮之后是否会取消其他按钮的选中。对于 QRadioButton 来说默认就是排他的。

例如:

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->radioButton_male->setChecked(true) ;
    ui->label->setText("您选择的性别为:其他");
       ui->radioButton_other->setChecked(false) ;


//        //禁用其他选项,setCheckable只是能够让按钮不被选中.仍然是可以响应点击事件
//       ui->radioButton_other->setCheckable(false) ;

//        //第一种写法:
//       ui->radioButton_other->setEnabled(false) ;


               //第二种写法:
              ui->radioButton_other->setCheckable(false) ;
              ui->radioButton_other->setDisabled(true);

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_radioButton_male_clicked()
{
    //把界面上的 label 的内容进行更新
     ui->label->setText("您选择的性别为:男");
}

void Widget::on_radioButton_female_clicked()
{
    //把界面上的 label 的内容进行更新
     ui->label->setText("您选择的性别为:女");
}

void Widget::on_radioButton_other_clicked()
{
    //把界面上的 label 的内容进行更新
     ui->label->setText("您选择的性别为:其他");
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_radioButton_male_clicked();

    void on_radioButton_female_clicked();

    void on_radioButton_other_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

• clicked 是⼀次⿏标按下+⿏标释放触发的.
• pressed 是⿏标按下触发的.
• released 是⿏标释放触发的.
• toggled 是 checked 属性改变时触发的
总的来说,toggled是最适合 QRadioButton 的

例如:

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_radioButton_clicked(bool checked)
{
    //此处从checked就表示了当前radioButton的选中状态.
            qDebug() << "clicked: " << checked;

}



void Widget::on_radioButton_2_pressed()
{
      qDebug() << "pressed: " ;
}

void Widget::on_radioButton_3_released()
{
     qDebug() << "released: " ;
}

void Widget::on_radioButton_4_toggled(bool checked)
{
  // checked 状态发生改变,就会触发这个信号
            qDebug() << "toggled: " << checked;

}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_radioButton_clicked(bool checked);



    void on_radioButton_2_pressed();

    void on_radioButton_3_released();

    void on_radioButton_4_toggled(bool checked);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

每⼀组内部来控制排他, 但是组和组之间不能排他

例如:

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QButtonGroup>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //使用 QButtonGroup对单选按钮进行分组
    QButtonGroup* group1 = new QButtonGroup(this);
    QButtonGroup* group2 = new QButtonGroup(this);
    QButtonGroup* group3 = new QButtonGroup(this);

    // 把上述单选按钮,放到不同的组里。
    group1->addButton(ui->radioButton);
    group1->addButton(ui->radioButton_2);
    group1->addButton(ui->radioButton_3);

    group2->addButton(ui->radioButton_4);
    group2->addButton(ui->radioButton_5);
    group2->addButton(ui->radioButton_6);

    group3->addButton(ui->radioButton_7);
    group3->addButton(ui->radioButton_8);
}

Widget::~Widget()
{
    delete ui;
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

Check Box

QCheckBox 表⽰复选按钮.

可以允许选中多个和QCheckBox 最相关的属性也是 checkable 和 checked ,都是继承⾃QAbstractButton .
⾄于 QCheckBox 独有的属性 tristate ⽤来实现 “三态复选框”

在界⾯上创建?三个复选按钮,?和⼀个普通按钮

例如:

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_clicked()
{
    QString result = "今天你的安排是:";
    if (ui->checkBox_study->isChecked()) {
        result += ui->checkBox_study->text() + " ";
    }
    if (ui->checkBox_game->isChecked()) {
        result += ui->checkBox_game->text() + " ";
    }
    if (ui->checkBox_work->isChecked()) {
        result += ui->checkBox_work->text();
    }
    ui->label->setText(result);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

显示类控件

QLabel 可以⽤来显⽰⽂本和图⽚
核⼼属性如下

  • textQLabel 中的文本。
  • textFormat:文本的格式。
    • Qt::PlainText:纯文本。
    • Qt::RichText:富文本(支持 HTML 标签)。
    • Qt::MarkdownText:Markdown 格式。
    • Qt::AutoText:根据文本内容自动决定文本格式。
  • pixmapQLabel 内部包含的图片。
  • scaledContents:设为 true 表示内容自动拉伸填充 QLabel,设为 false 则不会自动拉伸。
  • alignment:对齐方式。可以设置水平和垂直方向如何对齐。
  • wordWrap:设为 true 内部的文本会自动换行,设为 false 则内部文本不会自动换行。
  • indent:设置文本缩进,水平和垂直方向都生效。
  • margin:内部文本和边框之间的边距。不同于 indentmargin 是上下左右四个方向都同时有效,而 indent 最多只是两个方向有效(具体哪两个方向有效取决于 alignment)。
  • openExternalLinks:是否允许打开一个外部的链接。(当 QLabel 文本内容包含 URL 的时候涉及到)
  • buddy:给 QLabel 关联一个“伙伴”,这样点击 QLabel 时就能激活对应的伙伴。例如伙伴如果是一个 QCheckBox,那么该 QCheckBox 就会被选中。

widget.cpp:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //纯文本
    ui->label->setTextFormat(Qt::PlainText) ;
    ui->label->setText("<b>这是一段纯文本<b>") ;
    //富文本

    ui->label_2->setTextFormat(Qt::RichText) ;
    //  <b> 标签:让文本加粗
    ui->label_2->setText("<b>这是一段富文本</b>") ;

    //markdown 文本


    ui->label_3->setTextFormat(Qt::MarkdownText) ;
    ui->label_3->setText("#这是一段markdown文本") ;
}

Widget::~Widget()
{
    delete ui;
}



widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

标签加到纯文本中,只是被当成了单纯的文本没有进行任何的渲染操作

在纯文本中,#只是被单纯的当成了"文本"

在markdown中,#则是一级标题了

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //将QLabel 设置成和窗口一样大,并且把这个 QLabel左上角设置到窗口的左上角这里
    QRect windowRect = this->geometry();
    ui->label->setGeometry(0,0,windowRect.width(), windowRect.height());
    QPixmap pixmap( ":/dragon.jpg");
    ui->label->setPixmap(pixmap ) ;
    //将qrc图片与窗口大小保持一致
    ui->label->setScaledContents(true) ;
}

Widget::~Widget()
{
    delete ui;
}

在上面代码中是在构造函数里,进行的尺寸设置,这个尺寸设置相当于是"一次性的"

一旦程序运行起来之后,QLabel的尺寸就固定下来了.窗口发生改变,此时,QLabel是不会变化的

如果需要将图片与窗口实现同步拉伸:

解决方案:

可以让 Widget窗口类,重写父类(QWidget)的resizeEvent虚函数

widget.cpp

让Widget窗口类,重写父类(QWidget)的resizeEvent虚函数

在鼠标拖动窗口尺寸中,在这个过程中 ,resizeEvent函数会被反复调用执行

每次触发一个resizeEvent事件都会调用一次对应的虚函数

因为进行了函数重写,调用父类的虚函数就会调用子类对应的函数

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<QResizeEvent>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //将QLabel 设置成和窗口一样大,并且把这个 QLabel左上角设置到窗口的左上角这里
    QRect windowRect = this->geometry();
    ui->label->setGeometry(0,0,windowRect.width(), windowRect.height());
    QPixmap pixmap( ":/dragon.jpg");
    ui->label->setPixmap(pixmap ) ;
    //将qrc图片与窗口大小保持一致
    ui->label->setScaledContents(true) ;
}

Widget::~Widget()
{
    delete ui;
}
//重写父类(QWidget)的resizeEvent虚函数,将图片与窗口实现同步拉伸

//此处的形参event,包含了触发这个resize事件这一时刻,窗口的尺寸的数值
void Widget::resizeEvent(QResizeEvent *event)
{
    //qDebug() <<event->size() ;
    ui->label->setGeometry(0,0,event->size().width(), event->size().height());
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void resizeEvent(QResizeEvent * event);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

事件:

用户的操作,会对应一些信号,Qt中,表示用户的操作,有两类概念,一个是信号,另一个是事件

当用户拖拽修改窗口大小的时候,就会触发resize事件(resizeEvent)

像resize这样的事件,是连续变化的.把窗口尺寸从A拖到B这个过程中,会触发出一系列的resizeEvent

在实际编程中,指定回调函数其实有很多种写法

  1. 设置函数指针
  2. 设置仿函数(函数对象)
  3. 设置 lambda
  4. 通过重写父类虚函数(框架中拿着父类的指针调用这个函数。如果你创建了子类重写了这个函数,此时在多态机制下,实际执行的就是子类的函数了)
  5. Qt 的信号槽

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->label->setText("这是一段文本");
    //| :按位或
    ui->label->setAlignment(Qt::AlignHCenter |Qt::AlignVCenter );//水平居中对齐,垂直居中对齐

    ui->label_2->setText("这是一段文本");
    //| :按位或
    ui->label_2->setAlignment(Qt::AlignRight |Qt::AlignVCenter );//水平向右对齐,垂直居中对齐

    ui->label_3->setText("这是一段文本");
    //| :按位或
    ui->label_3->setAlignment(Qt::AlignRight |Qt::AlignTop );//水平向右对齐,垂直向上对齐



}

Widget::~Widget()
{
    delete ui;
}


wigdet.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

实现自动换行

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


    //设置自动换行
    ui->label->setText("这是一段文本这是一段文本这是一段文本这是一段文本这是一段文本这是一段文本这是一段文本这是一段文本");
    ui->label->setWordWrap(true);



}

Widget::~Widget()
{
    delete ui;
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

设置缩进,设置的缩进即使文本换行了,后续的行也会产生缩进,不仅仅是首行缩进

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


      //设置缩进
    ui->label->setText("这是一段文本");//设置的缩进即使文本换行了,后续的行也会产生缩进,不仅仅是首行缩进
    ui->label->setIndent(50) ;
	   ui->label->setMargin(100) ;  //设置边距

}

Widget::~Widget()
{
    delete ui;
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

&A , 通过键盘上的alt +a 来触发这个快捷键

&B , 通过键盘上的alt +B 来触发这个快捷键

绑定伙伴关系后,通过快捷键可以选中对应的单选按钮/复选按钮

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
   //设置label和radiobutton 的伙伴关系
    
    ui->label->setBuddy(ui->radioButton) ;
     ui->label_2->setBuddy(ui->radioButton_2) ;
}

Widget::~Widget()
{
    delete ui;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

使用QLCDNumber 实现一个倒计时,从0开始,到100结束

通过QTimer 这个类创建对象, 就会产生一个timeout这样的信号

通过start方法来开启定时器,并且参数中设定触发timeout 信号的周期

结合connect,将timeout信号绑定到对应的槽函数中 ,即可修改LCDNumber中的数字

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->lcdNumber->display("10");
   timer =  new QTimer(this) ;

    //将timeout与槽函数handle 连接
    connect(timer, &QTimer::timeout , this , &Widget::handle);
       timer->start(1000) ;
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handle()
{
  int value = ui->lcdNumber->intValue();
  if(value <=0)
  {
      timer->stop();
      return ;
  }
   ui->lcdNumber->display(value -1);
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
       void  handle() ;
private:
    Ui::Widget *ui;
    QTimer * timer ;
};
#endif // WIDGET_H

请看下面的一段代码

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<thread>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    int value  = ui->lcdNumber->intValue();
    while(true)
    {
        //先休眠1s
        std::this_thread::sleep_for(std::chrono::seconds(1)) ;

        if(value <=0)
        {
            break;
        }
        value-= 1 ;
        ui->lcdNumber->display(value);

    }
}

Widget::~Widget()
{
    delete ui;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H


上述代码中出现了问题: 需要等待10s,才能出现结果

问题原因:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解决方案:

在构造函数中,另外创建一个线程,在新的线程中,执行上述循环+更新操作

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<thread>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    
    
    //在构造函数中,另外创建一个线程,在新的线程中,执行上述循环+更新操作
    //这样写出现了问题:terminate called without an active exception
   
    std::thread t (  [this] ()
    {
         int value  = ui->lcdNumber->intValue();
            while(true)
            {
                //先休眠1s
                std::this_thread::sleep_for(std::chrono::seconds(1)) ;

                if(value <=0)
                {
                    break;
                }
                value-= 1 ;
                ui->lcdNumber->display(value);

            }
    }) ;



}

Widget::~Widget()
{
    delete ui;
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

上述解决方案是不可行的

问题原因:Qt里,界面有一个专门的线程去负责维护更新的(主线程), 主线程就是main函数所在的线程

对于GUI来说,,内部包含了很多的隐藏状态,Qt为了保证修改界面的过程中,不会因为线程安全受到影响, Qt禁止了其他线程直接修改界面.

   ui->lcdNumber->display(value);//这段代码 ,属于其他线程直接修改界面

因此Qt为了确保线程安全,要求所有的对界面的修改操作,必须在主线程中完成

对于Qt的槽函数来说,默认情况下,槽函数都是由主线程调用的.在槽函数中修改界面是没有任何问题的

QProgressBar

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

QProgressBar::chunk {background-color:red;}

QProgressBar::chunk : 选择器,设置的样式,到底要针对哪个控件生效

calendarWidget

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_calendarWidget_selectionChanged();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_calendarWidget_selectionChanged()
{
    QDate date =  ui->calendarWidget->selectedDate();
    qDebug() <<date;

    ui->label->setText(date.toString());

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2293509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 串口发送与接收

接线图 代码配置 根据上一章发送的代码配置&#xff0c;在GPIO配置的基础上需要再配置PA10引脚做RX接收&#xff0c;引脚模式可以选择浮空输入或者上拉输入&#xff0c;在USART配置串口模式里加上RX模式。 配置中断 //配置中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE…

【Unity2D 2022:UI】创建滚动视图

一、创建Scroll View游戏对象 在Canvas画布下新建Scroll View游戏对象 二、为Content游戏对象添加Grid Layout Group&#xff08;网格布局组&#xff09;组件 选中Content游戏物体&#xff0c;点击Add Competent添加组件&#xff0c;搜索Grid Layout Group组件 三、调整Grid La…

Python sider-ai-api库 — 访问Claude、llama、ChatGPT、gemini、o1等大模型API

目前国内少有调用ChatGPT、Claude、Gemini等国外大模型API的库。 Python库sider_ai_api 提供了调用这些大模型的一个完整解决方案&#xff0c; 使得开发者能调用 sider.ai 的API&#xff0c;实现大模型的访问。 Sider是谷歌浏览器和Edge的插件&#xff0c;能调用ChatGPT、Clau…

密云生活的初体验

【】在《岁末随笔之碎碎念》里&#xff0c;我通告了自己搬新家的事情。乙巳年开始&#xff0c;我慢慢与大家分享自己买房装修以及在新家的居住体验等情况。 跳过买房装修的内容&#xff0c;今天先说说这三个月的生活体验。 【白河】 潮白河是海河水系五大河之一&#xff0c;贯穿…

Leetcode - 周赛434

目录 一、3432. 统计元素和差值为偶数的分区方案二、3433. 统计用户被提及情况三、3434. 子数组操作后的最大频率四、3435. 最短公共超序列的字母出现频率 一、3432. 统计元素和差值为偶数的分区方案 题目链接 本题可以直接模拟&#xff0c;这里再介绍一个数学做法&#xff0…

C32.【C++ Cont】静态实现双向链表及STL库的list

目录 1.知识回顾 2.静态实现演示图 3.静态实现代码 1.初始双向链表 2.头插 3.遍历链表 4.查找某个值 4.任意位置之后插入元素 5.任意位置之前插入元素 6.删除任意位置的元素 4.STL库的list 1.知识回顾 96.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删 97.【C…

记录一次-Rancher通过UI-Create Custom- RKE2的BUG

一、下游集群 当你的下游集群使用Mysql外部数据库时&#xff0c;会报错&#xff1a; **他会检查ETCD。 但因为用的是Mysql外部数据库&#xff0c;这个就太奇怪了&#xff0c;而且这个检测不过&#xff0c;集群是咩办法被管理的。 二、如果不选择etcd,就选择控制面。 在rke2-…

51单片机入门_05_LED闪烁(常用的延时方法:软件延时、定时器延时;while循环;unsigned char 可以表示的数字是0~255)

本篇介绍编程实现LED灯闪烁&#xff0c;需要学到一些新的C语言知识。由于单片机执行的速度是非常快的&#xff0c;如果不进行延时的话&#xff0c;人眼是无法识别(停留时间要大于20ms)出LED灯是否在闪烁所以需要学习如何实现软件延时。另外IO口与一个字节位的数据对应关系。 文…

99.20 金融难点通俗解释:中药配方比喻马科维茨资产组合模型(MPT)

目录 0. 承前1. 核心知识点拆解2. 中药搭配比喻方案分析2.1 比喻的合理性 3. 通俗易懂的解释3.1 以中药房为例3.2 配方原理 4. 实际应用举例4.1 基础配方示例4.2 效果说明 5. 注意事项5.1 个性化配置5.2 定期调整 6. 总结7. 代码实现 0. 承前 本文主旨&#xff1a; 本文通过中…

6 [新一代Github投毒针对网络安全人员钓鱼]

0x01 前言 在Github上APT组织“海莲花”发布存在后门的提权BOF&#xff0c;通过该项目针对网络安全从业人员进行钓鱼。不过其实早在几年前就已经有人对Visual Studio项目恶意利用进行过研究&#xff0c;所以投毒的手法也不算是新的技术。但这次国内有大量的安全从业者转发该钓…

MYSQL面试题总结(题目来源JavaGuide)

MYSQL基础架构 问题1&#xff1a;一条 SQL语句在MySQL中的执行过程 1. 解析阶段 (Parsing) 查询分析&#xff1a;当用户提交一个 SQL 语句时&#xff0c;MySQL 首先会对语句进行解析。这个过程会检查语法是否正确&#xff0c;确保 SQL 语句符合 MySQL 的语法规则。如果发现…

redis实际开发应用简单实现

短信登录 首先来看看登录与注册常规实现流程如下&#xff1a; 其中&#xff0c;很多网站都有手机号验证码登录功能 如百度 实现之前咱可以来验证码有啥特点&#xff1a;一定时间内过期、验证码随机、与手机号会唯一匹配 所以可以使用redis的string来实现更容易&#xff0c;k…

Hive on Spark优化

文章目录 第1章集群环境概述1.1 集群配置概述1.2 集群规划概述 第2章 Yarn配置2.1 Yarn配置说明2.2 Yarn配置实操 第3章 Spark配置3.1 Executor配置说明3.1.1 Executor CPU核数配置3.1.2 Executor内存配置3.1.3 Executor个数配置 3.2 Driver配置说明3.3 Spark配置实操 第4章 Hi…

【实践案例】基于大语言模型的海龟汤游戏

文章目录 项目背景提示词构建海龟汤主持人真相判断专家 具体实现流程文心一言大语言模型“海龟汤”插件参考 项目背景 “海龟汤”作为一种聚会类桌游&#xff0c;又称情境推理游戏&#xff0c;是一种猜测情境还原事件真相的智力游戏。其玩法是由出题者提出一个难以理解的事件&…

创建前端项目的方法

目录 一、创建前端项目的方法 1.前提&#xff1a;安装Vue CLI 2.方式一&#xff1a;vue create项目名称 3.方式二&#xff1a;vue ui 二、Vue项目结构 三、修改Vue项目端口号的方法 一、创建前端项目的方法 1.前提&#xff1a;安装Vue CLI npm i vue/cli -g 2.方式一&…

Java 大数据与区块链的融合:数据可信共享与溯源(45)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

STM32单片机学习记录(2.2)

一、STM32 13.1 - PWR简介 1. PWR&#xff08;Power Control&#xff09;电源控制 &#xff08;1&#xff09;PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能&#xff1b; &#xff08;2&#xff09;可编程电压监测器&#xff08;…

ROS应用之SwarmSim在ROS 中的协同路径规划

SwarmSim 在 ROS 中的协同路径规划 前言 在多机器人系统&#xff08;Multi-Robot Systems, MRS&#xff09;中&#xff0c;SwarmSim 是一个常用的模拟工具&#xff0c;可以对多机器人进行仿真以实现复杂任务的协同。除了任务分配逻辑以外&#xff0c;SwarmSim 在协同路径规划方…

蓝桥杯python基础算法(2-1)——排序

目录 一、排序 二、例题 P3225——宝藏排序Ⅰ 三、各种排序比较 四、例题 P3226——宝藏排序Ⅱ 一、排序 &#xff08;一&#xff09;冒泡排序 基本思想&#xff1a;比较相邻的元素&#xff0c;如果顺序错误就把它们交换过来。 &#xff08;二&#xff09;选择排序 基本思想…

linux 进程补充

环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪 里&#xff0c;但是照样可以链接成功&#…