如何在可滚动的QTableWidget中冻结水平标题?

时间:2019-07-09 07:03:02

标签: c++ qt

我正在为我的应用程序(_tw)创建一个单列QTableWidget。我希望这个QTableWidget在垂直和水平方向都可以滚动。我隐藏了垂直标题,但是我需要水平标题。 问题是我无法获得“冻结”(对水平滚动不敏感)的水平标题,并且此标题的文本通常隐藏在滚动中。此外,在垂直滚动条之后,我可以看到水平标题的像素,这是不必要的。

我试图以不同的方式解决该问题,因为我一直在努力使此表可水平滚动。未能成功,每次滚动条移动时,我都尝试重新定位标题。即使我失败了,这也更像是一种解决方法,而不是解决方案。

_tw->setHorizontalScroolBarPolicy(Qt::ScrollBarAlwaysOn);
_tw->setHorizontalScroolMode(QAbstractItemView::ScrollPerPixel);
_tw->verticalHeader()->hide();
_tw->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
_tw->horizontalHeader()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
_tw->horizontalHeader()->setFixedHeight(_headerHeight);
_tw->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);

_tw->horizontalHeader()->setFixedWitdh(_tableWidth);
_tw->setFixedWidth(_tableWidth);

_tw->setColumnWidth(0, _tableWidth + _offset);

我希望水平标题与表的宽度相同,并且难以滚动。当前情况并非如此:标题具有列的大小(大于屏幕上显示的大小)。由于标题文本是水平对齐的,因此不会显示,而是随滚动条一起移动。

2 个答案:

答案 0 :(得分:1)

您可以尝试创建一个自定义类,将类头区域应用于任何QAbstractScrollArea(包括QTableWidget),并在tablewidget上设置视口页边距。您不需要弄乱标题不会滚动,但是如果您需要某种类似于标题的行为,则需要手动进行。

未经测试的代码:

class Header: public QWidget
{
public:
    Header(QAbstractScrollArea* parent=nullptr): QWidget(parent)
    {
        setFixedSize(parent->width(), 40);
    }

    virtual void paintEvent(QPaintEvent* event)
    {
        QPainter painter(this);
        QFont font("Arial");
        QFontMetrics fm(font);
        QRect txtRect;
        QString txt = "Header_name";
        txtRect = fm.boundingRect(txt).trabslated(dx, dy);//translate it to position you want
        painter.setFont(font);
        painter.painter.drawText(txtRect, txt);
    }
};

然后在tablewidget上设置视口边距,如下所示:

_tw->setViewportMargins(0, 40, 0, 0);

然后仅创建Header的实例:

Header *header = new Header(_tw);

如果此代码有效-Romha Korev获得功劳。我从他对this question的回答中得到了这个想法。

希望这会有所帮助。

答案 1 :(得分:0)

我尝试过的所有其他解决方案给了我一些我发现太明显的像素间隙。我决定大胆尝试,并创建一个专门用于解决此问题的自定义QWidget

基本上,我只是创建了一个QWidget,只包含QTableWidget,没有标题。为了使所有内容保持相同大小,我添加了一行,该行将保持空白,并被QPushButton隐藏。出于相同的原因,我将此行的高度设置为标题的高度。

在修改了QTableWidget的行为以使其跳过第一行之后,我创建了一个QPushButton,并将我的自定义小部件作为父级。幸运的是,在我的应用程序中,它们的外观与其他QHeader相同。由于这是一个自定义窗口小部件,因此要使按钮位于空白行的顶部,就可以用一个简单的button->move(0, 2);来完成。