【QT入门】 Qt自定义控件与样式设计之QPushButton实现鼠标悬浮按钮弹出对话框

这篇具有很好参考价值的文章主要介绍了【QT入门】 Qt自定义控件与样式设计之QPushButton实现鼠标悬浮按钮弹出对话框。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

往期回顾:

【QT入门】 Qt自定义控件与样式设计之qss选择器-CSDN博客

【QT入门】 Qt自定义控件与样式设计之QLineEdit的qss使用-CSDN博客

【QT入门】Qt自定义控件与样式设计之QPushButton常用qss-CSDN博客

【QT入门】 Qt自定义控件与样式设计之QPushButton实现鼠标悬浮按钮弹出对话框

一、最终效果

鼠标悬浮弹出对话框的功能:最终要实现纯代码设计出一个音量按钮,当鼠标悬浮在上面的时候,显示滑块,并可以自己调节大小,鼠标离开后滑块消失。

qt 移动鼠标弹框,QT入门,qt,开发语言,QPushButton,qss,音量滑块创建

二、具体实现

 1、鼠标事件捕捉

首先实现一个基本功能,就是窗口能识别鼠标,鼠标放上去就显示,不放上去就不显示,这个功能很简单只需要重写两个函数

void enterEvent(QEvent * event) override;
void leaveEvent(QEvent * event) override;

在Widget主窗口写这两个类,你那么就能实现鼠标放进主窗口有反应,拿出来也有反应

void Widget::enterEvent(QEvent * event)
{
    qDebug()<<"11111";
}

void Widget::leaveEvent(QEvent * event)
{
    qDebug()<<"22222";
}

2、加载主布局 

Widget类加载主布局,主类没操作,就是设置大小,创建布局,把按钮放进去。

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

    resize(800, 600);

    //创建水平布局
    QHBoxLayout *pHlay = new QHBoxLayout(this);

    //创建音量按钮并添加到布局水平布局里
    CVolumeButton* pVolumeButton = new CVolumeButton(this);
    pHlay->addWidget(pVolumeButton);
}

3、创建滑块 

 3.1cvolumesliderdialog类创建滑块

这个类本身继承自QDialog,主要作用是创建QSlider对象并添加到布局中。

QSlider是用于控制边界值的经典小部件。它允许用户沿水平或垂直凹槽移动QSlider 的滑块,并将 滑块 的位置转换为合法范围内的整数值。

    //设置对话框的固定大小为(40, 200)
    this->setFixedSize(40, 200);
    
    //创建一个垂直布局管理器pVLay,
    QVBoxLayout* pVLay = new QVBoxLayout(this);
    m_pSlider = new QSlider(this);
    
    //将一个垂直方向的QSlider对象m_pSlider添加到布局中
    m_pSlider->setOrientation(Qt::Vertical);
    pVLay->addWidget(m_pSlider);
3.2设置窗口标志

另外比较重要的一点,把设置窗口标志为无边框窗口和ToolTip提示框样式

这里用到一个ToolTip,ToolTip = Popup | Sheet ,可以实现滑块悬浮时显示,离开时消失

setFixedSize(40, 120);
    //设置窗口标志为无边框窗口和ToolTip提示框样式
    //ToolTip = Popup | Sheet,
    setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);   //ToolTip : 悬浮时显示,离开时消失
    setStyleSheet("QDialog{background-color: rgba(54, 54, 54, 0.5);}");  //0.5表示透明度,0表示全透明、1表示不透明;
//也可以使用百分百表示如: frm->setStyleSheet(“QFrame{background-color: rgba(255, 0, 0, 50%);}”);
3.3修复bug

bug: bool QWidget::event(QEvent *event)这个方法设置popup后,dialog会有窗口阴影

需要去除就重写event函数,

bool CVolumeSliderDialog::event(QEvent* event)
{
    //定义一个静态布尔变量class_amended,用于跟踪是否已经修改了窗口类。
    static bool class_amended = false;

    //事件类型为WinIdChange,表示窗口标识已更改。
    if (event->type() == QEvent::WinIdChange)
    {
        //获取对话框的窗口句柄
        HWND hwnd = (HWND)winId();

        //检查是否已经修改了窗口类
        if (class_amended == false)
        {
            class_amended = true;//将class_amended设置为true,表示已经修改了窗口类
            DWORD class_style = ::GetClassLong(hwnd, GCL_STYLE);//获取窗口类的样式
            //将CS_DROPSHADOW样式从窗口类样式中移除,这样可以去除窗口阴影
            class_style &= ~CS_DROPSHADOW;
            //将修改后的窗口类样式应用到窗口
            ::SetClassLong(hwnd, GCL_STYLE, class_style); // windows系统函数
        }
    }

    //调用基类QWidget的event函数来处理事件,确保其他事件得到正常处理
    return QWidget::event(event);
}

