首页 > 解决方案 > QHeaderview 中的排序指示器是什么?

问题描述

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

我不明白的是,根据我的理解,似乎应该调用 drawControl 来绘制排序指示器,但是我收到的标志从来没有我期望的 State_Up/Down,也没有受到打击.

三列,颜色鲜艳,但尽管在控件绘制后着色,但仍有一个可见的指示器

三列,每列都用 alpha 着色,但指标会渗出

使用 alpha 绘制,我们看到 A) 箭头很大,并且 B) 指示器只有一个阴影——如果文档似乎表明,如果由 drawControl 绘制,我们希望它周围还有一个框。

与上面相同的框,但箭头较小且未着色

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

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

微型车

标题

#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;
}

标签: c++cssqt

解决方案


原来,它是drawPrimitive。也就是说,我仍然不知道如何正确地为标签/标题的背景着色。上述方法,用最后绘制的 alpha 着色似乎......很愚蠢。

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

推荐阅读