Qt獲得焦點和失去焦點處理事件 (Focus事件)

方法一:

描述:一開始我要實現的目的就是,在一個窗體上有多個可編輯控件(比如QLineEdit、QTextEdit等),當哪個控件獲得焦點,哪個控件的背景就高亮用來起提示作用,查了下文檔應該用focusInEvent()和focusOutEvent(), 在實際過程中,我犯了十分嚴重的錯誤,最開始的時候我是這樣做的:我重寫了窗體QWidget的這兩個函數,然後再在函數體中把QFocusEvent事件傳遞給窗體上的QLineEdit控件:

void Widget::focusInEvent(QFocusEvent *event)
{
      QLineEdit::focusInEvent(event);
       .....
}

編譯的時候報錯,說是沒有調用對象什麼的,後來問了下朋友纔得到了完美的答案:

既然是要控件得到焦點改變動作,則應該重寫該控件的focusInEvent()和focusOutEvent(),即重寫QLineEdit類,再重新定義這兩個處理函數,然後再在主程序中,include 我們自己重寫的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獲得焦點高亮顯示與失去焦點恢復原樣的操作,是通過重新繼承該類,再重構該事件函數的方式。這篇文章緊跟那篇文章,這裏要實現的功能也是一樣的,而是通過另外不同的方式——事件過濾器(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);     // 最後將事件交給上層對話框
}
複製代碼

另外,我在一本書上看到作者有一個例子是關於動態按鈕的:鼠標未按下時沒有任何反應,當鼠標左鍵按下時圖片變大,鬆開鼠標後又恢復原來的狀態。其實這個效果和我這個例子是一個道理,也就是監聽按鈕的按下事件(QEvent::MouseButtonPress)和釋放事件(QEvent::MouseButtonRelease)

複製代碼
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);
}
複製代碼

發佈了6 篇原創文章 · 獲贊 5 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章