是什么在QHeaderview中绘制排序指示器?

时间:2018-08-16 16:28:29

标签: c++ css qt

我正在尝试在Linux RHEL 6.8的Qt 4.8中为QHeaderView的背景着色。所有人都认为这应该可以通过使用QProxyStyle来实现(与重载QHeaderView相对,在使用Creator时,我仍然不知道如何正确执行操作,但这是另一个问题/谷歌)。

我不了解的是,根据我的理解,应该调用drawControl来绘制排序指示器,但是我收到的标志从不具有我期望的State_Up / Down,也不会得到击中它。

Three columns, brightly colored but with an indicator visible despite being colored AFTER the control draws

Three columns, each colored with an alpha, but the indicator bleeds through

用alpha绘制,我们看到A)箭头很大,B)指示器仅一个阴影深-如果文档看起来好像被drawControl绘制,我们希望它周围也有一个方框表示。

Same boxes as above, but with a smaller arrow and not colorized

在这里,应用样式表后,我们的箭头变小了,但是根本没有调用StyleProxy!我相信这是一个已知问题。

由于我似乎无法覆盖代理中指标的绘制,该怎么办?

MCV

标题

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QProxyStyle>


QT_FORWARD_DECLARE_CLASS(QTreeWidget)
QT_FORWARD_DECLARE_CLASS(QTreeWidgetItem)

namespace Ui {
class MainWindow;
}

class MyProxy : public QProxyStyle
{
    Q_OBJECT
public:
    MyProxy(QStyle* style) : QProxyStyle(style) {}

    virtual void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
};


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow() {};

private:
    void init();
    QTreeWidgetItem* makeItem(QTreeWidgetItem* parent = NULL);

    QTreeWidget* m_tree;
};

#endif // MAINWINDOW_H

来源

#include "mainwindow.h"
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QStyleOptionHeader>
#include <QPainter>
#include <QVBoxLayout>
#include <QHeaderView>

void MyProxy::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    if (element >= CE_Header && element <= CE_HeaderLabel) {
        const QStyleOptionHeader* ho = qstyleoption_cast<const QStyleOptionHeader*>(option);

        // expectation: we'd be able to override all the colors that aren't being drawn here

        painter->save();
        QProxyStyle::drawControl(element, option, painter, widget);
        painter->restore();

        // as an example, just blart all over everything
        QColor col(Qt::GlobalColor(ho->section+Qt::red));
        //col.setAlphaF(0.3); // if you want to see what you've painted over
        painter->fillRect(option->rect, QBrush(col));

    } else {
        QProxyStyle::drawControl(element, option, painter, widget);
    }
}


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
   init();


    m_tree->setStyle(new MyProxy(m_tree->style()));

    // if this is in, our proxy never gets called with the header, but the arrows aren't huge
    // without it, we never get hit for the indicator anyway
//        m_tree->header()->setStyleSheet("QHeaderView::down-arrow { width: 16px; height:10px; subcontrol-position: center right;} "
//                              "QHeaderView::section { padding-right:2px; } "
//                              );

}

// handle the stuff to make the example go
void MainWindow::init() {
    resize(400,200);
    setWindowTitle("Without StyleSheet");

    QWidget* m = new QWidget(this);
    this->setCentralWidget(m);

    QVBoxLayout* layout = new QVBoxLayout(m);
    m->setLayout(layout);

    m_tree = new QTreeWidget(m);
    m_tree->setSortingEnabled(true);
    m_tree->setColumnCount(3);
    m_tree->header()->setProperty("showSortIndicator", QVariant(true));
    m_tree->header()->setDefaultAlignment(Qt::AlignCenter);

    layout->addWidget(m_tree);

    QTreeWidgetItem* item = makeItem();
    item->setText(0, "Item 1:1");
    item->setText(1, "Item 1:2");

    item = makeItem();
    item->setText(0, "Item 2");

    item = makeItem();
    item->setText(0, "Item 3 - Children");

    QTreeWidgetItem* kid = makeItem(item);
    kid->setText(1, "Paw Patrol!");

    QStringList labels;
    labels.append("Column\n1");
    labels.append("Column\n2");
    labels.append("Column\n3");
    m_tree->setHeaderLabels(labels);
    m_tree->setAlternatingRowColors(true);
    m_tree->header()->setResizeMode(QHeaderView::ResizeToContents);
}

QTreeWidgetItem* MainWindow::makeItem(QTreeWidgetItem* parent)  {
    QTreeWidgetItem* item = parent ? new QTreeWidgetItem(parent) : new QTreeWidgetItem(m_tree);
    for(int i=0; i < 3; ++i) {
        QColor col( Qt::GlobalColor(Qt::darkRed+i));
        col.setAlphaF(0.2);
        item->setBackgroundColor(i, col);
    }

    return item;
}

2 个答案:

答案 0 :(得分:0)

结果是drawPrimitive。就是说,我仍然对如何正确给标签/标题的背景上色感到困惑。上面的方法,用最后绘制的Alpha进行着色似乎很愚蠢。

void ObjHeaderProxyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    if( element ==  PE_IndicatorHeaderArrow )
    {
    // ....

答案 1 :(得分:0)

另一个影响大小的选项是使用QProxyStyle :: pixelMetric缩小大小。这样既减小了视觉尺寸,又减小了标签周围的边距,从而使所有尺寸的尺寸都更加正确。

$mvn_prj_vrsn

为什么它似乎从未听过PM_HeaderMarkSize-“标题中排序指示器的大小。”-我无法理解。