QT QLineEdit失去焦点事件问题与解决
本文介绍如何获得QLineEdit的失去焦点事件和获得焦点的输入框也会触发失去焦点事件的问题!
目录
一、QLineEdit获得失去焦点事件
1.自定义类继承自QLineEdit
class LineEditFocus : public QLineEdit {
Q_OBJECT
public:
explicit LineEditFocus(QWidget *parent = nullptr) { }
~LineEditFocus() override { }
}
2.重写 focusOutEvent
protected:
// 焦点离开
void focusOutEvent(QFocusEvent *event) override { }
// 获得焦点
void focusInEvent(QFocusEvent *event) override { }
当获得焦点时,focusInEvent方法会被触发;当失去焦点时,focusOutEvent方法会被触发;
然后就可以在方法内部做一些我们的需求处理,例如可以通过信号与槽通知主程序等;
3.使用
直接使用我们自定义的类,创建LineEditFocus对象即可;
如果使用的是ui布局中的部件,那么可以将部件提升为我们自定义的LineEditFocus即可;
二、失去焦点事件问题
1.问题描述
如果有多个输入框部件,且当前输入框部件失去焦点,且另一个获得焦点的部件不是输入框时,那么是没有问题的!
如果当前输入框失去焦点,且另一个获得焦点的部件也是输入框,那么这样就会出现问题;
会优先触发另一个输入框的失去焦点事件,然后才会触发当前输入框的失去焦点事件,最后再触发另一个输入框的获得焦点事件!!!
案例:
(1).继续在自定义类中添加信号 ;可以根据个人需求传输参数值,例如可以将当前输入框的文本传送;
signals:
void signalLoseFocus(int index);
(2).然后在失去焦点方法中,触发此信号
void LineEditFocus::focusOutEvent(QFocusEvent *event)
{
static int index = 1;
emit signalLoseFocus(index++);
QLineEdit::focusOutEvent(event);
}
(3).最后在主窗体中使用即可(ui部件,提升即可)
void Widget::init()
{
LineEditFocus *le1 = new LineEditFocus(this);
LineEditFocus *le2 = new LineEditFocus(this);
LineEditFocus *le3 = new LineEditFocus(this);
QList<LineEditFocus *> list;
list << le1 << le2 << le3;
foreach (LineEditFocus *lef, list) {
lef->setFixedSize(350, 50);
connect(lef, &LineEditFocus::signalLoseFocus, this, &Widget::onLeaveFocus);
}
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(le1);
layout->addWidget(le2);
layout->addWidget(le3);
this->setLayout(layout);
}
(4).在槽函数中将接收到的index,通过messagebox提示出来
void Widget::onLeaveFocus(int index)
{
QMessageBox::information(this, "提示", QString("输入框焦点离开:%1").arg(index));
}
(5).运行效果
可以看出,确实是有问题的!
2.问题解决
具体是什么原因导致出现这样的问题,我也没搞明白;
但是办法总比困难多,我们转换一下思路去解决他;
(1).增加变量用于标志是否获取到了焦点
private:
// 焦点获得标志
bool m_focus;
(2).焦点获得,获得焦点时,m_focus赋值true
void LineEditFocus::focusInEvent(QFocusEvent *event)
{
m_focus = true; // 标志当前编辑框已经获得焦点
QLineEdit::focusInEvent(event);
}
(3).失去焦点,通过m_focus变量辅助配合判断
void LineEditFocus::focusOutEvent(QFocusEvent *event)
{
if (m_focus && event->lostFocus()) { // event->lostFocus(): type() == FocusOut
m_focus = false; // 焦点失去
emit signalLoseFocus(m_index);
}
QLineEdit::focusOutEvent(event);
}
通过上面的测试可知,当从第一个输入框点击第二个输入框时,优先触发第二个输入框的失去焦点事件,此时,第二个输入框是还没有获得焦点的,即m_focus变量值为false,信号就没法触发;
紧接着第一个输入框的失去焦点事件触发,因为先前已经获得了焦点,即m_focus变量值为true,所以第一个输入框的失去焦点事件可以正常发射信号;
最后才会触发第二个输入框的获得焦点事件。
(3).运行测试
问题完美解决!
三、源码分享
lineeditfocus.h
#ifndef LINEEDIT_FOCUS_H
#define LINEEDIT_FOCUS_H
#include <QLineEdit>
class LineEditFocus : public QLineEdit {
Q_OBJECT
public:
explicit LineEditFocus(QWidget *parent = nullptr);
~LineEditFocus() override;
void SetIndex(int index);
int GetIndex() const;
signals:
void signalLoseFocus(int index);
void signalInFocus(int index);
protected:
// 焦点离开
void focusOutEvent(QFocusEvent *event) override;
// 获得焦点
void focusInEvent(QFocusEvent *event) override;
private:
// 记录标志
int m_index;
// 焦点获得标志
bool m_focus;
};
#endif // LINEEDIT_FOCUS_H
lineeditfocus.cpp
#include "lineeditfocus.h"
#include <QFocusEvent>
LineEditFocus::LineEditFocus(QWidget *parent) : QLineEdit(parent)
{
m_index = 0;
m_focus = false;
}
LineEditFocus::~LineEditFocus()
{
}
void LineEditFocus::SetIndex(int index)
{
m_index = index;
}
void LineEditFocus::focusOutEvent(QFocusEvent *event)
{
if (m_focus && event->lostFocus()) { // event->lostFocus() --> return type() == FocusOut;
m_focus = false; // 焦点失去
emit signalLoseFocus(m_index);
}
QLineEdit::focusOutEvent(event);
}
void LineEditFocus::focusInEvent(QFocusEvent *event)
{
m_focus = true; // 焦点获得
QLineEdit::focusInEvent(event);
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "lineeditfocus.h"
#include <QMessageBox>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
init();
}
Widget::~Widget()
{
delete ui;
}
void Widget::init()
{
LineEditFocus *le1 = new LineEditFocus(this);
// le1->setFixedSize(350, 50);
// le1->SetIndex(1);
LineEditFocus *le2 = new LineEditFocus(this);
// le2->setFixedSize(350, 50);
// le2->SetIndex(2);
LineEditFocus *le3 = new LineEditFocus(this);
// le3->setFixedSize(350, 50);
// le3->SetIndex(3);
QList<LineEditFocus *> list;
list << le1 << le2 << le3;
int index = 1;
foreach (LineEditFocus *lef, list) {
lef->setFixedSize(350, 50);
lef->SetIndex(index++);
connect(lef, &LineEditFocus::signalLoseFocus, this, &Widget::onLeaveFocus);
}
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(le1);
layout->addWidget(le2);
layout->addWidget(le3);
this->setLayout(layout);
}
void Widget::onLeaveFocus(int index)
{
QMessageBox::information(this, "提示", QString("输入框焦点离开:%1").arg(index));
}
完!
原文地址:https://blog.csdn.net/cpp_learner/article/details/143776448
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!