当前位置: 首页 > ds >正文

QT —— QWidget(1)

QT —— QWidget(1)

  • QWidget是啥
      • 通俗解释:QWidget 是什么?
      • 1. QWidget 能干什么?
      • 2. 举个栗子 🌰
      • 3. QWidget 的特点
      • 4. 和“控件”是什么关系?
      • 5. 什么时候用 QWidget?
      • 6. 总结
  • QWidget 核心属性
  • QWidget 常用属性说明
    • 基础属性
    • 交互属性
    • 样式属性
    • 尺寸控制
    • 辅助功能
    • 其他属性
  • enable
    • 方法说明
    • 使用示例
    • 注意事项
  • geometry
    • 方法说明
    • 使用示例
  • window frame
    • 坐标和尺寸获取方法
    • 客户区获取方法
    • 设置方法
    • 重要说明

我们从这章开始,我们介绍一下QT中一些常用控件,如果对之前的章节还不是很熟悉的可以点击这里:

https://blog.csdn.net/qq_67693066/category_12625974.html

QWidget是啥

通俗解释:QWidget 是什么?

QWidget 是 Qt 框架中的一个 基础类,用来创建 用户界面(UI)的“零件”
你可以把它理解成 “UI 积木块”——几乎所有你能看到的窗口、按钮、文本框、下拉菜单等,都是基于 QWidget 构建的。


1. QWidget 能干什么?

  • 创建窗口和控件
    • 比如:一个弹窗(QDialog)、一个按钮(QPushButton)、一个输入框(QLineEdit),本质上都是 QWidget 的子类。
  • 管理布局和样式
    • 控制大小、位置、颜色、字体等。
  • 处理用户交互
    • 响应点击、键盘输入、鼠标移动等事件。

2. 举个栗子 🌰

假设你要做一个简单的登录界面:

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLineEdit>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建一个窗口(QWidget 是所有窗口和控件的基类)QWidget window;window.setWindowTitle("登录界面");window.resize(300, 200);// 在窗口上放一个按钮QPushButton button("登录", &window);button.move(100, 100);// 在窗口上放一个输入框QLineEdit usernameInput(&window);usernameInput.setPlaceholderText("请输入用户名");usernameInput.move(50, 50);window.show(); // 显示窗口return app.exec();
}

效果
你会看到一个带输入框和按钮的窗口,这就是用 QWidget 及其子类拼出来的。


3. QWidget 的特点

特性说明
跨平台基于 Qt,同一套代码能运行在 Windows、macOS、Linux 甚至嵌入式设备上。
可嵌套可以把一个 QWidget(如按钮)放到另一个 QWidget(如窗口)上,形成父子关系。
支持样式定制能用 CSS 类似的语法修改外观(比如圆角按钮、渐变背景)。
事件驱动可以监听用户的鼠标、键盘操作(比如点击按钮触发函数)。

4. 和“控件”是什么关系?

  • QWidget 是基类,提供最基础的功能(比如显示、隐藏、调整大小)。
  • 控件(如 QPushButtonQCheckBox)是它的子类,增加了具体交互逻辑。
    • 类比:
      • QWidget ≈ “空白画布”
      • QPushButton ≈ “画布上画了一个按钮”

5. 什么时候用 QWidget?

  • 当你需要 自定义一个界面元素(比如设计一个圆形按钮),可以继承 QWidget 自己绘制。
  • 但大多数时候,直接用现成的子类(如 QMainWindowQLabel)就够了。

6. 总结

  • QWidget 是 Qt 的 UI 基石,所有看得见的界面元素都是它或它的子类。
  • 像乐高积木,通过组合各种 QWidget 派生出的控件,就能拼出完整的界面。
  • 适合:开发桌面应用、嵌入式设备界面、工业控制面板等。

我们可以在QT Desginer中可以看到各种各样的控件:

