如何查找包含QtVirtualKeyboard的窗口



我在嵌入式设备上使用qt小部件,虚拟键盘有问题。键盘显示为全屏,并与所有应用程序重叠。

在文章中,Yocto的虚拟键盘顶部黑屏描述了破解如何解决这个问题。

简而言之,您需要找到带有键盘的QQuickWindow,并在此窗口上调用setMask。然后键盘上方的区域将是透明的

我有问题如何找到QQuickWindow与虚拟键盘。我试着用

QApplication::allWidgets()

但是窗户不在这儿。

要获得所有窗口,您可以使用QGuiApplication::allWindows(),但这还不够,因为一开始不一定要创建QtVirtualKeyboard窗口,因此必须使用QInputMethod的visibleChanged信号。我没有使用QQuickWindow中的信息进行筛选,因为通常应用程序可能有其他信息,而是使用窗口所属的类的名称。

#include <QApplication>
#include <QWindow>
#include <cstring>
static void handleVisibleChanged(){
if (!QGuiApplication::inputMethod()->isVisible())
return;
for(QWindow * w: QGuiApplication::allWindows()){
if(std::strcmp(w->metaObject()->className(), "QtVirtualKeyboard::InputView") == 0){
if(QObject *keyboard = w->findChild<QObject *>("keyboard")){
QRect r = w->geometry();
r.moveTop(keyboard->property("y").toDouble());
w->setMask(r);
return;
}
}
}
}
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication a(argc, argv);
QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::visibleChanged, &handleVisibleChanged);
// ...

Python版本:

import os
import sys
from PySide2 import QtCore, QtGui, QtWidgets
# from PyQt5 import QtCore, QtGui, QtWidgets

def handleVisibleChanged():
if not QtGui.QGuiApplication.inputMethod().isVisible():
return
for w in QtGui.QGuiApplication.allWindows():
if w.metaObject().className() == "QtVirtualKeyboard::InputView":
keyboard = w.findChild(QtCore.QObject, "keyboard")
if keyboard is not None:
r = w.geometry()
r.moveTop(keyboard.property("y"))
w.setMask(QtGui.QRegion(r))
return

def main():
os.environ["QT_IM_MODULE"] = "qtvirtualkeyboard"
app = QtWidgets.QApplication(sys.argv)
QtGui.QGuiApplication.inputMethod().visibleChanged.connect(handleVisibleChanged)
w = QtWidgets.QLineEdit()
w.show()
sys.exit(app.exec_())

if __name__ == "__main__":
main()

我有一个解决方案,适用于将Raspberry与PyQt5一起使用的人。为了完成eyllanesc的答案,因为Python版本不适用于PyQt5,事实上,我们有这个问题:

TypeError:setMask(self,QRegion(:参数1具有意外类型"QRect">

要解决它:

def handleVisibleChanged():
if not QtGui.QGuiApplication.inputMethod().isVisible():
return
for w in QtGui.QGuiApplication.allWindows():
if w.metaObject().className() == "QtVirtualKeyboard::InputView":
keyboard = w.findChild(QtCore.QObject, "keyboard")
if keyboard is not None:
region = w.mask()
rect = [w.geometry()]
rect[0].moveTop(keyboard.property("y"))
region.setRects(rect)
w.setMask(region)
return

您可以将findChildren与继承QObject的任何类(如QApplication(一起使用。例如main.cpp:

QApplication a(argc, argv);
QList<QQuickWindow *> wind = a.findChildren<QQuickWindow *>();

这将为您提供一个指向应用程序中所有QQuickWindow的指针列表。

最新更新