Qt獲得和失去焦點事件(Focus事件)
1.重寫控制元件的focusInEvent()和focusOutEvent()函式
針對一個視窗上的多個可編輯控制元件(比如QLineEdit、QTextEdit等),我們希望控制元件在獲得焦點之後能夠和其他的控制元件有區別,如果想實現這一功能,就要用到focusInEvent()和focusOutEvent()函式。查看了官方文件,可以在子類中重寫這兩個函式來實現我們的目的。既然是要控制元件得到焦點改變動作,則應該重寫控制元件的focusInEvent()和focusOutEvent()函式,這裡以QLineEdit為例進行說明。重寫QLineEdit類,重新定義這兩個處理函式,然後在主程式中使用重寫之後的類,記得要包含重寫的QLineEdit標頭檔案,具體程式碼如下:
// MYLINEEDIT_H
#ifndef MYLINEEDIT_H
#define MYLINEEDIT_H
#include <QLineEdit>
class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
MyLineEdit(QWidget *parent=0);
~MyLineEdit();
protected:
virtual void focusInEvent(QFocusEvent *e);
virtual void focusOutEvent(QFocusEvent *e);
};
#endif // MYLINEEDIT_H
`
//myLineEdit.cpp
#include "myLineEdit.h"
MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent)
{
}
MyLineEdit::~MyLineEdit()
{
}
void MyLineEdit::focusInEvent(QFocusEvent *e)
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::green); //QPalette::Base 對可編輯輸入框有效,還有其他型別,具體的檢視文件
setPalette(p);
}
void MyLineEdit::focusOutEvent(QFocusEvent *e)
{
QPalette p1=QPalette();
p1.setColor(QPalette::Base,Qt::white);
setPalette(p1);
}
`
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "MyLineEdit.h"
#include <QGridLayout>
#include <QMessageBox>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
init();
}
Widget::~Widget()
{
delete ui;
}
void Widget::init()
{
lineEdit1=new MyLineEdit(this);
lineEdit2=new MyLineEdit(this);
gridLayout=new QGridLayout;
gridLayout->addWidget(lineEdit1,0,0);
gridLayout->addWidget(lineEdit2,1,0);
setLayout(gridLayout);
}
執行上面的程式,當QLineEdit獲得焦點後背景自動填充為綠色,失去焦點後背景恢復白色,這樣就達到了我想要的焦點高亮背景提醒功能,但是實際分析想來還是很複雜的,假如我的程式還有QTextEdit、QSpinBox等等控制元件,那我還要全部都重寫這些類,這樣還是比較麻煩的。
2.事件過濾器(eventFilter)
Qt的事件模型中提供的事件過濾功能使得一個QObject物件可以監視另一個QObject物件中的事件,通過在一個QObject物件中安裝事件過濾器可以在事件到達該物件前捕獲事件,從而起到監視該物件事件的效果。
實現類似功能的另一種方式是通過分別繼承不同的控制元件類,並重構各控制元件的事件響應函式,但若窗體中包含大量不同的控制元件時,每一個控制元件都必須重新繼承,然後分別重構不同的事件函式,實現比較複雜。事件過濾器可以實現在窗體中監視全部控制元件的不同事件,方便實現功能擴充套件。
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
public slots:
bool eventFilter(QObject *,QEvent *); // 注意這裡
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
`
#include "widget.h"
#include "ui_widget.h"
#include <QPalette>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ui->lineEdit1->installEventFilter(this); // 在窗體上為lineEdit1安裝過濾器
ui->lineEdit2->installEventFilter(this); // 在窗體上為lineEdit2安裝過濾器
}
Widget::~Widget()
{
delete ui;
}
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if (watched==ui->lineEdit1) // 首先判斷控制元件(這裡指 lineEdit1)
{
if (event->type()==QEvent::FocusIn) // 然後再判斷控制元件的具體事件 (這裡指獲得焦點事件)
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::green);
ui->lineEdit1->setPalette(p);
}
else if (event->type()==QEvent::FocusOut) // 這裡指 lineEdit1 控制元件的失去焦點事件
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::white);
ui->lineEdit1->setPalette(p);
}
}
if (watched==ui->lineEdit2) // 這裡來處理 lineEdit2 , 和處理lineEdit1 是一樣的
{
if (event->type()==QEvent::FocusIn)
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::green);
ui->lineEdit2->setPalette(p);
}
else if (event->type()==QEvent::FocusOut)
{
QPalette p=QPalette();
p.setColor(QPalette::Base,Qt::white);
ui->lineEdit2->setPalette(p);
}
}
return QWidget::eventFilter(watched,event); // 最後將事件交給上層對話方塊
}
3.動態按鈕
描述:滑鼠未按下時沒有任何反應,當滑鼠左鍵按下時圖片變大,鬆開滑鼠後又恢復原來的狀態,這個上面的事件過濾是一個道理,就是監聽按鈕的按下事件(QEvent::MouseButtonPress)和釋放事件(QEventButtonRelease)
bool EventFilter::eventFilter(QObject *watched,QEvent *event)
{
if (watched==Label1)
{
if (event->type()==QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent=static_cast<QMouseEvent *>event;
if (mouseEvent->buttons() && Qt::LeftButton)
{ // 更換一張大一點的圖片 ..........
}
if (event->type()==QEvent::MouseButtonRelease)
{ // 重新換回最初那張圖片 ...........
}
return QWidget::eventFilter(watched,event);
}