控件【QT】

文章目录

  • 控件
  • 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());

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker pull Error response from daemon问题

里面填写 里面解决方案就是挂代理。 以虚拟机为例&#xff0c;将宿主机配置端口设置&#xff0c;https/http端口设为7899 配置虚拟机的http代理&#xff1a; vim /etc/systemd/system/docker.service.d/http-proxy.conf里面填写&#xff0c;wq保存 [Service] Environment…

linux 进程补充

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

一文解释pytorch 中的 squeeze() 和 unsqueeze()函数(全网最详细版)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;零基础入门PyTorch框架_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 …

QT:对象树

1.概念 Qt 中的对象树是一种以树形结构组织 Qt 对象的方式。当创建一个QObject&#xff08;Qt 中大多数类的基类&#xff09;或其派生类的对象时&#xff0c;可以为其指定一个父对象&#xff08;parent&#xff09;。这个对象就会被添加到其父对象的子对象列表中&#xff0c;形…

labview通过时间计数器来设定采集频率

在刚接触labview的时候&#xff0c;笔者通常用定时里的等待函数来实现指令的收发&#xff0c;但是当用到的收发消息比较多时就出现了卡顿&#xff0c;卡死的情况&#xff0c;这是因为当用队列框架时&#xff0c;程序卡在了其中的一个分支里&#xff0c;等通过相应的延时后才可以…

2024最新前端面试题(附答案及解析)

文章目录 HTML篇1、HTML5有哪些新特性&#xff1f;2、介绍下 BFC 及其应用3、内元素和块级元素的区别&#xff1f;4、Doctype作用&#xff1f;标准模式与混杂模式如何区分&#xff1f;5、引入样式时&#xff0c;link和import的区别&#xff1f;6、介绍一下你对浏览器内核的理解…

Linux:文件系统(软硬链接)

目录 inode ext2文件系统 Block Group 超级块&#xff08;Super Block&#xff09; GDT&#xff08;Group Descriptor Table&#xff09; 块位图&#xff08;Block Bitmap&#xff09; inode位图&#xff08;Inode Bitmap&#xff09; i节点表&#xff08;inode Tabl…

Java基础面试题50题

1&#xff0c;""空字符串的作用 package com.neuedu.nineteen;public class Test {public static void main(String[] args) {String s"";for (char i a; i < d; i) {ssi;//输出abc // sis;//输出cba}System.out.println(s);} }如题所示&…

【技海登峰】Kafka漫谈系列(二)Kafka高可用副本的数据同步与选主机制

【技海登峰】Kafka漫谈系列(二)Kafka高可用副本的数据同步与选主机制 一. 数据同步 在之前的学习中有了副本Replica的概念,解决了数据备份的问题。我们还需要面临一个设计难题即:如何处理分区中Leader与Follwer节点数据同步不匹配问题所带来的风险,这也是保证数据高可用的…

GB/T 44721-2024 与 L3 自动驾驶:自动驾驶新时代的基石与指引

1.前言 在智能网联汽车飞速发展的当下&#xff0c;自动驾驶技术成为了行业变革的核心驱动力。从最初的辅助驾驶功能&#xff0c;到如今不断迈向高度自动化的征程&#xff0c;每一步都凝聚着技术的创新与突破。而在这一进程中&#xff0c;标准的制定与完善对于自动驾驶技术的规…

大语言模型的个性化综述 ——《Personalization of Large Language Models: A Survey》

摘要&#xff1a; 本文深入解读了论文“Personalization of Large Language Models: A Survey”&#xff0c;对大语言模型&#xff08;LLMs&#xff09;的个性化领域进行了全面剖析。通过详细阐述个性化的基础概念、分类体系、技术方法、评估指标以及应用实践&#xff0c;揭示了…

SpringBoot使用 easy-captcha 实现验证码登录功能

文章目录 一、 环境准备1. 解决思路2. 接口文档3. redis下载 二、后端实现1. 引入依赖2. 添加配置3. 后端代码实现4. 前端代码实现 在前后端分离的项目中&#xff0c;登录功能是必不可少的。为了提高安全性&#xff0c;通常会加入验证码验证。 easy-captcha 是一个简单易用的验…

国产编辑器EverEdit - 工具栏说明

1 工具栏 1.1 应用场景 当用户想显示/隐藏界面的标签栏、工具栏、状态栏、主菜单等界面元素时&#xff0c;可以通过EverEdit的菜单选项进行设置。 1.2 使用方法 选择菜单查看 -> 工具栏&#xff0c;在工具栏的子菜单中选择勾选或去掉勾选对应的选项。 标签栏&#xff1…

Redis的通用命令

⭐️前言⭐️ 本文主要介绍Redis的通用命令 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 &#x1f349;博客中涉及源码及博主日常练习代码均已上传GitHub &#x1f4cd;内容导…

机器学习专业毕设选题推荐合集 人工智能

目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光&#xff0c;一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整理…

Elasticsearch:如何搜索含有复合词的语言

作者&#xff1a;来自 Elastic Peter Straer 复合词在文本分析和标记过程中给搜索引擎带来挑战&#xff0c;因为它们会掩盖词语成分之间的有意义的联系。连字分解器标记过滤器等工具可以通过解构复合词来帮助解决这些问题。 德语以其长复合词而闻名&#xff1a;Rindfleischetik…

【后端开发】系统设计101——通信协议,数据库与缓存,架构模式,微服务架构,支付系统(36张图详解)

【后端开发】系统设计101——通信协议&#xff0c;数据库与缓存&#xff0c;架构模式&#xff0c;微服务架构&#xff0c;支付系统&#xff08;36张图&#xff09; 文章目录 1、通信协议通信协议REST API 对比 GraphQL&#xff08;前端-web服务&#xff09;grpc如何工作&#x…

Spark--如何理解RDD

1、概念 rdd是对数据集的逻辑表示&#xff0c;本身并不存储数据&#xff0c;只是封装了计算逻辑&#xff0c;并构建执行计划&#xff0c;通过保存血缘关系来记录rdd的执行过程和历史&#xff08;当一个rdd需要重算时&#xff0c;系统会根据血缘关系追溯到最初的数据源&#xff…

0205算法:最长连续序列、三数之和、排序链表

力扣128&#xff1a;最长连续序列 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 class Solution {public int longestConsecutive(in…

gitea - fatal: Authentication failed

文章目录 gitea - fatal: Authentication failed概述run_gitea_on_my_pkm.bat 笔记删除windows凭证管理器中对应的url认证凭证启动gitea服务端的命令行正常用 TortoiseGit 提交代码备注END gitea - fatal: Authentication failed 概述 本地的git归档服务端使用gitea. 原来的用…