【问题标题】:Qt Table widget. How to set the meaning/title for vertical header and horizontal header together?Qt 表小部件。如何一起设置垂直标题和水平标题的含义/标题?
【发布时间】:2015-02-25 21:18:55
【问题描述】:

我知道如何将文本标签设置为行或列标题。但我想做这样的事情:

http://i.stack.imgur.com/eMM6U.jpg

我没有找到任何关于如何在红圈内进行操作的信息。我开始相信这不能用 QTableWidget 完成。

谢谢 ;)

【问题讨论】:

    标签: c++ qt qtablewidget


    【解决方案1】:

    我认为使用标准标题(QHeaderView)because of是不可能的:

    注意:每个标题都为每个部分本身呈现数据,并且确实 不依赖代表。结果,调用标头的 setItemDelegate() 函数将不起作用。

    所以你需要忘记它并禁用它,你应该实现你自己的标题(设置你的颜色,你的文本等等),但我当然会帮助解释含义/标题。我通过下一个项目委托实现了这一点:

    .h:

    #ifndef ITEMDELEGATEPAINT_H
    #define ITEMDELEGATEPAINT_H
    
    #include <QStyledItemDelegate>
    
    class ItemDelegatePaint : public QStyledItemDelegate
    {
        Q_OBJECT
    public:
        explicit ItemDelegatePaint(QObject *parent = 0);
        ItemDelegatePaint(const QString &txt, QObject *parent = 0);
    
    
    protected:
        void paint( QPainter *painter,
                    const QStyleOptionViewItem &option,
                    const QModelIndex &index ) const;
        QSize sizeHint( const QStyleOptionViewItem &option,
                        const QModelIndex &index ) const;
        QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
        void setEditorData(QWidget * editor, const QModelIndex & index) const;
        void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
        void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const;
    
    signals:
    
    public slots:
    
    };
    
    #endif // ITEMDELEGATEPAINT_H
    

    但是所有这些方法在这里都不是很有用,你可以通过一些具体的动作自己实现它,我将向你展示主要方法-paint()

    void ItemDelegatePaint::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(index.row() == 0 && index.column() == 0)
        {
            QRect source1 = QRect(option.rect.topLeft(),option.rect.size()/2);
            QRect source2 = QRect(option.rect.topLeft(),option.rect.size()/2);
    
            painter->drawLine(option.rect.topLeft(),option.rect.bottomRight());
    
            source1.moveTopLeft(source1.topLeft() += QPoint(source1.size().width(),0));
            painter->drawText(source1,"agent reagent");
    
            source2.moveBottomLeft(source2.bottomLeft() += QPoint(0,source2.size().height()));
            painter->drawText(source2,"hallide ion");
        }
    
        else
        {
            QStyledItemDelegate::paint(painter,option,index);
        } 
    }
    

    这段代码展示了主要思想,它不是最终版本,但你应该自己做所有这些具体的事情。当然这种方法不是很容易,你可以创建图片并将其设置为单元格,但这种情况下图片的可扩展性不好。如果用户调整某些标题的大小,我的代码可以正常工作。为了证明,请查看不同大小的屏幕截图。

    【讨论】:

    • 谢谢 ;)。我认为可能有一些简单的方法可以使用我不知道的标准标题来做到这一点。我理解你的问题。现在我在想是否值得写这么多代码来构建我自己的标题只是为了显示那个简单的标题的含义。
    • 此 QTableView 解决方案也适用于 QTableWidget:stackoverflow.com/questions/22635867/…
    【解决方案2】:

    如果这里显示的文本元素

    足够了,可以使用标准标题和我在评论中发布的链接中的解决方案来完成:

    from PyQt5 import QtCore, QtWidgets
    
    class MyTableWidget(QtWidgets.QTableWidget):
        def __init__(self, parent = None):
            QtWidgets.QTableWidget.__init__(self, parent)
            self.setRowCount(4)
            self.setColumnCount(5)
            self.items = []
            self.items.append(['white ppt','no reaction', 'no reaction', 'no reaction', 'no reaction'])
            self.items.append(['no reaction','white ppt', 'dissolves', 'dissolves', 'no reaction'])
            self.items.append(['no reaction','pale yellow\nprecipitate', 'dissolves\npartly', 'dissolves', 'no reaction'])
            self.items.append(['no reaction','yellow ppt', 'does not\ndissolve', 'does not\ndissolve', 'turns\nblue'])
            self.horizontalHeader().setFixedHeight(90)
            self.verticalHeader().setFixedWidth(120)
            self.hh = ['Ca(NO\u2083)\u2082', 'AgNO\u2083','AgNO\u2083\n+\nNH\u2083','AgNO\u2083\n+\nNa\u2083S\u2082O\u2083','Starch\n+\nNaOCl']
            self.vh = ['NaF', 'NaCl', 'NaBr or KBR', 'NaJ']
    
            self.addItems()
            self.addHeaderItems()
            # text in cornerButton
            btnTxt = '{: >15}\n{: >19}\n{:<}\n{:<}'.format('reagent', '\u21D2','halide', 'ion \u21D3')
    
            # add cornerbutton from http://stackoverflow.com/questions/22635867/is-it-possible-to-set-the-text-of-the-qtableview-corner-button
            btn = self.findChild(QtWidgets.QAbstractButton)
            btn.setText(btnTxt)
            btn.installEventFilter(self)
    
            opt = QtWidgets.QStyleOptionHeader()
            opt.text = btn.text()    
            # end cornerbutton 
    
        def addItems(self):  
            for r in range(0,len(self.items)):
                for c in range(0,len(self.items[r])):
                    item = QtWidgets.QTableWidgetItem()
                    item.setText(self.items[r][c])
                    self.setItem(r,c,item)
    
        def addHeaderItems(self):
            for i in range(0,len(self.hh)):
                item = QtWidgets.QTableWidgetItem()
                item.setText(self.hh[i])
                self.setHorizontalHeaderItem(i,item)
                self.setColumnWidth(i,150)
            for i in range(0,len(self.vh)):
                item = QtWidgets.QTableWidgetItem()
                item.setText(self.vh[i])
                self.setVerticalHeaderItem(i,item)
                self.setRowHeight(i,60)
    
            # eventfilter from http://stackoverflow.com/questions/22635867/is-it-possible-to-set-the-text-of-the-qtableview-corner-button
        def eventFilter(self, obj, event):
            if event.type() != QtCore.QEvent.Paint or not isinstance(
                obj, QtWidgets.QAbstractButton):
                return False
    
            # Paint by hand (borrowed from QTableCornerButton)
            opt = QtWidgets.QStyleOptionHeader()
            opt.initFrom(obj)
            styleState = QtWidgets.QStyle.State_None
            if obj.isEnabled():
                styleState |= QtWidgets.QStyle.State_Enabled
            if obj.isActiveWindow():
                styleState |= QtWidgets.QStyle.State_Active
            if obj.isDown():
                styleState |= QtWidgets.QStyle.State_Sunken
            opt.state = styleState
            opt.rect = obj.rect()
            # This line is the only difference to QTableCornerButton
            opt.text = obj.text()
            opt.position = QtWidgets.QStyleOptionHeader.OnlyOneSection
            painter = QtWidgets.QStylePainter(obj)
            painter.drawControl(QtWidgets.QStyle.CE_Header, opt)
    
            return True
    

    如果painter.drawControl()-method 被任何其他painter.draw...()-method 任意元素替换,包括。可以在cornerButton上绘制图形。

    【讨论】:

    • 感谢您的回答。我理解你所说的,但就我的工作而言,我认为这个解决方案有点矫枉过正,现在我要另辟蹊径。
    • 好的。我很高兴跟进您的问题并添加了如何绘制对角线。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多