Поскольку QTableWidget
, по-видимому, должно содержать что-то в каждой ячейке, а по умолчанию используется редактируемое текстовое поле, кажется, что решением было бы вставить не редактируемый фиктивный элемент в пустые ячейки. Или иметь собственный виджет, который может скрывать его содержимое, что я и сделал в приведенном ниже примере.
Вы специально задали вопрос о фиксированном размере ... на самом деле есть несколько способов сделать это, в зависимости отна точных потребностях. Вы можете установить фиксированные размеры для всей таблицы, используя горизонтальные и вертикальные заголовки и делая их неизменяемыми. Другой способ - вызвать QTableView::setColumnWidth() / setRowHeight()
для каждой строки / столбца (при добавлении / item или всякий раз).
Вот пример использования первого метода (установка размера в заголовках) и двух способов определения фактического размера. - либо фиксированный размер перед построением таблицы, либо использование поиска по элементу пользовательского виджета для определения размера.
ОБНОВЛЕНИЕ : предыдущая версия использовала пустышку QTableWidgetItem
для заполненияпустые области, но я думаю, что это лучше, если в любом случае нужно использовать собственный виджет. См. Историю изменений для предыдущей версии.
// main.cpp
#include <QtWidgets>
// A custom table widget item which contains a progress bar. The bar is
// hidden if the value is set to < 0.
class ProgressBarTwItem : public QWidget, public QTableWidgetItem
{
Q_OBJECT
public:
ProgressBarTwItem(QWidget *parent = nullptr, int value = -1) :
QWidget(parent),
QTableWidgetItem(QTableWidgetItem::UserType)
{
QHBoxLayout *l = new QHBoxLayout(this);
l->setContentsMargins(0,0,0,0);
m_pb = new QProgressBar(this);
// don't let PB size dictate our size
m_pb->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
m_pb->setAlignment(Qt::AlignCenter);
m_pb->setMaximum(44);
l->addWidget(m_pb);
setValue(value);
}
QSize sizeHint() const override { return QSize(75, 25); }
public slots:
void setValue(int value = -1) const
{
m_pb->setVisible(value > -1);
if (value > -1)
m_pb->setValue(value);
}
private:
QProgressBar *m_pb;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyle("Fusion");
QDialog d;
d.setLayout(new QVBoxLayout);
QTableWidget *tw = new QTableWidget(5, 4, &d);
d.layout()->addWidget(tw);
// set to `true` to find the largest size from added custom widgets,
// otherwise use preset size
const bool useWidgetSize = true;
// This will be the fixed cell size, either preset or determined from custom widget.
// If looking up from widgets, this becomes the minimum size
// (eg. in case widgets didn't return valid sizes).
QSize cellSize = (useWidgetSize ? QSize(10, 10) : QSize(50, 15));
for (int r=0; r < tw->rowCount(); ++r) {
for (int c=0; c < tw->columnCount(); ++c) {
// make some widgets hidden and others display a progress value
const int val = (!((r*c) % (1+c)) ? -1 : (c+1 + r*10));
ProgressBarTwItem *item = new ProgressBarTwItem(tw, val);
tw->setCellWidget(r, c, item);
// tw->setItem(r, c, item); // needed? widget is shown anyway... docs not clear.
// Check the size.
if (useWidgetSize)
cellSize = cellSize.expandedTo(item->sizeHint());
}
}
// set fixed sizes for columns and rows on the horizontal and vertical headers
// respectively (this works even if they are hidden)
tw->horizontalHeader()->setDefaultSectionSize(cellSize.width());
tw->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
tw->verticalHeader()->setDefaultSectionSize(cellSize.height());
tw->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
return d.exec();
}
#include "main.moc"