PySide / PyQt4: добавление флажка в заголовок горизонтального (столбца) QTableWidget - PullRequest
5 голосов
/ 17 марта 2012

Я пытаюсь поставить флажок в горизонтальном (столбцовом) заголовке моего табличного виджета. Основываясь на другом посте здесь (поскольку базовый тип объекта такой же), я попробовал это:

item = QtGui.QTableWidgetItem()
item.setCheckState(QtCore.Qt.Checked)
self.tableWidget.setHorizontalHeaderItem(1, item)

и я тоже пробовал это:

self.tableWidget.horizontalHeaderItem(1).setCheckState(QtCore.Qt.Checked)

Ни один из них не создает флажок в горизонтальном заголовке. Предложения приветствуются.

Ответы [ 4 ]

4 голосов
/ 19 марта 2012

Это не так уж и красиво, но решение этой проблемы было размещено в FAQ на сайте qt-project.org .

Я адаптировал решение для Python и внес некоторые изменения, предложенные в комментариях.

from PyQt4.QtCore import Qt, QRect
from PyQt4.QtGui import QTableWidget, QApplication, QHeaderView, QStyleOptionButton, QStyle

import sys

class MyHeader(QHeaderView):

    isOn = False

    def __init__(self, orientation, parent=None):
        QHeaderView.__init__(self, orientation, parent)

    def paintSection(self, painter, rect, logicalIndex):
        painter.save()
        QHeaderView.paintSection(self, painter, rect, logicalIndex)
        painter.restore()

        if logicalIndex == 0:
            option = QStyleOptionButton()
            option.rect = QRect(10, 10, 10, 10)
            if self.isOn:
                option.state = QStyle.State_On
            else:
                option.state = QStyle.State_Off
            self.style().drawControl(QStyle.CE_CheckBox, option, painter)

    def mousePressEvent(self, event):
        self.isOn = not self.isOn
        self.updateSection(0)
        QHeaderView.mousePressEvent(self, event)

class MyTable(QTableWidget):
    def __init__(self):
        QTableWidget.__init__(self, 3, 3)

        myHeader = MyHeader(Qt.Horizontal, self)
        self.setHorizontalHeader(myHeader)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myTable = MyTable()
    myTable.show()
    sys.exit(app.exec_())
1 голос
/ 09 декабря 2015

В качестве благодарности Гэри за ответ, вот модифицированная версия его проверяемого заголовка, где все разделы можно проверять отдельно

class QCheckableHeader(QHeaderView):

def __init__(self, orientation, parent=None):
    QHeaderView.__init__(self, orientation, parent)
    self.lisCheckboxes = []
    self.sectionCountChanged.connect(self.onSectionCountChanged)

def paintSection(self, painter, rect, logicalIndex):
    print "paintSection", logicalIndex
    painter.save()
    QHeaderView.paintSection(self, painter, rect, logicalIndex)
    painter.restore()
    painter.save()
    painter.translate(rect.topLeft())

    option = QStyleOptionButton()
    option.rect = QRect(10, 10, 10, 10)
    if (len(self.lisCheckboxes) != self.count()):
        self.onSectionCountChanged(len(self.lisCheckboxes), self.count())

    if self.lisCheckboxes[logicalIndex]:
        option.state = QStyle.State_On
    else:
        option.state = QStyle.State_Off
    self.style().drawControl(QStyle.CE_CheckBox, option, painter)
    painter.restore()

def mousePressEvent(self, event):

    iIdx = self.logicalIndexAt(event.pos())
    self.lisCheckboxes[iIdx] = not self.lisCheckboxes[iIdx]
    self.updateSection(iIdx)
    QHeaderView.mousePressEvent(self, event)

@QtCore.Slot()
def onSectionCountChanged(self, oldCount,  newCount):
    if newCount > oldCount:
        for i in range(newCount - oldCount):
            self.lisCheckboxes.append(False)
    else:
        self.lisCheckboxes = self.lisCheckboxes[0:newCount]

Надеюсь, это поможет кому-то, кроме меня тоже: -)

1 голос
/ 22 марта 2012

Я отдал должное Гэри Хьюзу, потому что он фактически поставил флажок в самом разделе заголовка, но я подумал, что опубликую свое более простое решение, если кто-то захочет сделать это простым способом.Это основано на совете, который я получил на форумах Qt Developer :

Я вложил в класс QTableWidget, чтобы сделать флажки дочерними виджетами для HorizontalHeader () и вручную переставить флажки при изменении размера таблицы:

class custom_table(QtGui.QTableWidget):

    def __init__(self, parent=None):
        QtGui.QTableWidget.__init__(self, parent)
        self.chkbox1 = QtGui.QCheckBox(self.horizontalHeader())

    def resizeEvent(self, event=None):
        super().resizeEvent(event)
        self.chkbox1.setGeometry(QtCore.QRect((self.columnWidth(0)/2), 2, 16, 17))

"(self.columnWidth (0) / 2)" сохраняет флажок в середине заголовка столбца.

0 голосов
/ 06 июня 2017

Адаптировано из блога qt http://blog.qt.io/blog/2014/04/11/qt-weekly-5-widgets-on-a-qheaderview/

Это также можно использовать для размещения произвольных виджетов в заголовке

# coding=utf-8
from PySide.QtCore import Qt
from PySide.QtGui import QHeaderView, QCheckBox
from qtpy import QtCore


class CustomHeaderView(QHeaderView):
    def __init__(self, parent=None):
        QHeaderView.__init__(self, Qt.Horizontal, parent)
        self.setMovable(True)
        self.boxes = []

        self.sectionResized.connect(self.handleSectionResized)
        self.sectionMoved.connect(self.handleSectionMoved)

    def scrollContentsBy(self, dx, dy):
        super().scrollContentsBy(dx, dy)
        if dx != 0:
            self.fixComboPositions()

    def fixComboPositions(self):
        for i in range(self.count() + 1):
            self.boxes[i].setGeometry(self.sectionViewportPosition(i), 0,
                                      self.sectionSize(i) - 5, self.height())

    @QtCore.Slot()
    def showEvent(self, e):
        for i in range(self.count() + 1):
            if len(self.boxes) <= i:
                self.boxes.append(QCheckBox(self))
            self.boxes[i].setGeometry(self.sectionViewportPosition(i), 0,
                                      self.sectionSize(i) - 5, self.height())
            self.boxes[i].show()

        super().showEvent(e)

    @QtCore.Slot()
    def handleSectionMoved(self, logical, oldVisualIndex, newVisualIndex):
        for i in range(min(oldVisualIndex, newVisualIndex),self.count()):
            logical = self.logicalIndex(i)
            self.boxes[logical].setGeometry(self.sectionViewportPosition(logical), 0,
                                            self.sectionSize(logical) - 5, self.height())

    @QtCore.Slot()
    def handleSectionResized(self, i):
        for j in range(self.visualIndex(i),self.count()):
            logical = self.logicalIndex(j)
            self.boxes[logical].setGeometry(self.sectionViewportPosition(logical), 0,
                                            self.sectionSize(logical) - 5, self.height())
            self.boxes[logical].updateGeometry()
...