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

【三十四】【QT开发应用】音量图标以及滑动条,没有代码补全的小技巧

效果展示

在这里插入图片描述

  • 鼠标位于音量图标区域内,显示出滑动条。鼠标移出音量图标区域内滑动条隐藏。
  • 鼠标点击音量图标,如果此时音量为0,音量变成50,如果此时音量不为零,音量变为0。

CVolumeButton.h 音量图标头文件

#pragma once
#include <QtWidgets>
#include "CVolumeSliderDialog.h"class CVolumeButton :public QPushButton {Q_OBJECT
public:CVolumeButton(QWidget* p = nullptr);~CVolumeButton();protected:void enterEvent(QEnterEvent* event) override;void timerEvent(QTimerEvent* event) override;void mousePressEvent(QMouseEvent* event) override;private:CVolumeSliderDialog* m_pVolumeSliderDlg = nullptr;int m_timerId = -1;bool m_isMute = false;
};
  • #include <QtWidgets> 是 Qt 库中用于引入所有与图形用户界面(GUI)相关控件的头文件。可以理解为是一个模块头文件,用这一个头文件就可以包含许多其他的头文件,和C++中的万能头文件#include<bits/stdc++>有异曲同工之妙。通过 #include <QtWidgets>,你可以一次性引入所有常用的 GUI 控件,而无需单独引入每个控件的头文件。它包含了大部分用于创建桌面应用程序的常见控件,比如 QMainWindow、QDialog、QPushButton 等。
  • 重载了这三个函数事件,enterEvent是进入事件,也就是说当鼠标进入到空间区域内会触发的事件.timerEvent是定时器事件,设置完毕定时器之后,每过一段事件就会触发一遍定时器内的函数逻辑.mousePressEvent是鼠标按下事件,当鼠标按下按键之后,会触发的事件.
    	void enterEvent(QEnterEvent* event) override;void timerEvent(QTimerEvent* event) override;void mousePressEvent(QMouseEvent* event) override;
    
  • CVolumeSliderDialog是滑动条类,m_timerId是定时器的ID,创建出一个定时器之后会返回一个定时器ID,m_isMute用来判断音量是否不为0,也就是说判断是否有音量.
    	CVolumeSliderDialog* m_pVolumeSliderDlg = nullptr;int m_timerId = -1;bool m_isMute = false;
    

CVolumeButton.cpp 音量图标源文件

