【寫在前面】
這幾天突然想起來,之前公司有個需求,是類似於搜索引擎的那種關鍵字排序。
當然了,並不是做搜索,而是對歷史輸入記錄的一個匹配 + 排序。
然鵝因爲疫情,工作已經辭了,但想着這個東西挺有意思的,還是決定實現一下。
【正文開始】
老樣子,先展示一下效果圖:
一開始我以爲很難,實際上,實現起來非常容易,其核心不過二十來行代碼。
關鍵代碼 ( 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