Qt Focus事件处理及eventFilter的用法

Qt Focus事件处理及eventFilter的用法

方法一:

描述:一开始我要实现的目的就是,在一个窗体上有多个可编辑控件(比如QLineEdit、QTextEdit等),当哪个控件获得焦点,哪个控件的背景就高亮用来起提示作用,查了下文档应该用focusInEvent()和focusOutEvent(), 在实际过程中,我犯了十分严重的错误,最开始的时候我是这样做的:我重写了窗体QWidget的这两个函数,然后再在函数体中把QFocusEvent事件传递给窗体上的QLineEdit控件:


  
  
  1. void Widget::focusInEvent(QFocusEvent *event)
  2. {
  3. QLineEdit::focusInEvent(event);
  4. .....
  5. }

编译的时候报错,说是没有调用对象什么的,后来问了下朋友才得到了完美的答案:

既然是要控件得到焦点改变动作,则应该重写该控件的focusInEvent()和focusOutEvent(),即重写QLineEdit类,再重新定义这两个处理函数,然后再在主程序中,include 我们自己重写的QLineEdit头文件,具体代码如下:


  
  
  1. // MYLINEEDIT_H
  2. #ifndef MYLINEEDIT_H
  3. #define MYLINEEDIT_H
  4. #include <QLineEdit>
  5. class MyLineEdit : public QLineEdit
  6. {
  7. Q_OBJECT
  8. public:
  9. MyLineEdit(QWidget *parent= 0);
  10. ~MyLineEdit();
  11. protected:
  12. virtual void focusInEvent(QFocusEvent *e);
  13. virtual void focusOutEvent(QFocusEvent *e);
  14. };
  15. #endif // MYLINEEDIT_H
  16. `
  17. //myLineEdit.cpp
  18. #include "myLineEdit.h"
  19. MyLineEdit::MyLineEdit(QWidget *parent):QLineEdit(parent)
  20. {
  21. }
  22. MyLineEdit::~MyLineEdit()
  23. {
  24. }
  25. void MyLineEdit::focusInEvent(QFocusEvent *e)
  26. {
  27. QPalette p=QPalette();
  28. p.setColor(QPalette::Base,Qt::green); //QPalette::Base 对可编辑输入框有效,还有其他类型,具体的查看文档
  29. setPalette(p);
  30. }
  31. void MyLineEdit::focusOutEvent(QFocusEvent *e)
  32. {
  33. QPalette p1=QPalette();
  34. p1.setColor(QPalette::Base,Qt::white);
  35. setPalette(p1);
  36. }
  37. //widget.cpp
  38. #include "widget.h"
  39. #include "ui_widget.h"
  40. #include "MyLineEdit.h"
  41. #include <QGridLayout>
  42. #include <QMessageBox>
  43. Widget::Widget(QWidget *parent) :
  44. QWidget(parent),
  45. ui( new Ui::Widget)
  46. {
  47. ui->setupUi( this);
  48. init();
  49. }
  50. Widget::~Widget()
  51. {
  52. delete ui;
  53. }
  54. void Widget::init()
  55. {
  56. lineEdit1= new MyLineEdit( this);
  57. lineEdit2= new MyLineEdit( this);
  58. gridLayout= new QGridLayout;
  59. gridLayout->addWidget(lineEdit1, 0, 0);
  60. gridLayout->addWidget(lineEdit2, 1, 0);
  61. setLayout(gridLayout);
  62. }

方法二:

前面实现了QLineEdit获得焦点高亮显示与失去焦点恢复原样的操作,是通过重新继承该类,再重构该事件函数的方式。这里要实现的功能也是一样的,而是通过另外不同的方式——事件过滤器(eventFilter)。

Qt的事件模型中提供的事件过滤功能使得一个QObject对象可以监视另一个QObject对象中的事件,通过在一个QObject对象中安装事件过滤器可以在事件到达该对象前捕获事件,从而起到监视该对象事件的效果。

实现类似功能的另一种方式是通过分别继承不同的控件类,并重构各控件的事件响应函数,但若窗体中包含大量不同的控件时,每一个控件都必须重新继承,然后分别重构不同的事件函数,实现比较复杂。事件过滤器可以实现在窗体中监视全部控件的不同事件,方便实现功能扩展。


  
  
  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class Widget;
  6. }
  7. class Widget : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit Widget(QWidget *parent = 0);
  12. ~Widget();
  13. public slots:
  14. bool eventFilter(QObject *,QEvent *); //注意这里
  15. private:
  16. Ui::Widget *ui;
  17. };
  18. #endif // WIDGET_H
  19. `
  20. #include "widget.h"
  21. #include "ui_widget.h"
  22. #include <QPalette>
  23. Widget::Widget(QWidget *parent) :
  24. QWidget(parent),
  25. ui( new Ui::Widget)
  26. {
  27. ui->setupUi( this);
  28.   /*this指的是Widget类,下面语句意思是:要在this中监控发送给lineEdit1和lineEdit2的事件,
  29. *因此Widget中必然定义了eventFileter()
  30. */
  31. ui->lineEdit1->installEventFilter( this); //为lineEdit1安装过滤器
  32. ui->lineEdit2->installEventFilter( this); //为lineEdit2安装过滤器
  33. }
  34. Widget::~Widget()
  35. {
  36. delete ui;
  37. }
  38. bool Widget::eventFilter(QObject *watched, QEvent *event)
  39. {
  40. if (watched==ui->lineEdit1) //首先判断控件(这里指 lineEdit1)
  41. {
  42. if (event->type()==QEvent::FocusIn) //然后再判断控件的具体事件 (这里指获得焦点事件)
  43. {
  44. QPalette p=QPalette();
  45. p.setColor(QPalette::Base,Qt::green);
  46. ui->lineEdit1->setPalette(p);
  47. }
  48. else if (event->type()==QEvent::FocusOut) // 这里指 lineEdit1 控件的失去焦点事件
  49. {
  50. QPalette p=QPalette();
  51. p.setColor(QPalette::Base,Qt::white);
  52. ui->lineEdit1->setPalette(p);
  53. }
  54. }
  55. if (watched==ui->lineEdit2) //这里来处理 lineEdit2 , 和处理lineEdit1 是一样的
  56. {
  57. if (event->type()==QEvent::FocusIn)
  58. {
  59. QPalette p=QPalette();
  60. p.setColor(QPalette::Base,Qt::green);
  61. ui->lineEdit2->setPalette(p);
  62. }
  63. else if (event->type()==QEvent::FocusOut)
  64. {
  65. QPalette p=QPalette();
  66. p.setColor(QPalette::Base,Qt::white);
  67. ui->lineEdit2->setPalette(p);
  68. }
  69. }
  70. return QWidget::eventFilter(watched,event); // 最后将事件交给上层对话框
  71. }

另外,我在一本书上看到作者有一个例子是关于动态按钮的:鼠标未按下时没有任何反应,当鼠标左键按下时图片变大,松开鼠标后又恢复原来的状态。其实这个效果和我这个例子是一个道理,也就是监听按钮的按下事件(QEvent::MouseButtonPress)和释放事件(QEvent::MouseButtonRelease)


  
  
  1. bool EventFilter::eventFilter(QObject *watched,QEvent *event)
  2. {
  3. if (watched==Label1)
  4. {
  5. if (event->type()==QEvent::MouseButtonPress)
  6. {
  7. QMouseEvent *mouseEvent=static_cast <QMouseEvent *>event;
  8. if (mouseEvent->buttons() && Qt::LeftButton)
  9. { // 更换一张大一点的图片 ..........
  10. }
  11. if (event->type()==QEvent::MouseButtonRelease)
  12. { // 重新换回最初那张图片 ...........
  13. }
  14. return QWidget::eventFilter(watched,event);
  15. }

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

猜你喜欢

转载自blog.csdn.net/m0_37329910/article/details/88082372