注意这个完全可以作为一个通用类,需要的时候直接使用。

4、创建音量按钮

cvolumebutton类实现音量按钮的创建和滑块的绑定以及逻辑实现

主要是几个逻辑实现
 

1、纯代码创建一个音量按钮
2、创建滑块并定位在按钮上方合适位置
3、判断是否点击按钮需要静音来改变滑块上的位置
4、通过定时器判断鼠标是否离开按钮和滑块区域,离开滑块就消失
4.1首先通过重写paintEvent方法,实现了在CVolumeButton控件上绘制一个按钮外观的功能 
//代码可重用
void CVolumeButton::paintEvent(QPaintEvent*)
{
    //QStylePainter用于绘制基于QStyle的外观元素
    QStylePainter p(this);

    //QStyleOptionButton用于存储按钮控件的外观选项,如颜色、边框等
    QStyleOptionButton option;

    //调用initStyleOption方法初始化option对象
    //initStyleOption通常用于设置控件的外观选项,以便正确绘制控件
    initStyleOption(&option);

    //使用QStylePainter对象p绘制一个CE_PushButton类型的控件,参数为option对象。
    //这将根据option中的外观选项绘制按钮的外观,如背景、文本等
    p.drawControl(QStyle::CE_PushButton, option);
}
4.2然后在鼠标进入声音按钮时,创建并显示一个音量滑块对象,将其定位在合适的位置,并启动一个定时器。同时,建立了一个信号与槽的连接,以便在滑块数值变化时通知其他部分。 
void CVolumeButton::enterEvent(QEvent* event)
{
    //判断并初始化滑块对象,确保只有在需要时才创建滑块对象
    if (!m_pVolumeSliderDlg)
        m_pVolumeSliderDlg = new CVolumeSliderDialog(this);


    QPoint p1 = this->mapToGlobal(QPoint(0, 0));  //声音按钮左上角相对于桌面的绝对位置
    QRect rect1 = this->rect();    //获取声音按钮的矩形区域
    //获取滑块对象的矩形区域,rect包含标题栏,去掉标题栏后height不变
    QRect rect2 = m_pVolumeSliderDlg->rect();

    //计算滑块对象在水平方向上的位置,使其水平居中于声音按钮
    //这里计算很简单,就是按钮的一半减去滑块的一半,就是多出来的那部分
    //按钮的x加上多出来那部分,就能得到滑块居中的x位置
    int x = p1.x() + (rect1.width() - rect2.width()) / 2;

    //计算滑块对象在垂直方向上的位置,使其位于声音按钮上方并略微偏移5px
    //按钮的y减去滑块的长度再减去偏移的5px,就是滑块的左上角y位置
    int y = p1.y() - rect2.height() - 5;
    //滑块对象移动到计算得到的位置
    m_pVolumeSliderDlg->move(x, y);   //move是相对于桌面原点的位置

    m_pVolumeSliderDlg->show();//显示滑块对象
    m_timerId = startTimer(250);//动一个定时器,每250毫秒触发一次定时器事件

    connect(m_pVolumeSliderDlg, &CVolumeSliderDialog::sig_SliderValueChanged, [=](int value) {
        emit sig_VolumeValue(value);
    });
}
4.3检测鼠标按下事件实现静音
void CVolumeButton::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)//检查鼠标按下的按钮是否是左键
    {
        m_isMute = !m_isMute; //切换静音状态,真假切换
        if (m_isMute)//如果当前为静音状态
        {
            //如果滑块对象存在,将滑块值设置为0,表示静音状态
            if (m_pVolumeSliderDlg)
                m_pVolumeSliderDlg->setSliderValue(0);
        }
        else
        {
            //如果滑块对象存在,将滑块值设置为50,表示非静音状态下的默认音量
            if (m_pVolumeSliderDlg)
                m_pVolumeSliderDlg->setSliderValue(50);
        }
    }
}
4.4在定时器事件中检测鼠标位置,如果鼠标移出音量滑块对象或声音按钮的区域,则隐藏音量滑块对象;如果音量滑块对象不存在或不可见,则停止定时器。
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->rect();//获取音量滑块对象的矩形区域
            QRect rect3 = m_pVolumeSliderDlg->geometry();//获取音量滑块对象的几何信息

            QPoint p2 = this->mapToGlobal(QPoint(0, 0));   //声音按钮左上角相对于桌面的绝对位置

            //已知:音量框宽40 > 按钮宽30
            //创建一个矩形区域,用于检测鼠标位置是否在音量滑块对象或声音按钮上
            QRect area(rect3.left(), rect3.top(), rect2.width(), p2.y() + rect1.height() - rect3.top()); //左上宽高

            if (!area.contains(p1))//如果鼠标位置不在矩形区域内
            {
                m_pVolumeSliderDlg->hide();//隐藏音量滑块对象
            }
        }
    }
    else //如果鼠标位置在矩形区域内
    {
        //停止定时器,即终止定时器事件的触发
        killTimer(m_timerId);
    }
}

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!文章来源地址https://www.toymoban.com/news/detail-856149.html

