Qt 按钮被遮挡,点击响应

Qt的按钮有时候不能满足我们的需求,

例如我们想在按钮的特殊几个部分显示不同的文字。

按钮不支持这么复杂的操作,重载一种按钮,费时费力。

简单的做法:在按钮上覆盖一层QLabel,

1:设置背景透明:background-color: rgba(255, 255, 255, 0);

2:设置QLabel不响应点击事件: m_mUI.label_afoamt->setAttribute(Qt::WA_TransparentForMouseEvents, true);


更复杂的做法:

ison_jaro的帖子提到的做法很好。

问题:

1. 绿色区域内用界面布局设置了上下左右4个按钮,这4个按钮必须能够响应点击操作(click事件);
2. 红色控件为可拖拽控件(响应按住鼠标左键并移动鼠标),它在绿色区域后面时拖拽不会失效(现在会失效);

Qt 按钮被遮挡,点击响应_第1张图片


解决方案:

1. 查找QT源代码中用到Qt::WA_TransparentForMouseEvents的地方,发现在QApplication的widgetAt()和QWidget的childAt()方法中用到了。说明这个属性只会影响控件的查找,而不是事件的传递:

2. QWidget::mousePressEvent()调的是event->ignore();QAbstractButton::mousePressEvent调用的是event->accept();。
3. 打印接收到鼠标事件的控件名,发现调用event->ignore()之后,消息被传递给了父控件,而调用event->accept();之后消息就不再传递了。

根据这3个条件,可以让绿色控件截获到鼠标事件后,“绕过”自己,向后面的控件发送消息:


void  绿色控件::mouseMoveEvent( QMouseEvent *e )
{
     QWidget::mouseMoveEvent(e);
     MyMouseEvent(e);
}
 
void  绿色控件::mousePressEvent( QMouseEvent *e )
{
     QWidget::mousePressEvent(e);
     MyMouseEvent(e);
}
 
void  绿色控件::mouseReleaseEvent( QMouseEvent *e )
{
     QWidget::mouseReleaseEvent(e);
     MyMouseEvent(e);
}
 
void  绿色控件::mouseDoubleClickEvent( QMouseEvent *e )
{
     QWidget::mouseDoubleClickEvent(e);
     MyMouseEvent(e);
}
 
void  绿色控件::MyMouseEvent( QMouseEvent *e )
{
     if  ( this ->parentWidget())
     {
         // 将自己设为鼠标事件透明并重新搜索是否有后面的控件会响应鼠标事件。
         this ->setAttribute(Qt::WA_TransparentForMouseEvents,  true );
         QPoint pt =  this ->mapTo( this ->parentWidget(), e->pos());
         QWidget *w =  this ->parentWidget()->childAt(pt);
         if  (w)
         {
             pt = w->mapFrom( this ->parentWidget(), pt);
             QMouseEvent *event =  new  QMouseEvent(e->type(), pt, e->button(), e->buttons(), e->modifiers());
             QApplication::postEvent(w, event);
         }
         // 将自己设为鼠标事件不透明,以免影响button的功能
         this ->setAttribute(Qt::WA_TransparentForMouseEvents,  false );
     }
}



你可能感兴趣的:(笔记)