Reputation: 779
I'm running the sample code below with Qt5.11.0 on OSX 10.13.6 (also RHEL 7.6, where the problem also occurs, but not as ugly as on OSX). The test program displays a custom model in a QTableView, with indexWidgets set for several of the columns:
#include <QtCore/QDebug>
#include <QtCore/QAbstractItemModel>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QTableView>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QRadioButton>
class AModel : public QAbstractItemModel
{
public:
int rowCount( const QModelIndex& parent = QModelIndex() ) const override {
return 5;
};
int columnCount( const QModelIndex& parent = QModelIndex() ) const override {
return 5;
};
QModelIndex parent( const QModelIndex& index ) const override {
return QModelIndex();
};
QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const override {
if( ( ! parent.isValid() ) &&
row >= 0 && row < 5 &&
column >= 0 && column < 5 ) {
return createIndex( row, column );
} else {
return QModelIndex();
}
};
QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override {
QVariant qval;
if( index.column() >= 1 && index.column() < 4 ) { return QVariant(); }
switch( role ) {
case Qt::DisplayRole:
qval = QString( "%1,%2" ).arg( index.row() ).arg( index.column() );
break;
default:
qval = QVariant();
break;
}
return qval;
};
};
class AWidget : public QWidget
{
public:
AWidget( QWidget* parent ) : QWidget( parent ) {
QHBoxLayout* l = new QHBoxLayout();
this->setLayout( l );
QRadioButton* save = new QRadioButton( "Save" );
QRadioButton* del = new QRadioButton( "Delete" );
l->addWidget( save );
l->addWidget( del );
};
};
int
main( int argc, char *argv[] ) {
QApplication app( argc, argv );
QMainWindow* mw = new QMainWindow();
AModel* model = new AModel();
QTableView* view = new QTableView();
view->setModel( model );
// view->verticalHeader()->setDefaultSectionSize( 15 );
for( int irow = 0; irow < model->rowCount(); irow++ ) {
QPushButton* pb = new QPushButton( "Mogrify", mw );
QRadioButton* rb = new QRadioButton( "Choose", mw );
AWidget* aw = new AWidget( mw );
QObject::connect( pb, &QPushButton::clicked, [irow](){ qDebug() << "Mogrifying " << irow; } );
QObject::connect( rb, &QRadioButton::clicked, [irow](){ qDebug() << "Choosing " << irow; } );
view->setIndexWidget( model->index( irow, 1 ), pb );
view->setIndexWidget( model->index( irow, 2 ), rb );
view->setIndexWidget( model->index( irow, 3 ), aw );
}
view->resizeColumnsToContents();
mw->setCentralWidget( view );
mw->show();
return app.exec();
}
If I just run this as shown above, the result comes out with all the table-embedded widgets having enough space:
If however I uncomment the call to setDefaultSectionSize() in the code above, the table-embedded widgets do not size themselves the way I'd wish. The QPushButton is cut off at the bottom, the QRadioButton is crammed in with little padding, and the custom composite widget doesn't show up at all:
I've tried all manner of QSizeHint experiments, subclassing, and internet searching to get these embedded widgets to size themselves according to the space available in the table cells, so far to no avail. How do I make these embedded indexWidgets paint themselves so they fit into the cell space provided in the QTableView, when I'm telling the QTableView how big its cells should be?
Upvotes: 1
Views: 878
Reputation: 243907
The problem is not in the QTableView but in your custom widget. The custom widget has a layout that must have margins equal to 0.
class AWidget : public QWidget
{
public:
AWidget( QWidget* parent=nullptr) :
QWidget( parent )
{
QHBoxLayout* l = new QHBoxLayout(this);
l->setContentsMargins(0, 0, 0, 0); // <----
QRadioButton* save = new QRadioButton( "Save" );
QRadioButton* del = new QRadioButton( "Delete" );
l->addWidget( save );
l->addWidget( del );
};
};
Upvotes: 1