在这里插入图片描述
在 Qt 中, 使用 QWidget 类表示 “控件”. 像按钮, 视图, 输入框, 滚动条等具体的控件类, 都是继承自QWidget.可以说, QWidget 中就包含了 Qt 整个控件体系中, 通用的部分。

QWidget 核心属性

我们选了一个控件,右下角的黄色区域就可以显示该控件的属性:
在这里插入图片描述

QWidget 常用属性说明

基础属性

属性作用
enabled设置控件是否可用:
- true 表示可用
- false 表示禁用
geometry设置位置和尺寸(x, y, width, height)
坐标以父元素为参考
windowTitle设置窗口标题
windowIcon设置窗口图标
windowOpacity设置窗口透明度(0.0-1.0)

交互属性

属性作用
cursor鼠标悬停时的光标形状:
- 箭头、沙漏、十字等
focusPolicy焦点获取方式:
- NoFocus:不参与焦点管理
- TabFocus:通过Tab键获取
- ClickFocus:通过鼠标点击获取
- StrongFocus:键盘+鼠标获取
- WheelFocus:鼠标滚轮获取
contextMenuPolicy上下文菜单显示策略:
- DefaultContextMenu:默认右键菜单
- NoContextMenu:禁用菜单
- CustomContextMenu:自定义菜单
acceptDrops是否接受拖放操作:
- true:可接收拖放
- false:不接收

样式属性

属性作用
font设置字体(家族、大小、粗体、斜体等)
styleSheet使用CSS设置控件样式
palette调色板(设置颜色风格)
layoutDirection布局方向:
- LeftToRight:从左到右(默认)
- RightToLeft:从右到左

尺寸控制

属性作用
minimumSize最小尺寸(width, height)
maximumSize最大尺寸(width, height)
sizePolicy在布局管理器中的缩放方式
sizeIncrement窗口拖动时的尺寸调整单位
baseSize窗口基础尺寸(配合sizeIncrement使用)

辅助功能

属性作用
toolTip鼠标悬停时的提示信息
statusTip状态改变时的提示信息
whatsThis按Alt+F1显示帮助信息
accessibleName无障碍名称(供屏幕阅读器使用)
accessibleDescription无障碍详细描述

其他属性

属性作用
mouseTracking是否跟踪鼠标移动事件
tabletTracking是否跟踪触摸屏事件(Qt 5.9+)
autoFillBackground是否自动填充背景色
windowModality窗口模态行为设置
inputMethodHints输入框格式提示(如仅数字、仅日期等)

enable

方法说明

方法说明参数返回值
isEnabled()获取控件的当前可用状态bool
- true: 控件可用
- false: 控件禁用
setEnabled(bool)设置控件的可用状态enable: bool
- true: 启用控件
- false: 禁用控件

使用示例

// 获取按钮当前状态
bool isActive = ui->pushButton->isEnabled(); // 禁用按钮
ui->pushButton->setEnabled(false);// 启用按钮  
ui->pushButton->setEnabled(true);

我们可以写一段代码看一下:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* btn = new QPushButton(this);btn->setText("这是个被禁⽤的按钮");btn->setEnabled(false);
}

在这里插入图片描述

注意事项

  1. 禁用状态下的控件:

    • 显示为灰色(默认样式)
    • 不响应任何用户交互事件
    • 仍可通过程序代码修改其状态
  2. 父子控件关系:

    • 父控件禁用时,所有子控件会自动禁用
    • 单独启用子控件无效(需先启用父控件)
  3. 样式定制:

    • 可通过QSS修改禁用状态的样式:
    QPushButton:disabled {color: #999999;background-color: #dddddd;
    }
    

我们来写一个小栗子,创建两个按钮,其中一个按钮可以控制另一个按钮是否被启用:

我们先在ui界面创建两个按钮:
在这里插入图片描述
选中一个按钮之后,我们对它改个名字,方便我们辨识:
在这里插入图片描述
下面那个按钮也一样:
在这里插入图片描述
然后右击,分别为这两个按钮添加槽函数:
在这里插入图片描述
在这里插入图片描述

