用QCompleter进行全局输入



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

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,如:

['cam0001:left', 'cam0001:right', 'cam0002:left', 'cam0002:right', etc...]

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

我希望能够在搜索时glob模式,包括*?。例如,搜索cam000?:left将从结果中排除cam0010:left

看起来你将不得不实现你自己的完成器。下面是一个使用正则表达式过滤补全的示例:

#!/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_())

相关内容

  • 没有找到相关文章

最新更新