打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
QToolButton 之续述

有时候我们需要根据按钮的check状态来设置按钮的不同背景或者是实现不同的功能。关于Qt 中的四大按钮——QCheckBox, QPushButton, QRadioButton, QToolButton,这四个按钮都继承自QAbstractButton,所以他们Check状态的变化都由QAbstractButton来控制。要使用按钮的Check状态前提需要设置属性checkable为true。

通常每次点击按钮都会改变按钮的Check状态,看一下Qt如何实现的:

void QAbstractButton::nextCheckState()

This virtual handler is called when a button is clicked. The default implementation calls setChecked(!isChecked()) if the button isCheckable(). It allows subclasses to implement intermediate button states.

在按钮设置checkable为true时,当按钮被点击的时候nextCheckState方法被调用,而默认实现是调用setChecked(!isChecked())方法,也可以通过子类实现不同的按钮状态。

所以简单的来讲在每次点击按钮的时候其实就是调用了setChecked(!isChecked())方法。

这里我重写了QToolButton,并重写了mousePressEvent、mouseReleaseEvent、nextCheckState、checkStateSet方法,并对pressed、clicked、released信号绑定了不同的槽:

    connect(this, SIGNAL(pressed()), this, SLOT(onMousePress()));    connect(this, SIGNAL(clicked()), this, SLOT(onMouseClicked()));    connect(this, SIGNAL(released()), this, SLOT(onMouseRelease()));

点击按钮后输出:

this is mousePressEvent Fuctionthis is onMousePress Fuctionthis is mouseReleaseEvent Fuctionthis is nextCheckState Fuctionthis is onMouseRelease Fuctionthis is onMouseClicked Fuction

根据上面的调用顺序我们可以在相应的地方去调用setChecked方法来设置按钮的Check状态。需要注意的是setChecked方法不是随便用的。如果我们想每次按钮点击的时候都将按钮的Check状态设置为true,在mousePressEvent或者onMousePress或者mouseReleaseEvent方法中去调用setChecked(true),那么在nextCheckState方法中会调用setChecked(!isChecked());这样的话每次点击按钮之后,按钮的Check状态都会设置为false。

关于checkStateSet方法的调用,看一下Qt中对这个方法的描述:

void QAbstractButton::checkStateSet()

This virtual handler is called when setChecked() is used, unless it is called from within nextCheckState(). It allows subclasses to reset their intermediate button states.

当调用setChecked方法时会自动调用checkStateSet方法,而在nextCheckState方法中调用setChecked方法时则不会调用。当然在checkStateSet方法内部调用setChecked方法的话也会自动调用本身,会导致进入到一个死循环中导致程序崩溃,所以不能在checkStateSet内部设置按钮Check状态。

重新设置QToolButton菜单按钮区域的新功能

我们在给QToolButton进行设置setPopupMode(QToolButton::MenuButtonPopup);(带弹出式菜单)时,再设置一个菜单变量setMenu(m_menu); 这样在我们点击QToolButton菜单区域部分会弹出自定义菜单,如下图:

但是这样我们点击QToolButton菜单区域部分只能弹出之前设置的菜单,没有可拓展性。所以我们可以获取QToolButton右边菜单的区域,在鼠标点击这块区域时我们可以有不同的实现。下面是在mousePressEvent中获取到QToolButton菜单区域,然后判断当前鼠标是否点击在该区域中。

void MyToolButton::mousePressEvent(QMouseEvent *event){    QStyleOptionToolButton styleIOption;    initStyleOption(&styleIOption);    if (Qt::LeftButton == event->button() && MenuButtonPopup == popupMode())    {        // 获取QToolButton右边菜单按钮的区域;        QRect popupButtonRect = style()->subControlRect(QStyle::CC_ToolButton, &styleIOption, QStyle::SC_ToolButtonMenu, this);        if (popupButtonRect.isValid() && popupButtonRect.contains(event->pos()))        {            //在这里实现不同的功能,我这里是根据鼠标点击的位置显示菜单            if (this->isChecked())            {                m_menu->exec(event->globalPos());            }            // 可以向外发出信号            //emit signalToolMenuClicked();        }    }    qDebug() << "this is mousePressEvent Fuction";    QToolButton::mousePressEvent(event);}

下图为根据鼠标点击的位置显示菜单:

下图为点击菜单区域弹出窗口:

仔细看下图的菜单小箭头的颜色变化,不知道算不算上是QQ的一个bug。不过这只是一个小细节,纯属好玩发现的。(鼠标第一次点击小箭头变成黑色,再次点击变成灰色,后面连续点击任然是灰色,当鼠标离开这个控件区域后,再次点击变成黑色。也就是说在每次鼠标第一次进入到菜单按钮区域时点击小箭头会变黑色后面再次点击变灰色,可能个人想法不同,实现方案也不同。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
wpf控件
android listview会重复显示的问题 | 老狼博客
c – QLayout和离散小部件表示 – 如何?
Qt 按钮设置样式表
Qt----常用的基本组件按钮组(Buttons)常用方法
Android布局的一些属性和开关、创建log图片
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服