void Widget::on_pushButton_one_clicked()
{qDebug() << "this button has been clicked";
}void Widget::on_pushButton_two_clicked()
{bool flag = this->ui->pushButton_one->isEnabled();this->ui->pushButton_one->setEnabled(!flag);
}

在这里插入图片描述
在这里插入图片描述

geometry

位置和尺寸. 其实是四个属性的统称:
x 横坐标
y 纵坐标
width 宽度
height 高度

在这里插入图片描述
但是实际开发中, 我们并不会直接使用这几个属性, 而是通过⼀系列封装的方法来获取/修改。

对于 Qt 的坐标系, 不要忘记是⼀个 “左手坐标系”. 其中坐标系的原点是当前元素的父元素的左上角

在这里插入图片描述

方法说明

方法说明参数返回值
geometry()获取控件的位置和尺寸QRect
包含四个属性:
- x:左上角X坐标
- y:左上角Y坐标
- width:控件宽度
- height:控件高度
setGeometry(QRect)设置控件的位置和尺寸rect: QRect
(包含x,y,width,height)
setGeometry(int x, int y, int width, int height)设置控件的位置和尺寸x: 左上角X坐标
y: 左上角Y坐标
width: 控件宽度
height: 控件高度

使用示例

// 获取当前几何属性
QRect rect = widget->geometry();
qDebug() << "Position:" << rect.x() << rect.y() << "Size:" << rect.width() << rect.height();// 通过QRect设置
widget->setGeometry(QRect(100, 50, 200, 150));// 通过单独参数设置
widget->setGeometry(100, 50, 200, 150);

代码示例: 控制按钮的位置

  1. 在界面中拖五个按钮.
    五个按钮的 objectName 分别为 pushButton_target , pushButton_up ,
    pushButton_down , pushButton_left , pushButton_right五个按钮的初始位置和大小都随意。

我们在ui界面上拖出五个按钮来:
在这里插入图片描述
然后分别生成这五个按钮的槽函数:

void Widget::on_target_clicked()
{}void Widget::on_pushButton_up_clicked()
{QRect rect = ui->pushButton_target->geometry();rect.setY(rect.y() - 5);ui->pushButton_target->setGeometry(rect);
}void Widget::on_pushButton_down_clicked()
{QRect rect = ui->pushButton_target->geometry();rect.setY(rect.y() + 5);ui->pushButton_target->setGeometry(rect);
}void Widget::on_pushButton_left_clicked()
{QRect rect = ui->pushButton_target->geometry();rect.setX(rect.x() - 5);ui->pushButton_target->setGeometry(rect);
}void Widget::on_pushButton_right_clicked()
{QRect rect = ui->pushButton_target->geometry();rect.setX(rect.x() + 5);ui->pushButton_target->setGeometry(rect);
}

运行程序, 可以看到, 按下下方的四个按钮, 就会控制 target 的左上⻆的位置. 对应的按钮整个尺寸也会发生改变.

上述代码中我们是直接设置的 QRect 中的 x, y . 实际上 QRect 内部是存储了左上和右下两个点的坐标, 再通过这两个点的坐标差值计算长宽.单纯修改左上坐标就会引起整个矩形的长宽发生改变.
在这里插入图片描述
如果想让整个按钮都移动, 可以改成下列代码:

void Widget::on_pushButton_up_clicked()
{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()
{QRect rect = ui->pushButton_target->geometry();ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5, rect.width(), rect.height());
}void Widget::on_pushButton_left_clicked()
{QRect rect = ui->pushButton_target->geometry();ui->pushButton_target->setGeometry(rect.x() - 5, rect.y(), rect.width(),rect.height());
}void Widget::on_pushButton_right_clicked()
{QRect rect = ui->pushButton_target->geometry();ui->pushButton_target->setGeometry(rect.x() + 5, rect.y(), rect.width(),rect.height());
}

在这里插入图片描述

