1. 程式人生 > >Qt 按鈕被遮擋,點選響應

Qt 按鈕被遮擋,點選響應

Qt的按鈕有時候不能滿足我們的需求,

例如我們想在按鈕的特殊幾個部分顯示不同的文字。

按鈕不支援這麼複雜的操作,過載一種按鈕,費時費力。

簡單的做法:在按鈕上覆蓋一層QLabel,

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

2:設定QLabel不響應點選事件: m_mUI.label_afoamt->setAttribute(Qt::WA_TransparentForMouseEvents, true);

更復雜的做法:

問題:

1. 綠色區域內用介面佈局設定了上下左右4個按鈕,這4個按鈕必須能夠響應點選操作(click事件);
2. 紅色控制元件為可拖拽控制元件(響應按住滑鼠左鍵並移動滑鼠),它在綠色區域後面時拖拽不會失效(現在會失效);


解決方案:

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); } }