Qt Focus事件处理及eventFilter的用法

方法一:

描述:一开始我要实现的目的就是,在一个窗体上有多个可编辑控件(比如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);
}

 转载自: http://www.cnblogs.com/hicjiajia/archive/2012/05/30/2526776.html

 
 

你可能感兴趣的:(Qt Focus事件处理及eventFilter的用法)