【问题标题】:PyQt-QtableView Header. How to add top-right small button to hide/show column with checked/unchecked Checkboxes?PyQt-QtableView 标头。如何添加右上角的小按钮以隐藏/显示带有选中/未选中复选框的列?
【发布时间】:2014-09-09 12:00:23
【问题描述】:

使用 PyQt4,我使用的 QtableView 超过 10 列。用户必须可以选择显示/隐藏列。

这通常通过在表格标题的右上角添加一个小按钮来完成。该按钮显示一个带有选中/未选中复选框的菜单,允许隐藏/显示列。

这是来自Sqlite-Manager Table 的示例。 所以,我想知道如何使用 PyQt 的 QtableView 做同样的事情?

谢谢,

【问题讨论】:

    标签: qt checkbox pyqt4 qtableview


    【解决方案1】:

    谢谢 Kitsune Meyoko,这是个好主意.. ;)

    我通过使用带有 Checkable QActions 而不是 QPushButton 的 QMenu 找到了与您的非常相似的另一个解决方案:Let's Go:

    import sys
    import string
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    class Header(QHeaderView):
    
        def __init__(self, parent=None):
            super(Header, self).__init__(Qt.Horizontal, parent)
    
            self.setContextMenuPolicy(Qt.CustomContextMenu)
            self.customContextMenuRequested.connect(self.ctxMenu)
    
            self.setup()
    
        @pyqtSlot(bool)
        def printID(self, i):
            print("id")
            if i == False:
                self.hideSection(0)
            else:
                self.showSection(0)
    
        @pyqtSlot(bool)        
        def printNAME(self, i):
            print("name")
            if i == False:
                self.hideSection(1)
            else:
                self.showSection(1)
    
        @pyqtSlot(bool)        
        def printUSERNAME(self, i):
            print("username")
            if i == False:
                self.hideSection(2)
            else:
                self.showSection(2)
    
        def setup(self):
    
            self.id = QAction("id",self)
            self.id.setCheckable(True)
            self.id.setChecked(True)
            self.connect(self.id, SIGNAL("triggered(bool)"), self, SLOT("printID(bool)"))
    
    
            self.name = QAction("name",self)
            self.name.setCheckable(True)
            self.name.setChecked(True)
            self.connect(self.name, SIGNAL("triggered(bool)"), self, SLOT("printNAME(bool)"))
    
    
            self.username = QAction("username",self)
            self.username.setCheckable(True)
            self.username.setChecked(True)
            self.connect(self.username, SIGNAL("triggered(bool)"), self, SLOT("printUSERNAME(bool)"))
    
        def ctxMenu(self, point):
            menu = QMenu(self)
            self.currentSection = self.logicalIndexAt(point)
            menu.addAction(self.id)
            menu.addAction(self.name)
            menu.addAction(self.username)
            menu.exec_(self.mapToGlobal(point))
    
    
    class Table(QTableWidget):
        def __init__(self, parent=None):
            super(Table, self).__init__(parent)
            self.setHorizontalHeader(Header(self))
            self.setColumnCount(3)
            self.setHorizontalHeaderLabels(['id', 'name', 'username'])
            self.populate()
    
        def populate(self):
            self.setRowCount(10)
            for i in range(10):
                for j,l in enumerate(string.ascii_letters[:3]):
                    self.setItem(i, j, QTableWidgetItem(l)) 
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        t = Table()
        t.show()
        app.exec_()
        sys.exit()
    

    【讨论】:

    • 听起来不错。唉......如果我把所有的东西都隐藏了,它就不能再右键单击了。它应该在QTableWidget 中处理超过?还是用按钮处理好?
    • 嗯,是的,我认为用户没有兴趣隐藏所有部分。因此,当只有一个部分仍然可见时,可以禁用隐藏部分!
    • 是的,隐藏所有部分应该没有兴趣。但它可以设置隐藏所有。如果用户不小心隐藏了所有并想再次显示它,它不能再做回来了。所以,用户可以认为它是“BUG”,不是吗?
    【解决方案2】:

    在QTableView 中没有类似“Sqlite-Manager Table”的按钮。但是您可以使用QtGui.QPushButton 自定义小部件并与QtGui.QMenu 一起使用以从用户那里获取列。并使用QTableView.hideColumn (self, int column) & QTableView.showColumn (self, int column) 隐藏显示您的列;

    完整示例;

    import sys
    import random
    from functools import partial
    from PyQt4 import QtGui
    
    class QCustomTableViewWidget (QtGui.QWidget):
        def __init__ (self, myQStandardItemModel, *args, **kwargs):
            super(QCustomTableViewWidget, self).__init__(*args, **kwargs)
            # Layout setup
            self.localQTableView        = QtGui.QTableView()
            self.rightCornerQPushButton = QtGui.QPushButton()
            menuQHBoxLayout = QtGui.QHBoxLayout()
            menuQHBoxLayout.addStretch(1)
            menuQHBoxLayout.addWidget(self.rightCornerQPushButton)
            allQVBoxLayout = QtGui.QVBoxLayout()
            allQVBoxLayout.addLayout(menuQHBoxLayout)
            allQVBoxLayout.addWidget(self.localQTableView)
            self.setLayout(allQVBoxLayout)
            # Object setup
            self.localQTableView.setModel(myQStandardItemModel)
            self.rightCornerQPushButton.setText('Show column')
            currentQMenu = QtGui.QMenu()
            for column in range(myQStandardItemModel.columnCount()):
                currentQAction = QtGui.QAction('Column %d' % (column + 1), currentQMenu)
                currentQAction.setCheckable(True)
                currentQAction.setChecked(True)
                currentQAction.toggled.connect(partial(self.setColumnVisible, column))
                currentQMenu.addAction(currentQAction)
            self.rightCornerQPushButton.setMenu(currentQMenu)
    
        def setColumnVisible (self, column, isChecked):
            if isChecked:
                self.localQTableView.showColumn(column)
            else:
                self.localQTableView.hideColumn(column)
    
        def tableView (self):
            return self.localQTableView
    
    # Simulate data
    myQStandardItemModel = QtGui.QStandardItemModel()
    for _ in range(10):
        myQStandardItemModel.appendRow([QtGui.QStandardItem('%d' % random.randint(100, 999)), QtGui.QStandardItem('%d' % random.randint(100, 999)), QtGui.QStandardItem('%d' % random.randint(100, 999))])
    
    # Main application
    myQApplication           = QtGui.QApplication(sys.argv)
    myQCustomTableViewWidget = QCustomTableViewWidget(myQStandardItemModel)
    myQCustomTableViewWidget.show()
    sys.exit(myQApplication.exec_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 2016-03-13
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      相关资源
      最近更新 更多