2017-07-29 86 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