背景:
我只是想處理焦點動作,由于懶,上網一搜,排名靠前的一位朋友,使用重寫部件的方式實現。還是因為懶,所以感覺復雜了。于是又花了一分鐘解決了一下。
所以記錄下來,以免以后忘了。
思路:
事件過濾器是個好東西。
在vs里,從6.0到.net,為什么很多人評價說人家編程優雅,確實好用。代碼自動格式化,各種事件特別全。
在qt里面轉到槽,就簡單的幾個信號。大部分還是要靠事件過濾器細分。其實,qt內部已經準備了很多最基礎的信號(事件),只是需要多這樣一步。
插曲:之前跟同事聊,有些事實現起來不愿意多想,閑聊一句:qt能干這事不?也是隨口一句回答:c++都不行還什么能行?這句隨口一答,當時是我即興發揮,沒考慮負不負責任。但卻成了后來qt之旅的信心來源。
言歸正傳。
先說一種場景,比如窗體上放一個文本框,我希望它永遠是焦點,也就是說,只要焦點離開,就setfocus。不討論實用性,只討論方法。以前在js中就實現過。
所以,第一步要做的是先看QEvent幫助,確認里面支持。于是看到:enum QEvent::Type中有
QEvent::FocusIn和QEvent::FocusOut,這就行了。我們只用到QEvent::FocusOut。
?
方法:
給文本框安裝事件過濾器,窗體代碼中重寫eventFilter函數,并在其中判斷event->type()。代碼如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;bool eventFilter(QObject *watched, QEvent *event);
};#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);ui->lineEdit->installEventFilter(this);
}MainWindow::~MainWindow()
{delete ui;
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{if (watched == ui->lineEdit && event->type() == QEvent::FocusOut){ui->lineEdit->setFocus();return true;}return QWidget::eventFilter(watched, event);
}
然后直接運行看效果,始終是這個文本框獲得焦點,無論鼠標點擊別處,或者tab鍵切換焦點。
總結:
所以,核心思想還是充分理解事件過濾器,相當好用。
本文完。