Qt / Qml 實現歷史編輯器 ( 支持歷史搜索 & 關鍵字匹配 )

【寫在前面】

這幾天突然想起來,之前公司有個需求,是類似於搜索引擎的那種關鍵字排序。

當然了,並不是做搜索,而是對歷史輸入記錄的一個匹配 + 排序

然鵝因爲疫情,工作已經辭了,但想着這個東西挺有意思的,還是決定實現一下。


【正文開始】

老樣子,先展示一下效果圖:

 一開始我以爲很難,實際上,實現起來非常容易,其核心不過二十來行代碼。

關鍵代碼 ( C++ 部分 ) :

void HistoryModel::sortByKey(const QString &key)
{
    if (key.isEmpty()) {
        beginResetModel();
        m_data = m_historyData;
        endResetModel();
    } else {
        QMultiMap<int, QString> temp;
        for (auto str : m_historyData) {
            int ret = str.indexOf(key);
            if (ret == -1) continue;
            else temp.insert(ret, str);
        }

        beginResetModel();
        m_data.clear();
        if (!temp.isEmpty()) {
            //也可 for range-based
            for (auto it = temp.begin(); it != temp.end(); it++) {
                m_data.push_back(it.value());
            }
        }
        endResetModel();
    }
}

1、因爲每次改變關鍵字後,匹配到的數據就會完全改變,所以應當重置模型,這裏使用 beginResetModel()endResetModel()

2、使用 QMultiMap 進行排序 ( 自排序 ),其匹配索引 ( index ) 作爲權值。

3、遍歷匹配結果集 ( temp ),依次填充 model 即可。

而界面就很簡單了:

Qml 部分:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("History Editor")

    TextField {
        id: inputField
        width: 300
        height: 40
        selectByMouse: true
        font.pointSize: 12
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top
        anchors.topMargin: 100
        background: Rectangle {
           radius: 4
           border.color: "green"
        }

        property bool editing: false

        onTextEdited: editing = true;
        onEditingFinished: editing = false;
        onTextChanged: {
            myModel.sortByKey(inputField.text);
        }
    }

    Button {
        text: qsTr("搜索")
        width: 70
        height: 40
        anchors.top: inputField.top
        anchors.left: inputField.right
        anchors.leftMargin: 12
    }

    Rectangle {
        id: historyList
        radius: 4
        width: 300
        height: 200
        visible: inputField.editing || inputField.activeFocus
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: inputField.bottom
        anchors.topMargin: 2
        border.color: "red"
        color: "#eee"

        ListView {
            id: listView
            anchors.fill: parent
            anchors.margins: 5
            clip: true
            spacing: 5
            delegate: Component {
                Rectangle {
                    radius: 4
                    width: listView.width - 20
                    height: 40
                    color: hovered ? "#f4f4f4" : "#ddd"
                    border.color: "gray"

                    property bool hovered: false

                    Text {
                        id: displayText
                        text: display
                        anchors.verticalCenter: parent.verticalCenter
                        anchors.left: parent.left
                        anchors.leftMargin: 20
                        font.pixelSize: 18
                        font.wordSpacing: 3

                        Rectangle {
                            color: "red"
                            opacity: 0.4
                            x: display.indexOf(inputField.text) * displayText.font.pixelSize / 2
                            width: displayText.font.pixelSize / 2 * inputField.text.length
                            height: parent.height
                        }
                    }

                    MouseArea {
                        anchors.fill: parent
                        hoverEnabled: true
                        onEntered: parent.hovered = true;
                        onExited: parent.hovered = false;
                    }
                }
            }
            model: myModel
            ScrollBar.vertical: ScrollBar {
                width: 12
                policy: ScrollBar.AlwaysOn
            }
        }
    }
}

【結語】

最後,從效果來看還是很滿意的。

不過,如果數據過多性能就一般般了,應該要考慮更好的算法。

附上項目鏈接(多多star呀..⭐_⭐):

CSDN的:https://download.csdn.net/download/u011283226/12256591

Github的:https://github.com/mengps/QmlControls

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章