我在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_())