QLineEdit的焦点事件

前言

在项目中,遇到了在通过焦点事件调用系统输入法显示异常的情况,后来发现问题发生在焦点事件上,在调用输入法以及关闭输入法的时候出现了焦点的转移,这就导致输入法一直被调用。
就特意研究了一下Qt的焦点事件,以及通过QLineEdit进行一些测试操作。

焦点事件

在应用程序中,都会有一个当前窗口,即当前获得焦点事件的窗口,这个窗口可以接受键盘的输入
焦点事件分为FocusInFocusOut,也就是获得焦点失去焦点两种情况。

QLineEdit焦点事件测试

接下来就是测试了,为了结果的可靠性,这里分为两种方式进行验证:事件过滤器、重写QLineEdit。

使用事件过滤器的方式

源码如下:

#include "QLineEdtFocusEventTest.h"
#include "windows.h"
#include <QMessageBox>

QLineEdtFocusEventTest::QLineEdtFocusEventTest(QWidget *parent)
	: QMainWindow(parent)
	, m_pMessageBox(new QMessageBox(this))
{
	ui.setupUi(this);

	ui.lineEdit->installEventFilter(this);
	ui.lineEdit->setFocusPolicy(Qt::ClickFocus);
}

bool QLineEdtFocusEventTest::eventFilter(QObject * watched, QEvent * event)
{
	static int inTime = 0;
	static int outTime = 0;
	if (ui.lineEdit == watched)
	{
		if (event->type() == QEvent::FocusIn)
		{
			ShellExecute(NULL, L"open", L"C:/Program Files/Common Files/Microsoft Shared/ink/TabTip.exe", NULL, NULL, SW_SHOWNA);
			ui.intimeLbl->setText(QString::number(++inTime));
		}
		else if (event->type() == QEvent::FocusOut)
		{
			ui.outtimeLbl->setText(QString::number(++outTime));
			DWORD WM_DESKBAND_CLICKED = ::RegisterWindowMessage(L"TabletInputPanelDeskBandClicked");
			HWND hWnd = ::FindWindow(L"IPTip_Main_Window", NULL);
			if (hWnd != NULL && ::IsWindowVisible(hWnd))
			{
				::PostMessage(hWnd, WM_DESKBAND_CLICKED, 0, 0);
			}
		}
	}

	return QMainWindow::eventFilter(watched, event);
}

测试的结果为,在点击QLineEdit文本框的时候,会触发FocusIn事件,然后就会调出输入法;但是在调用输入法的过程中,QLineEdit将会触发FocusOut失去焦点事件;在关闭输入法之后,又会触发QLineEdit的FocusIn事件,如此循环往复。

重写QLineEdit的方式

源码如下:

#pragma once

#include <QLineEdit>

class MyLineEdt : public QLineEdit
{
	Q_OBJECT

signals:
	void fin();
	void fout();

public:
	MyLineEdt(QWidget *parent = nullptr);
	~MyLineEdt();

protected:
	virtual void focusInEvent(QFocusEvent *e) override;

	virtual void focusOutEvent(QFocusEvent *e) override;
};

#include "MyLineEdt.h"
#include <QMessageBox>
#include "windows.h"


MyLineEdt::MyLineEdt(QWidget *parent)
	: QLineEdit(parent)
{
}

MyLineEdt::~MyLineEdt()
{
}

void MyLineEdt::focusInEvent(QFocusEvent * e)
{
	emit fin();

	ShellExecute(NULL, L"open", L"osk.exe", NULL, NULL, SW_SHOWNORMAL);
}

void MyLineEdt::focusOutEvent(QFocusEvent *e)
{
	emit fout();


	DWORD WM_DESKBAND_CLICKED = ::RegisterWindowMessage(L"TabletInputPanelDeskBandClicked");
	HWND hWnd = ::FindWindow(L"IPTip_Main_Window", NULL);
	if (hWnd != NULL && ::IsWindowVisible(hWnd))
	{
		::PostMessage(hWnd, WM_DESKBAND_CLICKED, 0, 0);
	}
}
#include "QLineEdtFocusEventTest.h"
#include "windows.h"
#include <QMessageBox>

QLineEdtFocusEventTest::QLineEdtFocusEventTest(QWidget *parent)
	: QMainWindow(parent)
	, m_pMessageBox(new QMessageBox(this))
{
	ui.setupUi(this);

	ui.lineEdit->setFocusPolicy(Qt::ClickFocus);

	connect(ui.lineEdit, SIGNAL(fin()), this, SLOT(onfin()));
	connect(ui.lineEdit, SIGNAL(fout()), this, SLOT(onfout()));
}

void QLineEdtFocusEventTest::onfout()
{
	static int i{ 1 };
	ui.outtimeLbl->setText(QString::number(i++));
}

void QLineEdtFocusEventTest::onfin()
{
	static int i{ 1 };
	ui.intimeLbl->setText(QString::number(i++));
}

测试结果同使用事件过滤器的方式相同。

操作系统对于焦点事件的影响

后为了严谨性,更换了操作系统进行测试,当前使用的是Windows10操作系统,现更换为Windows7操作系统。
后发现在Windows7操作系统中,在调用输入法的过程中没有丢失焦点
我当时的表情就是这样的:ヾ(。ꏿ﹏ꏿ)ノ゙。
原因未知,没有查到这方面的资料,如果读者知晓这方面的原因的话,还请在评论区留言,不胜感谢。

结论

在Windows10操作系统中,如果涉及到调用其他软件或界面的情况,最好不要采用焦点事件的方式,在Windows7中倒是没有这个顾忌。

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值