【问题标题】:How to customize QComboBox如何自定义 QComboBox
【发布时间】:2014-11-02 05:11:50
【问题描述】:

我希望能够从其下拉菜单中选择多个QComboBox 的项目(使用 Shift 或 Alt+单击以从当前选择中添加/提取)。

  1. 单击时,QComboBox 会向下滚动一个下拉菜单。

  2. 但是当用户第二次点击鼠标时(从下拉菜单中选择一个项目)

ComboBox 不会像默认情况下那样回滚(或自折叠)。相反,它将保持打开状态,以便用户能够按住 Shift 键并单击更多组合框项目以添加或从选择中提取它们。最后,当用户对选择感到满意时,按下Enter 键以“确认”选择。

这是一个 Photoshop 的图像,显​​示了我想要实现的“多选”QComboBox 的概念:

下面的代码创建 QComboBox,几乎所有事件都暴露出来。但我看到的唯一“代理”是 onMousePressEvent()。当用户从下拉菜单中选择项目时,我找不到追踪的方法......

编辑:

一小时后,我了解到QComboBox 可以通过其.view().setSelectionMode(3) 设置为多选。

那么同样的.view()可以用来查询Combobox选中项:

selectedIndexes=self.view().selectionModel().selectedIndexes() 

(其中self 本身就是一个组合)

有一种方法可以使用selectionModel.select(idx, QtGui.QItemSelectionModel.Select) 选择组合项

但到目前为止我没能成功.....

from PyQt4 import QtCore, QtGui

app = QtGui.QApplication([])
class Combo(QtGui.QComboBox):
    def __init__(self, *args, **kwargs):
        super(Combo, self).__init__()
        self.addItems(['Item_1','Item_2','Item_3','Item_4','Item_5'])
        self.view=self.view()
        self.view.setSelectionMode(3)
        self.activated.connect(self.clicked)   
        self.show()

    def clicked(self, arg=None):
        selectionModel=self.view.selectionModel()
        selectedIndexes=selectionModel.selectedIndexes()

        for idx in selectedIndexes:
            selectionModel.select(idx, QtGui.QItemSelectionModel.Select)
            print 'selecting idx: %s'%idx

        self.showPopup()

tree=Combo()
sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt


    【解决方案1】:

    其他方式,您可以使用类似图标来检查状态。比QtGui.QStandardItem 容易。方法QIcon QComboBox.itemIcon (self, int index)和方法QComboBox.setItemIcon (self, int index, QIcon icon)在类QtGui.QComboBox中可用;

    import sys
    from PyQt4 import QtGui
    
    class QCustomComboBox (QtGui.QComboBox):
        CHECK_QICON   = QtGui.QIcon.fromTheme('call-start')
        UNCHECK_QICON = QtGui.QIcon.fromTheme('call-stop')
    
        def __init__(self, *args, **kwargs):
            super(QCustomComboBox, self).__init__(*args, **kwargs)
            listsItem = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']
            for index in range(0, len(listsItem)):
                self.addItem(listsItem[index])
                self.setItemIcon(index, self.UNCHECK_QICON)
            self.activated.connect(self.customActivated)
    
        def hidePopup (self):
            pass # Force only ESC button to exit.
    
        def customActivated (self, index):
            # self.blockSignals(True) # Force first index only
            # self.setCurrentIndex(0)
            # self.blockSignals(False)
            stateQIcon = self.itemIcon(index)
            newQIcon = {
                self.CHECK_QICON.name()   : self.UNCHECK_QICON,
                self.UNCHECK_QICON.name() : self.CHECK_QICON,
            } [stateQIcon.name()]
            self.setItemIcon(index, newQIcon)
            print self.export() # View last update data
    
        def export (self):
            listsExportItem = []
            for index in range(0, self.count()):
                stateQIcon = self.itemIcon(index)
                state = {
                    self.CHECK_QICON.name()   : True,
                    self.UNCHECK_QICON.name() : False,
                } [stateQIcon.name()]
                listsExportItem.append([str(self.itemText(index)), state])
            return listsExportItem
    
    myQApplication = QtGui.QApplication([])
    myQCustomComboBox = QCustomComboBox()
    myQCustomComboBox.show()
    sys.exit(myQApplication.exec_())
    

    【讨论】:

    • 我喜欢图标的想法......几个问题。 1.export()方法的目的是什么? 2. 自定义 ComboBox 应允许从其下拉菜单中多选项目。从您的代码中使用 ComoboBox 我当时只能检查一个(单个)项目。单击一项会取消选中所有其他项(就像默认的 ComboBox 一样)。请指教。
    • (1) 对于item中的导出数据,就像在QtGui.QComboBox中的每个item中的get state是check or uncheck一样。 (2) 它在 OSX 中不起作用吗? def hidePopup (self): pass 不行吗?我在 Ubuntu 12 中使用,它工作正常,可以多选。
    • 我爱def hidePopup(self):pass!!!简直美极了。无需搞乱setSetCurrentIndex(0);self.showPopup() 等但export() 方法在我的mac 上不起作用...我认为没什么大不了的...感谢 hidePopup() 技巧!
    • 什么小部件/函数/方法调用export()方法?我看不到它与代码中的任何内容相关联...它是“内置”QComboBox 方法吗?
    • 看来我看不到图标的原因是因为 OSX 问题。以下是之前关于同一主题的讨论的链接:stackoverflow.com/a/12825838/1107049
    【解决方案2】:

    我最终使用文本颜色来区分单击(也称为选定)项目与其他项目。

    首先单击 ComboBox 打开其下拉菜单。 以下所有点击都是选择/取消选择(突出显示的红色)项目。点击退出以关闭下拉菜单。

    from PyQt4 import QtCore, QtGui
    app = QtGui.QApplication([])
    
    class Combo(QtGui.QComboBox):
        def __init__(self, *args, **kwargs):
            super(Combo, self).__init__()        
            for each in ['Item_1','Item_2','Item_3','Item_4','Item_5']:
                item=QtGui.QStandardItem(each) 
                self.model().appendRow(item)
                item.setData('black')
    
            self.activated.connect(self.clicked)   
            self.show()  
    
        def clicked(self, clickedNumber=None): 
            self.blockSignals(True)  
            self.setCurrentIndex(0)        
            self.showPopup()
            self.view().clearSelection()
    
            clickedItem=self.model().item(clickedNumber)
    
            color=clickedItem.data().toString()
            if color=='black': clickedItem.setData('red')
            elif color=='red': clickedItem.setData('black')
            clickedItem.setForeground(QtGui.QColor(clickedItem.data().toString()))
    
            clickedIndex=self.model().indexFromItem(clickedItem)
            self.view().selectionModel().select(clickedIndex, QtGui.QItemSelectionModel.Select)
            self.setCurrentIndex(clickedNumber)  
    
            self.blockSignals(False)
    
    tree=Combo()
    sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 2018-10-28
      • 2012-02-22
      • 2010-10-10
      • 2012-11-15
      相关资源
      最近更新 更多