#include "CVolumeButton.h"CVolumeButton::CVolumeButton(QWidget* p):QPushButton(p) {this->setFixedSize(32, 32);setStyleSheet(R"(
QPushButton{
background-image:url(:/widget/resources/audio_open.svg);
border:none;
}
QPushButton:hover{
background-image:url(:/widget/resources/audio_open_hover.svg);
}
QPushButton:pressed{
background-image:url(:/widget/resources/audio_open.svg);
}
)");}CVolumeButton::~CVolumeButton() {}void CVolumeButton::enterEvent(QEnterEvent* event) {qDebug() << "1111111";if (m_pVolumeSliderDlg == nullptr) m_pVolumeSliderDlg = new CVolumeSliderDialog(this);QPoint p1 = this->mapToGlobal(QPoint(0, 0));//局部坐标(0, 0)转换为全局坐标p1QRect rect1 = this->rect();//获取当前按钮的矩形区域QRect rect2 = m_pVolumeSliderDlg->rect();//获取滑动条的矩形区域int x = p1.x() + (rect1.width() - rect2.width()) / 2;int y = p1.y() - rect2.height();m_pVolumeSliderDlg->move(x, y);//将滑动条移动到(x,y)位置,全局坐标(x,y)m_pVolumeSliderDlg->show();//显示滑动条m_timerId = startTimer(250);//启动定时器,返回定时器ID,定时器间隔250ms触发一次
}void CVolumeButton::timerEvent(QTimerEvent* event) {if ((m_pVolumeSliderDlg != nullptr) && (m_pVolumeSliderDlg->isVisible())) {QPoint p1 = QCursor::pos();//获取鼠标全局坐标if (m_pVolumeSliderDlg) {QRect rect1 = this->rect();//获取局部矩形区域QRect rect2 = m_pVolumeSliderDlg->geometry();//获取全局矩形区域QPoint p2 = this->mapToGlobal(QPoint(0, 0));QRect arec(rect2.left(), rect2.top(), rect2.width(), p2.y() + rect1.height() - rect2.top());//定义滑动条显示的情况下鼠标存在的区域if (!arec.contains(p1))//如果arec不包含p1,隐藏滑动条m_pVolumeSliderDlg->hide();}}
}void CVolumeButton::mousePressEvent(QMouseEvent* event) {if (m_pVolumeSliderDlg->isZeroValue()) {//判断滑动条值是否为0m_isMute = false;//为零表示不存在音量值} else {m_isMute = true;//否则表示存在音量值}if (event->button() == Qt::LeftButton) {//如果左键点击按钮if (m_isMute) {//如果有音量if (m_pVolumeSliderDlg) {m_pVolumeSliderDlg->setSliderValue(0);//音量置0}} else {if (m_pVolumeSliderDlg) {m_pVolumeSliderDlg->setSliderValue(50);//否则置50}}}
}

enterEvent

进入事件,当鼠标进入到音量图标控件区域内就会触发的事件函数.
我们希望触发的事件是显示出滑动条,并且滑动条显示的位置在音量控件的正上方,水平居中对齐.因此我们需要设置滑动条的位置,通过使用move(x,y)函数操作使滑动条移动到指定的位置.
在这里插入图片描述

timerEvent

定时器事件,设置定时器时间,定时器会每间隔time时间就运行一遍函数.

rect和geometry的区别

rect()

  • 返回值:控件自身的局部坐标系中的矩形区域,仅代表控件本身的尺寸(宽度和高度),而不包含控件相对于屏幕或父窗口的位置。
  • x()y() 均为 0,因为这个矩形是以控件的左上角为原点的局部坐标。
  • width()height() 分别表示控件的宽度和高度。
  • 使用场景:当你只关心控件的尺寸(宽度和高度),而不关心它相对于父控件或屏幕的位置时,使用 rect()

geometry()

  • 返回值:控件在父控件或屏幕上的绝对矩形区域,即控件的相对位置(x 和 y 坐标)以及它的尺寸(宽度和高度)。
  • x()y() 表示控件相对于父控件或窗口的左上角位置。
  • width()height()rect() 返回的尺寸相同,表示控件的宽度和高度。
  • 使用场景:当你需要知道控件在父控件或屏幕中的具体位置(包括坐标和尺寸)时,使用 geometry()

区别总结:

  • rect():只提供控件的宽度和高度,左上角坐标总是 (0, 0)。
  • geometry():不仅提供控件的宽度和高度,还包含控件相对于父控件或屏幕的左上角位置坐标 (x, y)。

在这里插入图片描述

  • 局部坐标转化为全局坐标
    QPoint p1 = this->mapToGlobal(QPoint(0, 0));
  • 设置控件左上角坐标
    m_pVolumeSliderDlg->move(x, y);
  • 获取鼠标全局坐标
    QPoint p1 = QCursor::pos();

CVolumeSliderDialog.h 滑动条头文件

#pragma once
#include <QtWidgets>class CVolumeSliderDialog :public QWidget {Q_OBJECT
public:CVolumeSliderDialog(QWidget* p = nullptr);~CVolumeSliderDialog();void setSliderValue(int value) {m_pSlider->setValue(value);}bool isZeroValue() {return m_pSlider->value() == 0;}private:QSlider* m_pSlider = nullptr;
};
  • setSliderValue函数内置控制滑动条的函数,我们可以通过QSlider直接控制滑动条的值,为啥还需要内置一个函数去控制?因为我们运用CVolumeSliderDialog类无法控制私有的变量,所以需要共有的函数去控制
  • isZeroValue函数内置判断滑动条值是否为0.

CVolumeSliderDialog.cpp

#include "CVolumeSliderDialog.h"CVolumeSliderDialog::CVolumeSliderDialog(QWidget* p):QWidget(p) {this->setFixedSize(40, 120);QVBoxLayout* pVLay = new QVBoxLayout(this);m_pSlider = new QSlider(this);m_pSlider->setOrientation(Qt::Vertical);pVLay->addWidget(m_pSlider);setStyleSheet(R"(
QDialog{
background-color:rgba(54,54,54,0.5);
}
)");setWindowFlags(Qt::ToolTip);}
CVolumeSliderDialog::~CVolumeSliderDialog() {}
  • setWindowFlags(Qt::ToolTip);这是一个 WindowType 标志,表示窗口将被设置为类似工具提示(ToolTip)的窗口。

    • 特点
      • 没有标题栏,也不会显示在任务栏或窗口列表中。
      • 无法通过点击或拖动对其进行交互。
      • 通常用于显示一些临时性的信息,比如提示文本、悬停提示等。
  • m_pSlider->setOrientation(Qt::Vertical); 这行代码用于将滑块控件 (QSlider 或类似的控件) 的方向设置为垂直方向 (Qt::Vertical)。

