问题描述
我在嵌入式设备上使用qt小部件,并且虚拟键盘有问题。键盘显示为全屏,并且与所有应用程序重叠。
在文章Virtual keyboard top black screen in 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,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(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()
,
您可以将findChildren
与任何继承QObject
的类一起使用,例如QApplication
。例如在 main.cpp 中:
QApplication a(argc,argv);
QList<QQuickWindow *> wind = a.findChildren<QQuickWindow *>();
这将为您提供一个指向应用程序中所有QQuickWindow
的指针的列表。
我为将 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