PyQt4:避免将项添加到QComboBox()

时间:2017-07-29 19:58:36

标签: python-2.7 qt4 pyqt4

在以下可执行源代码中,您可以看到我正在使用QCompleter - 与QComboBox()结合使用。

以下情况:想象一下,您要输入当前列表中不存在的任何随机字母,然后按Enter键。您连续多次执行此过程。现在点击QComboBox(),您会看到广泛输入的字符位于QComboBox()。我不想要那个。我怎么能阻止这个?为什么?我只想处理列表中的数据。用户键入几个字母,他正在寻找的单词。但是,当用户按Enter键时,我不想在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 个答案:

答案 0 :(得分:1)

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

  

当用户在可编辑组合框中输入新字符串时,窗口小部件可能插入也可能不插入,并且可以将其插入多个位置。默认策略是AtBottom,但您可以使用setInsertPolicy()更改此设置。

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

  

void setInsertPolicy(InsertPolicy policy)

     

QComboBox :: NoInsert - 该字符串不会插入组合框中。