widget.cpp


#include "widget.h"
#include "QtWidgets"
#include "CVolumeButton.h"
#include "CVolumeSliderDialog.h"widget::widget(QWidget* parent): QWidget(parent) {ui.setupUi(this);resize(800, 600);QHBoxLayout* pHLay = new QHBoxLayout(this);CVolumeButton* pVolumeButton = new CVolumeButton(this);//CVolumeSliderDialog* ptemp = new CVolumeSliderDialog(this);pHLay->addWidget(pVolumeButton);}widget::~widget() {}

没有代码提示怎么办?

当你发现某一个关键字没有代码提示的时候,Ctrl+左键进入到目标文件中.
在这里插入图片描述
以QHBoxLayout关键字为例,进入之后复制文件夹的完整路径.
在这里插入图片描述
点开番茄助手添加复制的完整路径点击确定.
在这里插入图片描述
然后启动窗口,重新启动该程序,再次输入就会有代码补全了.

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!

http://www.lryc.cn/news/466112.html

相关文章:

  • Android修改第三方应用相机方向
  • Python 读取文件汇总
  • 云原生:一张图了解devops 中CI/CD
  • 无人机之自组网通信技术篇
  • 【WebLogic】Oracle发布2024年第四季度中间件安全公告
  • Java集合(3:Set和Map)
  • 【Golang】Gin框架中如何定义路由
  • CPU内存飙升
  • 【Java】LinkedList实现类的使用
  • 创建人物状态栏
  • django5入门【01】环境配置
  • 1000集《楼兰》系列短剧开机仪式在疆举行,开启全球传播新篇章
  • 【景观生态学实验】实验五 景观生态脆弱性评价
  • ChatGPT 现已登陆 Windows 平台
  • 和鲸社区数据科学实训季,西安交通大学圆满收官,西安,后会有期!
  • 工作使用篇:如何在centos系统中安装anaconda
  • qt creator 转 visual stdio 项目调试
  • django5入门【02】创建新的django程序
  • 乐趣无限,十个让你沉浸的“摸鱼”网站
  • ubuntu22.04 桌面系统怎么搭建一个esp-idf的项目,搭建开发环境
  • iOS Swift逆向——deMangle过程中的偏移计算
  • 国产大模型基础能力大比拼 - 计数:通义千文 vs 文心一言 vs 智谱 vs 讯飞-正经应用场景的 LLM 逻辑测试
  • YOLO11改进 | 注意力机制 | 正确的 Self-Attention 与 CNN 融合范式,性能速度全面提升【独家创新】
  • 0基础学java之Day11
  • python主流框架Django:ORM框架关联查询与管理器
  • 如何有效维护您的WordPress在线商店内容:提高客户参与度与转化率的实用技巧
  • 【Java】认识异常
  • 20 Shell Script输入与输出
  • HCIP-HarmonyOS Application Developer 习题(十六)
  • 没有什么可以抵达乌托邦,包括AI