QQuickView,切换后没有键盘焦点windows
QQuickView, no keyboard focus after switching windows
我的 cpp 应用程序有一个派生的 QMainWindow class,在 ui 中有 QQuickView 小部件。视图内部有许多接受键盘输入的 QML 项。单击某个项目时,我会在单击的项目上调用 forceActiveFocus()。从我启动应用程序到切换到另一个 window.
如果我切换到另一个应用程序并返回,或者在我的应用程序中切换到另一个 window 并返回,则调用 forceActiveFocus() 无效。这些项目有几种不同的类型,但这里有一个示例项目:
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
MouseArea {
anchors.fill: textInput
onClicked: {
textInput.forceActiveFocus()
console.log("clicked")
}
}
}
关闭时,我看到 activeFocus 在控制台上记录为 false。当我再次切换回来并单击该项目时,"clicked" 会记录到控制台,因此正在处理鼠标事件。但是,永远不会再调用 onActiveFocusChanged。
我还尝试了一个使用 FocusScope 作为项目的父项的实现,得到了相同的行为,在我点击之后焦点一直到我切换到其他 window 并再次返回的点。
更新
阅读@user2436719 的评论后,我尝试了两个最小的示例。只有在使用 QQuickView
时才会出现这个问题。这是使用 QML Window
和以下 main.qrc
的 QML 应用程序,它工作得很好:
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
color: "lightblue"
Rectangle {
id: textInputRect
color: "white"
height: 50
width: 150
anchors.centerIn: parent
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
}
}
}
第二个是带有 QMainWindow
派生 class 的 CPP 应用程序,在 ui 中有一个 QQuickView
小部件。此版本表现出问题行为。这是 main.qrc
:
import QtQuick 2.7
import QtQuick.Window 2.2
Rectangle {
anchors.fill: parent
color: "lightblue"
Rectangle {
id: textInputRect
color: "white"
height: 50
width: 150
anchors.centerIn: parent
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
}
}
}
来自QQuickView版,这里是main
:
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
MainWindow window;
QQuickView* view = new QQuickView;
window.setView(view);
window.show();
return app.exec();
}
这是我在 MainWindow
中设置 QQuickView
的方式:
void MainWindow::setView(QQuickView *value)
{
view = value;
QWidget *container = QWidget::createWindowContainer(view, this);
view->setSource(QUrl("qrc:/main.qml"));
ui->verticalLayout->addWidget(container);
}
好的,这是 QTBUG-34414。在该错误的评论底部发布了解决方法。在切换到我的应用程序的其他 windows 或其他应用程序的情况下,发布的解决方法为我解决了这个问题。关闭对话框后仍然没有焦点。将此覆盖放在我的 window class 中解决了这两种情况的问题:
bool MyWindow::event(QEvent *event)
{
if (event->type() == QEvent::ActivationChange ||
event->type() == QEvent::WindowUnblocked) {
if(view->isActive()) { //view is pointer to my QQuickView
window()->activateWindow();
return true;
}
}
// handle events that don't match
return QWidget::event(event);
}
此覆盖对我在 OSX Sierra 上的 Qt 5.7 有效。
我的 cpp 应用程序有一个派生的 QMainWindow class,在 ui 中有 QQuickView 小部件。视图内部有许多接受键盘输入的 QML 项。单击某个项目时,我会在单击的项目上调用 forceActiveFocus()。从我启动应用程序到切换到另一个 window.
如果我切换到另一个应用程序并返回,或者在我的应用程序中切换到另一个 window 并返回,则调用 forceActiveFocus() 无效。这些项目有几种不同的类型,但这里有一个示例项目:
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
MouseArea {
anchors.fill: textInput
onClicked: {
textInput.forceActiveFocus()
console.log("clicked")
}
}
}
关闭时,我看到 activeFocus 在控制台上记录为 false。当我再次切换回来并单击该项目时,"clicked" 会记录到控制台,因此正在处理鼠标事件。但是,永远不会再调用 onActiveFocusChanged。
我还尝试了一个使用 FocusScope 作为项目的父项的实现,得到了相同的行为,在我点击之后焦点一直到我切换到其他 window 并再次返回的点。
更新
阅读@user2436719 的评论后,我尝试了两个最小的示例。只有在使用 QQuickView
时才会出现这个问题。这是使用 QML Window
和以下 main.qrc
的 QML 应用程序,它工作得很好:
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
color: "lightblue"
Rectangle {
id: textInputRect
color: "white"
height: 50
width: 150
anchors.centerIn: parent
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
}
}
}
第二个是带有 QMainWindow
派生 class 的 CPP 应用程序,在 ui 中有一个 QQuickView
小部件。此版本表现出问题行为。这是 main.qrc
:
import QtQuick 2.7
import QtQuick.Window 2.2
Rectangle {
anchors.fill: parent
color: "lightblue"
Rectangle {
id: textInputRect
color: "white"
height: 50
width: 150
anchors.centerIn: parent
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
}
}
}
来自QQuickView版,这里是main
:
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
MainWindow window;
QQuickView* view = new QQuickView;
window.setView(view);
window.show();
return app.exec();
}
这是我在 MainWindow
中设置 QQuickView
的方式:
void MainWindow::setView(QQuickView *value)
{
view = value;
QWidget *container = QWidget::createWindowContainer(view, this);
view->setSource(QUrl("qrc:/main.qml"));
ui->verticalLayout->addWidget(container);
}
好的,这是 QTBUG-34414。在该错误的评论底部发布了解决方法。在切换到我的应用程序的其他 windows 或其他应用程序的情况下,发布的解决方法为我解决了这个问题。关闭对话框后仍然没有焦点。将此覆盖放在我的 window class 中解决了这两种情况的问题:
bool MyWindow::event(QEvent *event)
{
if (event->type() == QEvent::ActivationChange ||
event->type() == QEvent::WindowUnblocked) {
if(view->isActive()) { //view is pointer to my QQuickView
window()->activateWindow();
return true;
}
}
// handle events that don't match
return QWidget::event(event);
}
此覆盖对我在 OSX Sierra 上的 Qt 5.7 有效。