在下面的可執行源代碼中,您可以看到我正在使用QCompleter
- 與QComboBox()
結合使用。PyQt4:避免將項目添加到QComboBox()
以下情況:想象一下,您即將輸入任何不在當前列表中的隨機字母,然後按Enter鍵。您連續多次執行此程序。現在點擊QComboBox()
,你會看到這個瘋狂輸入的字符在QComboBox()
。我不想那樣。我怎樣才能防止這一點?爲什麼?我只想處理列表中的數據。用戶鍵入幾個字母,他正在查找的單詞。但是當用戶按下回車鍵時,我不想在QComboBox()
中輸入新單詞。
# -*- coding: cp1252 -*-
import sys
from PyQt4.QtCore import Qt, QVariant, SIGNAL, QEvent
from PyQt4.QtGui import QApplication, QStandardItemModel, QStandardItem, QTreeView, QComboBox, QDialog, \
QVBoxLayout, QPushButton, QAbstractItemView, QCompleter, QSortFilterProxyModel, \
QKeyEvent
class MyCustomDialog(QDialog):
def __init__(self, app=None, parent=None):
QDialog.__init__(self, parent)
self.app = app
# Second, we need our QTreeView() and
# the settings
self.init_tree_view()
# Create an empty model for the TreeViews' data
_standard_item_model = QStandardItemModel(0,2)
# Add some textual items
self.food_list = [
["0", 'Cookie dough'],
["1", 'Hummus'],
["2", 'Spaghetti'],
["3", 'Dal makhani'],
["6", 'Blolonese'],
["4", 'Hachfleisch'],
["3", 'Nudeln'],
["666", 'Flösch'],
["4", 'Chocolate whipped cream']
]
# Now its time to populate data
self.populate(model=_standard_item_model)
# Apply the model to the list view
self.set_tree_view_model(_standard_item_model)
# QComboBox() will be created
self.combo_box = QComboBox(self)
self.init_complete(model=_standard_item_model)
# layout is a defined QVBoxLayout()
layout = QVBoxLayout(self)
layout.addWidget(self.combo_box)
self.setLayout(layout)
def init_tree_view(self):
self.tree_view = QTreeView()
self.tree_view.setRootIsDecorated(False)
self.tree_view.setWordWrap(True)
self.tree_view.setAlternatingRowColors(True)
self.tree_view.setSelectionMode(QTreeView.ExtendedSelection)
self.tree_view.header().hide()
self.tree_me = QTreeView()
self.tree_me.setRootIsDecorated(False)
self.tree_me.setWordWrap(True)
self.tree_me.setAlternatingRowColors(True)
self.tree_me.setSelectionMode(QTreeView.ExtendedSelection)
self.tree_me.header().hide()
def init_complete(self, model=None):
# add a completer, which uses the filter model
# add a filter model to filter matching items
filterModel = QSortFilterProxyModel(self.combo_box)
filterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
filterModel.setSourceModel(model)
filterModel.setFilterKeyColumn(0)
completer = QCompleter(self.combo_box)
# Set the model that the QCompleter uses
# on model column change, update the model
# column of the filter and completer as well
completer.setModel(filterModel)
completer.setCompletionColumn(0)
completer.popup().installEventFilter(self)
completer.popup().selectionModel().selectionChanged.connect(lambda new_index:
self.get_id_tree_view(new_index=new_index))
# always show all (filtered) completions
completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
completer.setPopup(self.tree_me)
self.tree_me.setColumnHidden(1, True)
self.combo_box.setEditable(True)
self.combo_box.setCompleter(completer)
# on model column change, update the model
# column of the filter and completer as well
self.combo_box.setModel(model)
self.combo_box.setView(self.tree_view)
# on model column change, update the model column of
# the filter and completer as well
self.combo_box.setModelColumn(0)
self.tree_view.resizeColumnToContents(0)
self.tree_view.setColumnHidden(1, True)
if self.combo_box.isEditable():
self.app.connect(self.combo_box.lineEdit(), SIGNAL('textEdited(QString)'), filterModel.setFilterFixedString)
def set_tree_view_model(self, model):
self.tree_view.setModel(model)
def generator_header_data(self, list_header):
for header_data in list_header:
yield header_data
def set_header_data(self, list_header_data=None, model=None):
count_column = 0
for header_data in self.generator_header_data(list_header_data):
model.setHeaderData(count_column, Qt.Horizontal, header_data)
count_column +=1
def get_id_tree_view(self, new_index=None):
try:
if not new_index is None:
index = new_index.indexes()[1].data()#.toPyObject()
if isinstance(index, QVariant):
print "get_id_tree_view, index", index.toString()
except IndexError as InErr:
pass#print "InErr", InErr
def populate_data_item(self, item_list=None, model=None):
count_items = len(item_list)
if count_items == 2:
item_first, item_second = item_list
two_columns_item = [QStandardItem(item_second), QStandardItem(str(item_first))]
model.appendRow(two_columns_item)
def populate(self, model=None):
for single_list in self.food_list:
self.populate_data_item(item_list=single_list, model=model)
def main():
app = QApplication(sys.argv)
window = MyCustomDialog(app=app)
window.resize(300, 50)
window.show()
try:
sip.setdestroyonexit(False)
except:
# missing in older versions
pass
sys.exit(app.exec_())
if __name__ == "__main__":
main()
TA,vedadev。你的解決方案就像一個魅力。 – Sophus
不客氣。很高興它的工作。 – vedadev