如何通过发送 QKeyEvent 在 TableView 项之间移动?
How to move between TableView items by sending QKeyEvent?
我的 QML 文件中有一个 TableView,其中通过向其提供模型加载了几个项目。我可以通过箭头键(向上、向下)在项目之间导航,但我不知道如何通过代码在项目之间导航。
这是我尝试发送事件的方式,但似乎我将我的事件发送到错误的组件:
QQuickItem* focusedItem = qobject_cast<QQuickItem*>(QGuiApplication::focusObject());
QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress,Qt::Key_Up,Qt::NoModifier);
QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease,Qt::Key_Up,Qt::NoModifier);
QCoreApplication::postEvent (focusedItem, event1);
QCoreApplication::postEvent (focusedItem, event2);
焦点项似乎是一个 focusScope,它的父项是一个空 QObject!我用这个测试过:
qDebug () << "ITEM =>" << focusedItem;
qDebug () << "PARENT=>" << focusedItem->parent();
寻找此类内容的好地方是 Qt 本身的自动测试。例如,如果您查看 tst_tableview.qml
,您会发现按键事件未发送到特定项目。相反,目标项目事先获得焦点,事件被发送到 window:
table.forceActiveFocus();
keyClick(Qt.Key_Down);
所以,举个小例子:
#include <QtGui>
#include <QtQuick>
class Controller : public QObject
{
Q_OBJECT
public:
Controller() :
mTarget(0),
mTimerId(0) {
}
void setTarget(QQuickItem *item) {
if (item == mTarget)
return;
mTarget = item;
if (mTarget)
mTimerId = startTimer(1000);
else
killTimer(mTimerId);
}
void timerEvent(QTimerEvent *) {
if (mTarget) {
QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Down, Qt::NoModifier);
QCoreApplication::postEvent(mTarget->window(), event1);
QCoreApplication::postEvent(mTarget->window(), event2);
}
}
private:
QQuickItem *mTarget;
int mTimerId;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Controller controller;
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
controller.setTarget(engine.rootObjects().first()->property("target").value<QQuickItem*>());
return app.exec();
}
#include "main.moc"
当在控制器上设置目标项目时,我们会启动一个计时器,每秒向该项目所在的 window 发送一个向下事件。如果您只有一个 window,没有必要有目标的概念;在发送事件之前将焦点放在 QML 中的正确项目上。
然后,在main.qml
中:
import QtQuick 2.5
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
ApplicationWindow {
id: winRoot
visible: true
width: 500
height: 500
property alias target: tableView
TableView {
id: tableView
focus: true
model: ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
TableViewColumn {
role: "title"
title: "Title"
width: 100
}
TableViewColumn {
role: "author"
title: "Author"
width: 200
}
}
}
我的 QML 文件中有一个 TableView,其中通过向其提供模型加载了几个项目。我可以通过箭头键(向上、向下)在项目之间导航,但我不知道如何通过代码在项目之间导航。
这是我尝试发送事件的方式,但似乎我将我的事件发送到错误的组件:
QQuickItem* focusedItem = qobject_cast<QQuickItem*>(QGuiApplication::focusObject());
QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress,Qt::Key_Up,Qt::NoModifier);
QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease,Qt::Key_Up,Qt::NoModifier);
QCoreApplication::postEvent (focusedItem, event1);
QCoreApplication::postEvent (focusedItem, event2);
焦点项似乎是一个 focusScope,它的父项是一个空 QObject!我用这个测试过:
qDebug () << "ITEM =>" << focusedItem;
qDebug () << "PARENT=>" << focusedItem->parent();
寻找此类内容的好地方是 Qt 本身的自动测试。例如,如果您查看 tst_tableview.qml
,您会发现按键事件未发送到特定项目。相反,目标项目事先获得焦点,事件被发送到 window:
table.forceActiveFocus();
keyClick(Qt.Key_Down);
所以,举个小例子:
#include <QtGui>
#include <QtQuick>
class Controller : public QObject
{
Q_OBJECT
public:
Controller() :
mTarget(0),
mTimerId(0) {
}
void setTarget(QQuickItem *item) {
if (item == mTarget)
return;
mTarget = item;
if (mTarget)
mTimerId = startTimer(1000);
else
killTimer(mTimerId);
}
void timerEvent(QTimerEvent *) {
if (mTarget) {
QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Down, Qt::NoModifier);
QCoreApplication::postEvent(mTarget->window(), event1);
QCoreApplication::postEvent(mTarget->window(), event2);
}
}
private:
QQuickItem *mTarget;
int mTimerId;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Controller controller;
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
controller.setTarget(engine.rootObjects().first()->property("target").value<QQuickItem*>());
return app.exec();
}
#include "main.moc"
当在控制器上设置目标项目时,我们会启动一个计时器,每秒向该项目所在的 window 发送一个向下事件。如果您只有一个 window,没有必要有目标的概念;在发送事件之前将焦点放在 QML 中的正确项目上。
然后,在main.qml
中:
import QtQuick 2.5
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
ApplicationWindow {
id: winRoot
visible: true
width: 500
height: 500
property alias target: tableView
TableView {
id: tableView
focus: true
model: ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
TableViewColumn {
role: "title"
title: "Title"
width: 100
}
TableViewColumn {
role: "author"
title: "Author"
width: 200
}
}
}