控件【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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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本身的geometryQRect 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本身的geometryQRect 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本身的geometryQRect 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本身的geometryQRect 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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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){//先休眠1sstd::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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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 exceptionstd::thread t (  [this] (){int value  = ui->lcdNumber->intValue();while(true){//先休眠1sstd::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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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.rhkb.cn/news/13031.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苹果再度砍掉AR眼镜项目?AR真的是伪风口吗?

曾经&#xff0c;AR游戏一度异常火热&#xff0c;宝可梦go让多少人不惜翻墙都要去玩&#xff0c;但是也没过去几年&#xff0c;苹果被曝出再度砍掉了AR眼镜项目&#xff0c;面对着市场的变化&#xff0c;让人不禁想问AR真的是伪风口吗&#xff1f; 一、苹果再度砍掉AR眼镜项目&…

《redis4.0 通信模块源码分析(一)》

【redis导读】redis作为一款高性能的内存数据库&#xff0c;面试服务端开发&#xff0c;redis是绕不开的话题&#xff0c;如果想提升自己的网络编程的水平和技巧&#xff0c;redis这款优秀的开源软件是很值得大家去分析和研究的。 笔者从大学毕业一直有分析redis源码的想法&…

日期选择控件,时间跨度最大一年。

<el-date-picker v-model"times" type"daterange" unlink-panels :picker-options"pickerOptions" :range-separator"$lang(至)":start-placeholder"$lang(开始)" :end-placeholder"$lang(结束)" :default-tim…

JDK9新特性

文章目录 新特性&#xff1a;1.模块化系统使用模块化module-info.java&#xff1a;exports&#xff1a;opens&#xff1a;requires&#xff1a;provides&#xff1a;uses&#xff1a; 2.JShell启动Jshell执行计算定义变量定义方法定义类帮助命令查看定义的变量&#xff1a;/var…

Vue Router 客户端路由解决方案:axios 响应拦截(跳转到登录页面)

文章目录 引言客户端路由 vs. 服务端路由简单的路由案例术语I Vue Router 提供的组件RouterLinkRouterViewII 创建路由器实例调用 createRouter() 函数创建路由选项III 注册路由器插件通过调用 use() 来完成注册路由器插件的职责对于组合式 API,Vue Router 给我们提供了一些组…

在游戏本(6G显存)上本地部署Deepseek,运行一个14B大语言模型,并使用API访问

在游戏本6G显存上本地部署Deepseek&#xff0c;运行一个14B大语言模型&#xff0c;并使用API访问 环境说明环境准备下载lmstudio运行lmstudio 下载模型从huggingface.co下载模型 配置模型加载模型测试模型API启动API服务代码测试 deepseek在大语言模型上的进步确实不错&#xf…

【Uniapp-Vue3】创建DB schema数据表结构

右键uniCloud文件下的database文件&#xff0c;点击“新建DB schema”&#xff0c;选择模板&#xff0c;修改文件名&#xff0c;点击“创建” 创建完成后会出现对应的文件&#xff0c;进入该文件进行配置 对文件中的必填选项&#xff0c;用户权限&#xff0c;字段进行配置 其…

1-ET框架开发环境与demo运行

所需开发环境 安装Unity模块时&#xff0c;记得安装windows Build Support&#xff08;IL2CPP&#xff09;&#xff0c;否则打包会出问题。 安装visual studio&#xff0c;因为需要安装开发组件&#xff0c;需要选择 下载MongoDB7.0.2并安装 确认MongoDB安装成功 查看计算机…

CTP查询资金费率和手续费没响应

CTP的OnRspQryInstrumentOrderCommRate()和OnRspQryInstrumentCommissionRate()和手续费率和手续费有关系&#xff0c;但是今天我通过重写这两个方法&#xff0c;并且调用ReqQryInstrumentCommissionRate()后没响应&#xff0c;查了半天发现&#xff0c;我应该把响应函数实现写…

Python爬虫实战:一键采集电商数据,掌握市场动态!

电商数据分析是个香饽饽&#xff0c;可市面上的数据采集工具要不贵得吓人&#xff0c;要不就是各种广告弹窗。干脆自己动手写个爬虫&#xff0c;想抓啥抓啥&#xff0c;还能学点技术。今天咱聊聊怎么用Python写个简单的电商数据爬虫。 打好基础&#xff1a;搞定请求头 别看爬虫…

Page Assist实现deepseek离线部署的在线搜索功能

前面文章Mac 基于Ollama 本地部署DeepSeek离线模型 实现了deepseek的离线部署&#xff0c;但是部署完成虽然可以进行问答和交互&#xff0c;也有thinking过程&#xff0c;但是没办法像官方一样进行联网搜索。今天我们介绍一款浏览器插件Page Assist来实现联网搜索&#xff0c;完…

Qt跨屏窗口的一个Bug及解决方案

如果我们希望一个窗口覆盖用户的整个桌面&#xff0c;此时就要考虑用户有多个屏幕的场景&#xff08;此窗口要横跨多个屏幕&#xff09;&#xff0c;由于每个屏幕的分辨率和缩放比例可能是不同的&#xff0c;Qt底层在为此窗口设置缩放比例&#xff08;DevicePixelRatio&#xf…

AI绘画:解锁商业设计新宇宙(6/10)

1.AI 绘画&#xff1a;商业领域的潜力新星 近年来&#xff0c;AI 绘画技术以惊人的速度发展&#xff0c;从最初简单的图像生成&#xff0c;逐渐演变为能够创造出高度逼真、富有创意的艺术作品。随着深度学习算法的不断优化&#xff0c;AI 绘画工具如 Midjourney、Stable Diffu…

逻辑回归原理

逻辑回归是一个分类算法&#xff0c;它可以处理二元分类以及多元分类。虽然它名字里面有“回归”两个字&#xff0c;却不是一个回归算法。 逻辑回归尤其是二元逻辑回归是非常常见的模型&#xff0c;训练速度很快&#xff0c;虽然使用起来没有支持向量机&#xff08;SVM&#xf…

四.4 Redis 五大数据类型/结构的详细说明/详细使用( zset 有序集合数据类型详解和使用)

四.4 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; zset 有序集合数据类型详解和使用&#xff09; 文章目录 四.4 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; zset 有序集合数据类型详解和使用&#xff09;1. 有序集合 Zset(sorted set)2. zset 有序…

AlwaysOn 可用性组副本所在服务器以及该副本上数据库的各项状态信息

目录标题 语句代码解释:1. `sys.dm_hadr_database_replica_states` 视图字段详细解释及官网链接官网链接字段解释2. `sys.availability_replicas` 视图字段详细解释及官网链接官网链接字段解释查看视图的创建语句方法一:使用 SQL Server Management Studio (SSMS)方法二:使用…

编程之路:在细节中磨砺技艺

编程之路&#xff1a;在细节中磨砺技艺 在编程的世界里&#xff0c;每一个字符、每一行代码都像是精心雕琢的艺术品&#xff0c;承载着程序员的智慧与心血。而在这个充满挑战与惊喜的旅程中&#xff0c;问题与解决方案总是如影随形。就像在开发居家养老管理系统时&#xff0c;我…

基于ArcGIS的SWAT模型+CENTURY模型模拟流域生态系统水-碳-氮耦合过程研究

流域是一个相对独立的自然地理单元&#xff0c;它是以水系为纽带&#xff0c;将系统内各自然地理要素连结成一个不可分割的整体。碳和氮是陆地生态系统中最重要的两种化学元素&#xff0c;而在流域系统内&#xff0c;水-碳-氮是相互联动、不可分割的耦合体。随着流域内人类活动…

【Linux网络编程】:URL(encode),HTTP协议,telnet工具

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ Linux网络编程笔记&#xff1a; https://mp.csdn…

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

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