使用QCompleter进行模糊匹配输入?

2024-05-14 18:08:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个QLineEdit中实现了一个标准的PyQtQCompleter,其核心是:

self.cam_completer = QtGui.QCompleter( self.cameras, self )
self.cam_completer.setCaseSensitivity( 0 )
self.cam_completer.setCompletionMode( 2 )
self.CamerasSearch.setCompleter( self.cam_completer )

其中self.cameras是一个list字符串,如:

^{pr2}$

QLineEdit中,输入cam将返回所有项目,cam0001将只返回前2个项目,依此类推。但是,当我输入cam*时,没有返回任何内容。在

我希望能够在搜索时全局搜索模式,包括*和{}。例如,搜索cam000?:left将从结果中删除cam0010:left。在


Tags: 项目self核心标准leftcamqtguicameras
1条回答
网友
1楼 · 发布于 2024-05-14 18:08:59

看来你要实现你自己的完成器。下面是一个使用正则表达式筛选完成的示例:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

#    -
# IMPORT
#    -
import sys, random

import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)

from PyQt4 import QtGui, QtCore

#    -
# DEFINE
#    -
class QDialogTest(QtGui.QDialog):
    def __init__(self, parent=None):
        super(QDialogTest, self).__init__(parent)

        self.maxVisibleItems = 7

        self.lineEdit = QtGui.QLineEdit(self)
        self.lineEdit.textChanged.connect(self.on_lineEdit_textChanged)

        self.standardItemModel = QtGui.QStandardItemModel(self)

        with open("/usr/share/dict/words", "r") as fileInput:
            for line in  random.sample(fileInput.readlines(), 111):
                self.standardItemModel.appendRow(
                    QtGui.QStandardItem(line.strip())
                )

        self.sortFilterProxyModel = QtGui.QSortFilterProxyModel(self)
        self.sortFilterProxyModel.setSourceModel(self.standardItemModel)
        self.sortFilterProxyModel.setFilterKeyColumn(0)

        self.tableView = QtGui.QTableView(self)
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.setModel(self.sortFilterProxyModel)

        self.pushButtonClose = QtGui.QPushButton(self)
        self.pushButtonClose.setText("Close")
        self.pushButtonClose.clicked.connect(sys.exit)

        self.layoutVertical = QtGui.QVBoxLayout(self)
        self.layoutVertical.addWidget(self.tableView)
        self.layoutVertical.addWidget(self.lineEdit)
        self.layoutVertical.addWidget(self.pushButtonClose)

        self.tableViewPopup = QtGui.QTableView(self)
        self.tableViewPopup.setModel(self.sortFilterProxyModel)
        self.tableViewPopup.setWindowFlags(QtCore.Qt.Popup)
        self.tableViewPopup.setFocusPolicy(QtCore.Qt.NoFocus)
        self.tableViewPopup.setFocusProxy(self.lineEdit)
        self.tableViewPopup.setMouseTracking(True)
        self.tableViewPopup.setEditTriggers(QtGui.QTableView.NoEditTriggers)
        self.tableViewPopup.setSelectionBehavior(QtGui.QTableView.SelectRows)
        self.tableViewPopup.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
        self.tableViewPopup.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.tableViewPopup.horizontalHeader().setStretchLastSection(True)
        self.tableViewPopup.horizontalHeader().hide()
        self.tableViewPopup.verticalHeader().hide()
        self.tableViewPopup.verticalHeader().setDefaultSectionSize(20)
        self.tableViewPopup.doubleClicked.connect(self.setCurrentCompletion)
        self.tableViewPopup.installEventFilter(self)

    def setCurrentCompletion(self):
        self.closePopup()

        indexes = self.tableViewPopup.selectionModel().selectedIndexes()

        self.lineEdit.blockSignals(True)
        self.lineEdit.setText(indexes[0].data(QtCore.Qt.DisplayRole))
        self.lineEdit.blockSignals(False)

    def closePopup(self):
        self.tableViewPopup.hide()
        self.lineEdit.setFocus()

    def eventFilter(self, obj, event):
        if obj != self.tableViewPopup:
            return False

        elif event.type() == QtCore.QEvent.MouseButtonPress:
            self.closePopup()

        elif event.type() == QtCore.QEvent.KeyPress:
            if event.key() in [
                QtCore.Qt.Key_Enter,
                QtCore.Qt.Key_Return
            ]:
                self.setCurrentCompletion()

            elif event.key() in [
                QtCore.Qt.Key_Escape
            ]:
                self.closePopup()

            elif not event.key() in [
                QtCore.Qt.Key_Up,
                QtCore.Qt.Key_Down,
                QtCore.Qt.Key_Home,
                QtCore.Qt.Key_End,
                QtCore.Qt.Key_PageUp,
                QtCore.Qt.Key_PageDown
            ]:
                self.lineEdit.event(event)

        return super(QDialogTest, self).eventFilter(obj, event)

    @QtCore.pyqtSlot(str)
    def on_lineEdit_textChanged(self, text):
        self.tableViewPopup.hide()

        if text != "":
            self.setCompletionPrefix(text)

    def setCompletionPrefix(self, prefix):
        self.sortFilterProxyModel.setFilterRegExp(QtCore.QRegExp(prefix))

        if self.sortFilterProxyModel.rowCount():
            self.complete()

    def complete(self):
        self.tableViewPopup.move(
            self.lineEdit.mapToGlobal(
                QtCore.QPoint(0, self.lineEdit.height())
            )
        )
        self.tableViewPopup.resize(
            self.lineEdit.width(), 
            self.tableViewPopup.verticalHeader().defaultSectionSize() * min(
                self.maxVisibleItems,
                self.sortFilterProxyModel.rowCount()
            ) + 2
        )
        self.tableViewPopup.setFocus()
        self.tableViewPopup.show()       

#    -
# MAIN
#    -
if __name__ == "__main__":    
    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('QDialogTest')

    main = QDialogTest()
    main.resize(333, 333)
    main.exec_()

    sys.exit(app.exec_())

相关问题 更多 >

    热门问题