python - Entrada globbing con QCompleter?
regex pyqt (1)
Implementé un PyQt QCompleter
estándar dentro de un QLineEdit
, QLineEdit
agallas son:
self.cam_completer = QtGui.QCompleter( self.cameras, self )
self.cam_completer.setCaseSensitivity( 0 )
self.cam_completer.setCompletionMode( 2 )
self.CamerasSearch.setCompleter( self.cam_completer )
donde self.cameras
es una list
de cadenas, como:
[''cam0001:left'', ''cam0001:right'', ''cam0002:left'', ''cam0002:right'', etc...]
Dentro de QLineEdit
, la entrada de la cam
devolverá todos los elementos, cam0001
devolverá solo los primeros 2, etc. Sin embargo, cuando ingreso la cam*
, no se devuelve nada.
Me gustaría poder buscar patrones al buscar, incluidos *
y ?
. Por ejemplo, buscar cam000?:left
cam0010:left
eliminaría cam0010:left
los resultados.
Parece que va a tener que implementar su propio complemento. Aquí hay un ejemplo que usa expresiones regulares para filtrar terminaciones:
#!/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_())