到了这里,关于【QT入门】 Qt自定义控件与样式设计之QPushButton实现鼠标悬浮按钮弹出对话框的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【QT】 QTabWidget&QTabBar控件样式设计(QSS)

    很高兴在雪易的CSDN遇见你 ,给你糖糖 欢迎大家加入 雪易社区-CSDN社区云   本文分享QT控件QTabWidgetQTabBar的样式设计,介绍两者可以自定义的内容,以及如何定义,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我

    2024年01月18日
    浏览(40)
  • QT鼠标事件穿透,使QLabel、QPushbutton等上层控件可以被穿透

    几乎QT所有的标准控件都可以被穿透。方法除了我们自定义这个控件外,如: 之外,这些标准控件也可以通过配置setAttribute来实现鼠标事件穿透。如:

    2024年02月12日
    浏览(28)
  • QT自定义优雅的表单控件,简单实现设置界面布局

    FormView.h FormView.cpp 核心函数 函数 变量 功能 addEditableItem title: 输入框前面的提示文字,同时作为该控件的标识符 place_holder: 输入框中的提示文字 在表单中插入一个可填写项 addCheckableItem title: 不显示在UI中,仅作为该控件的标识符 content: 勾选框后面的内容 init_status: 勾选框的初

    2024年02月11日
    浏览(31)
  • qt设置控件的风格样式

    设置tablewidget 设置表头样式 设置Lineedit样式 设置GroupBox样式 设置CheckBox的样式 设置PushButton的样式 设置RadioButton的样式 设置ComboBox的样式 设置Label的样式

    2024年02月14日
    浏览(21)
  • Qt自定义窗口部件/控件(实现一个十六进制微调框SpinBox)

    在某些情况下,我们发现Qt窗口控件需要更多的自定义定制,这些定制可能要比它在Qt设计师里可设置的属性或者对它调用的那些函数更多一些。一个简单而直接的解决方法就是对相关的窗口部件类进行子类化并且使它能够满足我们的需要。 本文主要是通过实现一个十六进制微调

    2024年02月11日
    浏览(30)
  • QT各种控件常用样式表qss示例

    目录 1、表格控件QTableWidget和QTableView 2、滚动条QScrollBar 这个控件比较复杂,里面包含了滑动条、表头(又细分为内容区/空白区)、表格、整体、左上角按钮等多种不同的元素,他们之间有复杂的叠层关系。需要通过各种“选择器”来指定样式的作用范围。 本文由【暴躁的野

    2024年02月16日
    浏览(32)
  • qt 系列(二)---qt designer通过设置控件样式表进行背景颜色设置

    1. 前言 一般Layouts不可以进行改变样式表,当我们想修改背景样式表,同时又不改变其他控件的颜色时,可以选择List View 控件改变背景颜色。 2. 设置背景 (1)配置 .qrc 文件 新建mypicture.qrc文件,记事本打开 (2)右键选择项目–添加–现有项,选择建立的.qrc文件,此时,项

    2024年02月06日
    浏览(33)
  • Qt自定义控件 —— 颜色选择组合控件

             在开始阅读本文之前,如果您有学习创建Qt自定义控件并在其他项目中引用的需求,请参考: Linux系统下在Qt Creator中创建自定义控件并在其他项目中引用 https://blog.csdn.net/YMGogre/article/details/128920804 目录 1、应用场景: 2、所需资源: 3、界面布局: 3.1、各布局/控件

    2024年02月10日
    浏览(28)
  • Qt--自定义控件

    Qt中提供了应用在各种场景的控件,使开发人员在实际工作中选择。但有些特定的场合中这些控件并不满足需要时,Qt允许使用自定义的控件。 例:我们在工作中有这样一种需求,点击按钮会根据一些其他状态来显示不同的图片,这时Qt提供的QPushButton就无法满足这种需求,这

    2024年02月16日
    浏览(27)
  • qt自定义控件的封装

    刚学了一个很有意思的东西,前面学了list,Tree,Table三大控件和一部分常用基础控件,但感觉没啥意思,就是用别人的直接用,刚学了一个自定义控件的封装,流程如下:   想把两个不相关的组件封装在一块,直接用ui不行,所以先新添加了qt设计师页面,新添加了一个SmallWidget *ui 在smallw

    2024年01月23日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包