我创建了一个列跟踪布局,它继承自QHBoxLayout
. 它不如将小部件嵌入到标题中,但至少它给出了小部件绑定到它们各自的表格列的外观:
演示截屏

该项目托管在 GitHub 上,地址为https://github.com/sashoalm/ColumnAlignedLayout。
您只需要 columnalignedlayout.cpp 和 columnalignedlayout.h
由于它们足够小,我将直接粘贴它们。
列对齐布局.h
#ifndef COLUMNALIGNEDLAYOUT_H
#define COLUMNALIGNEDLAYOUT_H
#include <QHBoxLayout>
class QHeaderView;
class ColumnAlignedLayout : public QHBoxLayout
{
Q_OBJECT
public:
ColumnAlignedLayout();
explicit ColumnAlignedLayout(QWidget *parent);
void setTableColumnsToTrack(QHeaderView *view) { headerView = view; }
signals:
public slots:
private:
void setGeometry(const QRect &r);
QHeaderView *headerView;
};
#endif // COLUMNALIGNEDLAYOUT_H
columnalignedlayout.cpp
#include "columnalignedlayout.h"
#include <QHeaderView>
ColumnAlignedLayout::ColumnAlignedLayout()
: QHBoxLayout()
{
}
ColumnAlignedLayout::ColumnAlignedLayout(QWidget *parent)
: QHBoxLayout(parent)
{
}
void ColumnAlignedLayout::setGeometry(const QRect &r)
{
QHBoxLayout::setGeometry(r);
Q_ASSERT_X(headerView, "layout", "no table columns to track");
if (!headerView) {
return;
}
Q_ASSERT_X(headerView->count() == count(), "layout", "there must be as many items in the layout as there are columns in the table");
if (headerView->count() != count()) {
return;
}
Q_ASSERT(parentWidget());
int widgetX = parentWidget()->mapToGlobal(QPoint(0, 0)).x();
int headerX = headerView->mapToGlobal(QPoint(0, 0)).x();
int delta = headerX - widgetX;
for (int ii = 0; ii < headerView->count(); ++ii) {
int pos = headerView->sectionViewportPosition(ii);
int size = headerView->sectionSize(ii);
auto item = itemAt(ii);
auto r = item->geometry();
r.setLeft(pos + delta);
r.setWidth(size);
item->setGeometry(r);
}
}
示例用法:
alignedLayout = new ColumnAlignedLayout();
alignedLayout->addWidget(new QLineEdit(this));
alignedLayout->addWidget(new QLineEdit(this));
alignedLayout->addWidget(new QLineEdit(this));
alignedLayout->addWidget(new QLineEdit(this));
ui->widget->setLayout(alignedLayout);
alignedLayout->setTableColumnsToTrack(ui->tableWidget->horizontalHeader());
alignedLayout->setParent(ui->widget);
connect(ui->tableWidget->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), SLOT(invalidateAlignedLayout()));
connect(ui->tableWidget->horizontalScrollBar(), SIGNAL(valueChanged(int)), SLOT(invalidateAlignedLayout()));
然后在 slot 中调用 invalidate():
void MainWindow::invalidateAlignedLayout()
{
alignedLayout->invalidate();
}