2017-07-29 77 views
0

在下面的可执行源代码中,您可以看到我正在使用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() 

回答

1

http://doc.qt.io/qt-4.8/qcombobox.html#details

当用户进入可编辑ComboBox一个新的字符串,窗口小部件可以或可以不将其插入,并且它可以在多个位置将其插入。默认策略是AtBottom,但您可以使用setInsertPolicy()更改它。

http://doc.qt.io/qt-4.8/qcombobox.html#insertPolicy-prop

无效setInsertPolicy(InsertPolicy政策)

QComboBox :: NoInsert - 字符串不会被插入到组合框。

+1

TA,vedadev。你的解决方案就像一个魅力。 – Sophus

+0

不客气。很高兴它的工作。 – vedadev