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



我正在为我的应用程序创建一个单列QTableWidget(_tw)。我希望这个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);

我希望水平标题与表格的宽度相同,并且滚动不明智。目前情况并非如此:标题具有列的大小(大于屏幕上显示的大小)。由于标题文本水平对齐,因此不会显示它并随滚动移动。

您可以尝试创建一个自定义类,该类将类似标题的区域应用于任何QAbstractScrollArea(包括QTableWidget),并在表格小部件上设置视口边距。您不需要破坏标题而不是滚动,但是如果您需要一些类似标题的行为,则需要手动执行此操作。

未经测试的代码:

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

然后在表格小部件上设置视口边距,如下所示:

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

然后只需创建Header的实例:

Header *header = new Header(_tw);

如果这段代码有效 - Romha Korev 获得荣誉。我从他对这个问题的回答中得到了这个想法。

希望这有帮助。

我尝试的所有其他解决方案都给了我一些像素差距,我觉得这些差距太明显了。我决定做大,并创建一个专门用于回答此问题的自定义QWidget

基本上我只是创建了一个仅包含QTableWidgetQWidget,没有标题。为了保持所有东西的大小相同,我加了一行,它将保持空白并被QPushButton隐藏。出于同样的原因,我为我的标题提供了我想要的高度。

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

相关内容

最新更新