我使用Qt 5.6.2(Windows 10)並且有一個QObject
衍生的映射器,它將QKeyEvent
發送到當前關注的QML項目。我的基類有一個虛擬的mapToKey()
函數,然後在我想要使用的各種映射器中重寫。例如下面的映射函數是我LeftArrowMapper
的一部分,併發送左箭頭鍵事件:QML ListView和按鍵導航 - 處理單個按鍵事件
void LeftArrowMapper::mapToKey()
{
// Retrieve root of QML context
QObject* root = engine->rootObjects()[0];
// Get currently focused item
QQuickItem *item = (root->property("activeFocusItem")).value<QQuickItem *>();
if (item == NULL) qDebug() << "No item";
// Create a key and a key event
Qt::Key key = Qt::Key_Left;
QKeyEvent* event = new QKeyEvent(QKeyEvent::KeyPress,
key,
Qt::NoModifier,
KeySequence(key).toString());
// Send it to the focused QML item
QCoreApplication::postEvent(item,event);
}
如果給定的項目支持的按鍵事件,它將相應地作出反應。否則,收到的按鍵事件不會觸發任何響應。我已經用TextField
,一個基於自定義Text
的組件(只更新了text
屬性和通過關鍵事件發送的文本)等來測試它,並且我還沒有遇到任何問題。直到我開始用ListView
工作...
我試圖使用鍵盤的左右箭頭鍵使用我的我的映射器的mapToKey()
功能(點這裏的關鍵事件被人爲地創建導航ListView
:映射硬件事件,如按真實按鈕到Qt事件)。在Qt 5.6中,將focus
屬性設置爲true
可以使用鍵進行導航(在5.8中,也可能是5.7,keyNavigationEnabled
屬性必須設置爲true
;在Qt 5.6中沒有這種屬性)。
我ListView
如下所示:
ListView {
id: list
orientation: Qt.Horizontal
width: rootWindow.width
height: 50
Keys.onPressed: {
console.log("list: " + event.key + " : " + event.text)
if (event.key == Qt.Key_Left) console.log("Moving to the left");
else if (event.key == Qt.Key_Right) console.log("Moving to the right");
}
model: ListModel {
id: items
}
delegate: Rectangle {
width: 50
height: 50
Text {
anchors.centerIn: parent
text: "[" + name + "]"
}
}
Component.onCompleted: function() {
for(var i = 1; i <= 100; i++) {
items.append({"name" : i});
}
}
onFocusChanged: {
console.log("List focus has changed");
}
}
我發現這個問題是奇怪的方式的關鍵事件是由該QML組件處理。它似乎試圖模仿基於動力學的滑動(考慮加速度),您可以在滾動瀏覽其中的項時使用鼠標執行滑動。這意味着:
- 滾動視圖,如果方向鍵被保持的很長一段時間被觸發(約2秒) - 一旦啓用它不滾動單個項目,但多
- 上述滾動觸發後,用戶可以繼續按方向鍵繼續快速滾動。此時,每個按鍵事件滾動單個項目也是可能的,但是...
- 更改方向會導致上述行爲的重置,因此用戶需要執行另一個「觸發器滾動」事件才能滾動到相反的方向
- 觸發多個單獨的按鍵事件也會觸發滾動,但此時一次只觸發一個項目。我上面提到的時間間隔似乎也不適用於此。用戶需要按給定的方向鍵7次(至少這是多少我已經計算在內)之前,他可以在列表中
似乎選擇下一個/上一個項目在內部映射需要一定的金額新聞發佈或長按-X秒鍵事件實際觸發ListView
某些響應。
現在我的一位同事創建了我們正在使用的ListView
的自定義關鍵導航,它工作正常。不過,我想知道是否沒有一些祕密設置(或者我們都沒有錯過文檔中的備忘錄)來處理這個問題。我可以看到這種類型的與鍵的交互(即模擬加速)的應用,但對於我正在處理的場景,我真的不需要它,或者至少現在不需要。另外,如果我想在某個時刻添加僞加速部分,則知道事情是如何完成是非常有用的。
謝謝。你是對的。在Key.onPressed中添加一個'console.log'的確在'currentIndex'中顯示了一個變化。我只是沒有看到這種變化,因爲我沒有突出顯示,只有當currentIndex到達視圖的末尾時,列表滾動才變得可見。 :d – rbaleksandar