window frame

我们每次运行出来的窗口都会有一个小白条:
在这里插入图片描述
其实在我们的Widget的外围还有一层细细的边框:
在这里插入图片描述
以上提到的这两部分都是操作系统给我们的Widget自动添加的,我们称之为window frame,我们上面提到的geometry是只针对Widget本身的,QT还针对的有window frame的方法:

坐标和尺寸获取方法

方法说明包含 Window Frame返回类型等价关系
x()获取控件左上角X坐标✔️intframeGeometry().x()
y()获取控件左上角Y坐标✔️intframeGeometry().y()
pos()获取控件位置✔️QPointQPoint(x(), y())
frameSize()获取包含边框的尺寸✔️QSizeframeGeometry().size()
frameGeometry()获取完整外框矩形✔️QRectQRect(pos(), frameSize())

客户区获取方法

方法说明包含 Window Frame返回类型等价关系
width()获取客户区宽度intgeometry().width()
height()获取客户区高度intgeometry().height()
size()获取客户区尺寸QSizegeometry().size()
rect()获取客户区矩形(相对坐标)QRectQRect(0, 0, width(), height())
geometry()获取客户区绝对矩形QRectQRect(客户区x, 客户区y, width(), height())

设置方法

方法参数包含 Window Frame说明
setGeometry(QRect)QRect设置客户区位置和尺寸
setGeometry(x, y, w, h)int, int, int, int设置客户区位置和尺寸

重要说明

  1. Window Frame 包含

    • 窗口边框
    • 标题栏
    • 系统菜单按钮等装饰部件
  2. 典型差异值

    QMainWindow window;
    window.setGeometry(100, 100, 400, 300);// 输出示例:
    geometry(): QRect(100,100 400x300)
    frameGeometry(): QRect(98,78 404x322) 
    

我们可以来试试:

#include "widget.h"
#include <QDebug>#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();QRect rect1 = w.geometry();QRect rect2 = w.frameGeometry();qDebug() << rect1;qDebug() << rect2;return a.exec();
}

打印出来,可以看到细微差别:
在这里插入图片描述

http://www.xdnf.cn/news/3877.html

相关文章:

  • 白皮解读:数据流通关键技术白皮书【附全文阅读】
  • MNN 支持 DeepSeekVL
  • shell入门
  • 通过Docker部署Prometheus + Grafana搭建监控平台【超详细版】
  • 驱动总裁v2.19(含离线版)驱动工具软件下载及安装教程
  • 实用在线工具箱OmniTools
  • Python硬核革命:从微控制器到FPGA的深度开发指南
  • 多模态大语言模型arxiv论文略读(五十七)
  • Java响应式编程
  • DeepSeek实战--蒸馏
  • Java快速上手之实验六
  • Scrapy框架之【settings.py文件】详解
  • 开源项目实战学习之YOLO11:ultralytics-cfg-models-rtdetr(十一)
  • 强化学习:山地车问题
  • 【信息系统项目管理师】【论文】项目背景-通用部分(可背诵)
  • P1434 [SHOI2002] 滑雪
  • NVMe控制器之完成信息解析模块
  • Rotary Positional Embedding
  • FastAPI系列14:API限流与暴力破解防护
  • 学习黑客资产威胁分析贴
  • Linux:时间同步服务器
  • 深入理解C++中的指针与引用:区别、应用与最佳实践
  • 《Spring Boot实战指南:从零开始构建现代Java应用》
  • 从实列中学习linux shell11 :在 shell 中 对于json的解析 jq 和awk 如何选择,尤其在数据清洗,数据重新组织中的应用
  • 叠层阻抗线框
  • 【信息系统项目管理师-论文真题】2011下半年论文详解(包括解题思路和写作要点)
  • 1penl配置
  • 【Go类库分享】mcp-go Go搭建MCP服务
  • HTTPcookie与session实现
  • 洛谷 P1850 [NOIP 2016 提高组] 换教室