Qt焦点事件
2013-07-23 10:17
519 查看
在我的前一篇文章<focusInEvent()与focusOutEvent>中,我实现了QLineEdit获得焦点高亮显示与失去焦点恢复原样的操作,是通过重新继承该类,再重构该事件函数的方式。这篇文章紧跟那篇文章,这里要实现的功能也是一样的,而是通过另外不同的方式——事件过滤器(eventFilter)。
Qt的事件模型中提供的事件过滤功能使得一个QObject对象可以监视另一个QObject对象中的事件,通过在一个QObject对象中安装事件过滤器可以在事件到达该对象前捕获事件,从而起到监视该对象事件的效果。
实现类似功能的另一种方式是通过分别继承不同的控件类,并重构各控件的事件响应函数,但若窗体中包含大量不同的控件时,每一个控件都必须重新继承,然后分别重构不同的事件函数,实现比较复杂。事件过滤器可以实现在窗体中监视全部控件的不同事件,方便实现功能扩展。
`
[cpp] view
plaincopy
#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
`
[cpp] view
plaincopy
#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)
`
[cpp] view
plaincopy
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);
}
评论 (1)
QTabWidget
类归于: Qt — mingw32 @ 1:47 上午
哈哈,这个暑假在家里学习Qt,有了一些理论知识后,就想动手搞个什么小东西,在Qt Demo中看到了一个简单的文本编辑器,我就研究它了,当然Qt带的这个例子功能十分简单,经过几天不断的摸索和实践我也搞了一个类似的,不过功能要强大,而且比Windows 默认带的那个记事本也要强,呵呵,后来就想继续扩充功能,时下十分流行的那个功能“一个窗口多个标签页显示”就如IE8那种,可以在一个窗口打开多个网页,在Qt中当然要用QTabWidget,但是据我所知这个控件并没有提供关闭按钮,这个很麻烦了,google一晚上,在国外某个论坛上看到了解决方案:在Qt
4.5 中 QTabWidget 多了一个属性 tabsClosable ,将其设置为True即可出现关闭按钮。先来张截图吧:
默认情况下,每个标签上的关闭按钮是没有任何响应的,我们需要自己动手为他添加关闭响应。
关闭信号为 void tabCloseRequested(int index)
关闭函数为 void removeTab(int index)
注意关闭标签的是一个普通公共函数,不是槽函数,不可以直接与信号相连,我们需要自己手动定义个接受 int类型的槽函数,然后把参数再传递给关闭函数。
`
[cpp] view
plaincopy
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTabWidget>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->tabWidget,SIGNAL(tabCloseRequested(int)),this,SLOT(removeSubTab(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::removeSubTab(int index)
{
ui->tabWidget->removeTab(index);
}
void MainWindow::on_pushButton_clicked()
{
QTextEdit *edit=new QTextEdit;
ui->tabWidget->addTab(edit,"hitemp 1");
}
评论 (0)
描述:一开始我要实现的目的就是,在一个窗体上有多个可编辑控件(比如QLineEdit、QTextEdit等),当哪个控件获得焦点,哪个控件的背景就高亮用来起提示作用,查了下文档应该用focusInEvent()和focusOutEvent(), 在实际过程中,我犯了十分严重的错误,最开始的时候我是这样做的:我重写了窗体QWidget的这两个函数,然后再在函数体中把QFocusEvent事件传递给窗体上的QLineEdit控件:
[cpp] view
plaincopy
void Widget::focusInEvent(QFocusEvent *event)
{
QLineEdit::focusInEvent(event);
.....
}
编译的时候报错,说是没有调用对象什么的,后来问了下朋友才得到了完美的答案:
既然是要控件得到焦点改变动作,则应该重写该控件的focusInEvent()和focusOutEvent(),即重写QLineEdit类,再重新定义这两个处理函数,然后再在主程序中,include 我们自己重写的QLineEdit头文件,具体代码如下:
[cpp] view
plaincopy
// 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
`
[cpp] view
plaincopy
//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);
}
`
[cpp] view
plaincopy
//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);
}
上图为程序范例,当某个文本框获得焦点后背景自动填充为绿色,失去焦点后背景恢复白色,这样就达到了我想要的焦点高亮背景提醒功能,但是实际分析想来还是很复杂的,假如我的程序还有QTextEdit、QSpinBox等等控件,那我还要全部都重写这些类,麻烦…我原本以为Qt提供了这种获得与失去焦点的信号,可惜没有,期待以后版本加上,就更加方便了…
Qt的事件模型中提供的事件过滤功能使得一个QObject对象可以监视另一个QObject对象中的事件,通过在一个QObject对象中安装事件过滤器可以在事件到达该对象前捕获事件,从而起到监视该对象事件的效果。
实现类似功能的另一种方式是通过分别继承不同的控件类,并重构各控件的事件响应函数,但若窗体中包含大量不同的控件时,每一个控件都必须重新继承,然后分别重构不同的事件函数,实现比较复杂。事件过滤器可以实现在窗体中监视全部控件的不同事件,方便实现功能扩展。
`
[cpp] view
plaincopy
#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
`
[cpp] view
plaincopy
#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)
`
[cpp] view
plaincopy
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);
}
评论 (1)
QTabWidget
使用小记
类归于: Qt — mingw32 @ 1:47 上午哈哈,这个暑假在家里学习Qt,有了一些理论知识后,就想动手搞个什么小东西,在Qt Demo中看到了一个简单的文本编辑器,我就研究它了,当然Qt带的这个例子功能十分简单,经过几天不断的摸索和实践我也搞了一个类似的,不过功能要强大,而且比Windows 默认带的那个记事本也要强,呵呵,后来就想继续扩充功能,时下十分流行的那个功能“一个窗口多个标签页显示”就如IE8那种,可以在一个窗口打开多个网页,在Qt中当然要用QTabWidget,但是据我所知这个控件并没有提供关闭按钮,这个很麻烦了,google一晚上,在国外某个论坛上看到了解决方案:在Qt
4.5 中 QTabWidget 多了一个属性 tabsClosable ,将其设置为True即可出现关闭按钮。先来张截图吧:
默认情况下,每个标签上的关闭按钮是没有任何响应的,我们需要自己动手为他添加关闭响应。
关闭信号为 void tabCloseRequested(int index)
关闭函数为 void removeTab(int index)
注意关闭标签的是一个普通公共函数,不是槽函数,不可以直接与信号相连,我们需要自己手动定义个接受 int类型的槽函数,然后把参数再传递给关闭函数。
`
[cpp] view
plaincopy
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTabWidget>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->tabWidget,SIGNAL(tabCloseRequested(int)),this,SLOT(removeSubTab(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::removeSubTab(int index)
{
ui->tabWidget->removeTab(index);
}
void MainWindow::on_pushButton_clicked()
{
QTextEdit *edit=new QTextEdit;
ui->tabWidget->addTab(edit,"hitemp 1");
}
评论 (0)
2010年07月27日
focusInEvent()与focusOutEvent()
类归于: Qt — mingw32 @ 1:05 上午描述:一开始我要实现的目的就是,在一个窗体上有多个可编辑控件(比如QLineEdit、QTextEdit等),当哪个控件获得焦点,哪个控件的背景就高亮用来起提示作用,查了下文档应该用focusInEvent()和focusOutEvent(), 在实际过程中,我犯了十分严重的错误,最开始的时候我是这样做的:我重写了窗体QWidget的这两个函数,然后再在函数体中把QFocusEvent事件传递给窗体上的QLineEdit控件:
[cpp] view
plaincopy
void Widget::focusInEvent(QFocusEvent *event)
{
QLineEdit::focusInEvent(event);
.....
}
编译的时候报错,说是没有调用对象什么的,后来问了下朋友才得到了完美的答案:
既然是要控件得到焦点改变动作,则应该重写该控件的focusInEvent()和focusOutEvent(),即重写QLineEdit类,再重新定义这两个处理函数,然后再在主程序中,include 我们自己重写的QLineEdit头文件,具体代码如下:
[cpp] view
plaincopy
// 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
`
[cpp] view
plaincopy
//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);
}
`
[cpp] view
plaincopy
//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);
}
上图为程序范例,当某个文本框获得焦点后背景自动填充为绿色,失去焦点后背景恢复白色,这样就达到了我想要的焦点高亮背景提醒功能,但是实际分析想来还是很复杂的,假如我的程序还有QTextEdit、QSpinBox等等控件,那我还要全部都重写这些类,麻烦…我原本以为Qt提供了这种获得与失去焦点的信号,可惜没有,期待以后版本加上,就更加方便了…
相关文章推荐
- Qt中的键盘事件,以及焦点的设置(比较详细)
- Qt获得焦点和失去焦点处理事件 (Focus事件)
- Qt获得焦点和失去焦点处理事件 (Focus事件)
- Qt中的焦点事件
- Qt中的键盘事件以及焦点设置
- QT 焦点事件(4种方式的解释,还有委托焦点)
- Qt中的焦点事件
- Qt获得焦点和失去焦点处理事件 (Focus事件)
- Qt之Tab键实现(自由切换焦点)—— 采用事件过滤器处理
- Qt获得焦点和失去焦点处理事件 (Focus事件)
- Qt中使用事件过滤器来处理键盘焦点
- Qt焦点事件
- Qt焦点事件
- qt焦点事件响应捕捉处理,事件过滤器
- Qt获得焦点和失去焦点处理事件 (Focus事件)
- Qt焦点事件
- 关键词:键盘触发事件、QList用法、清除/获得焦点、CSS、Qt初学教程
- Qt中的焦点事件
- Qt获得焦点和失去焦点处理事件 (Focus事件)
- Qt QTableView焦点事件