How to reduce padding on QTableView cells?
-
NOTE: Qt version: 6.10.1, Linux
I'm trying to adjust the amount of space between the contents of the cells and their borders in a
QTableViewto achieve a display similar to a DNA alignment editor. Each cell will only display a character ('A', 'T', 'C', 'G', or '-') in different colors, probably with different backgrounds. The goal is to have a padding of 1 or 2 pixels per cell. In the example below I usedview->setStyleSheet("QTableView::item{border:0px;padding:1px;}");but without any result. It doesn't matter if I change
QTableView::itemtoQTableViewalone, or omitborder:0px;. The final result is always a table with a considerable amount of space surrounding each individual character (more pronounced at the left and right sides). However, the stylesheet method works for other attributes. For example, uncommenting the line//view->setStyleSheet("QTableView::item{background-color:yellow;}");renders the background of the cells yellow.
#include <QAbstractTableModel> #include <QApplication> #include <QMainWindow> #include <QTableView> #include <QHeaderView> #include <QList> class TableModel : public QAbstractTableModel { Q_OBJECT private: int rows {10}; int columns {10}; char seqs[100]; QList<QString> names; public: explicit TableModel(QObject *parent = nullptr) { names.push_back("Species 01"); names.push_back("Species 02"); names.push_back("Species 03"); names.push_back("Species 04"); names.push_back("Species 05"); names.push_back("Species 06"); names.push_back("Species 07"); names.push_back("Species 08"); names.push_back("Species 09"); names.push_back("Species 10"); std::string d ="AGTATAATTATTCGGGCTGAGTTAGGTCAGCCAGGTAGATTCATTGGAGACGATCAGATTTATAATGTAGTTGTTACGGCGCATGCTTTTGTAATAATTT"; std::copy(std::begin(d), std::begin(d) + sizeof(seqs), std::begin(seqs)); } int rowCount(const QModelIndex &parent = QModelIndex()) const override { return rows; } int columnCount(const QModelIndex &parent = QModelIndex()) const override { return columns; } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { switch( role ) { case Qt::DisplayRole: if( index.column() == 0 ) { return QString("%1").arg( names[ index.row() ] ); } else { char base = seqs[index.row()*columns+index.column()]; return QString("%1").arg( base ); } break; case Qt::TextAlignmentRole: return int(Qt::AlignCenter | Qt::AlignVCenter); break; default: return QVariant(); } } }; class MainWindow : public QMainWindow { Q_OBJECT private: QTableView * view; TableModel * model; public: MainWindow(QWidget *parent = nullptr) { setMinimumSize( 400, 300 ); model = new TableModel( this ); view = new QTableView( this ); view->setModel( model ); // view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // view->setSizeAdjustPolicy( QAbstractScrollArea::AdjustToContents ); // QHeaderView * header = view->horizontalHeader(); // QHeaderView * rows = view->verticalHeader(); // header->hide(); // rows->hide(); // view->verticalHeader()->setDefaultSectionSize(10); // view->horizontalHeader()->setDefaultSectionSize(10); // view->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); // view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); view->resizeColumnsToContents(); view->setStyleSheet("QTableView::item{border:0px;padding:1px;}"); //view->setStyleSheet("QTableView::item{background-color:yellow;}"); setCentralWidget( view ); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } #include "main.moc" -
Hi,
Did you consider implementing a QStyledItemDelegate ?
That way you will have more control on the rendering of your content. -
Hi,
Did you consider implementing a QStyledItemDelegate ?
That way you will have more control on the rendering of your content.@SGaist said in How to reduce padding on QTableView cells?:
Hi,
Did you consider implementing a QStyledItemDelegate ?
That way you will have more control on the rendering of your content.Thanks @SGaist
I did consider implementing my own QStyledItemDelegate. In fact, I've tried it once but failed! I was hoping that there was a simpler way of styling Qt tables through style sheets.
-
As suggested by @Sgaist, I've implemented a "simple" demonstration of my
QTableViewbelow using aQItemDelegateto render the cell contents. I selected this delegate type instead ofQStyledItemDelegateto have access to functions likedrawDisplay()anddrawFocus()instead of usingpainter->save()andpainter->restore(). I moved the font settings fromQTableModel::data()toQItemDelegate::paint()just to ensure the delegate was working.The code produces a
QTableViewwith the table cells more or less adjusted to their contents. The first column with the sequence names is correct, but the subsequent columns for the bases are a bit wide. Apparently, there's a minimum width for columns, but I don't know where it's defined! How do I change that? Is it through theQStyleOptionViewItemclass?#include <QAbstractTableModel> #include <QApplication> #include <QMainWindow> #include <QTableView> #include <QHeaderView> #include <QItemDelegate> #include <QList> #include <QPainter> #include <QFont> class BaseDelegate : public QItemDelegate { Q_OBJECT public: explicit BaseDelegate(QObject *parent = nullptr) {} void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { // if ( index.column() > 0 ) { QString text = index.data(Qt::DisplayRole).toString(); QStyleOptionViewItem myOption = option; QFont font("Courier New"); font.setPointSize( 14 ); myOption.font = font; myOption.displayAlignment = Qt::AlignCenter | Qt::AlignVCenter; drawDisplay( painter, myOption, myOption.rect, text ); drawFocus( painter, myOption, myOption.rect ); } else { QItemDelegate::paint(painter, option, index); } } }; class TableModel : public QAbstractTableModel { Q_OBJECT private: int rows {10}; int columns {10}; char seqs[100]; QList<QString> names; public: explicit TableModel(QObject *parent = nullptr) { names.push_back("Species 01"); names.push_back("Species 02"); names.push_back("Species 03"); names.push_back("Species 04"); names.push_back("Species 05"); names.push_back("Species 06"); names.push_back("Species 07"); names.push_back("Species 08"); names.push_back("Species 09"); names.push_back("Species 10"); std::string d ="AGTATAATTATTCGGGCTGAGTTAGGTCAGCCAGGTAGATTCATTGGAGACGATCAGATTTATAATGTAGTTGTTACGGCGCATGCTTTTGTAATAATTT"; std::copy(std::begin(d), std::begin(d) + sizeof(seqs), std::begin(seqs)); } int rowCount(const QModelIndex &parent = QModelIndex()) const override { return rows; } int columnCount(const QModelIndex &parent = QModelIndex()) const override { return columns; } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { switch( role ) { case Qt::DisplayRole: if( index.column() == 0 ) { return QString("%1").arg( names[ index.row() ] ); } else { char base = seqs[index.row()*columns+index.column()]; return QString("%1").arg( base ); } break; default: return QVariant(); } } }; class MainWindow : public QMainWindow { Q_OBJECT private: QTableView * view; TableModel * model; public: MainWindow(QWidget *parent = nullptr) { setMinimumSize( 400, 300 ); model = new TableModel( this ); view = new QTableView( this ); view->setModel( model ); view->resizeColumnsToContents(); view->setItemDelegate( new BaseDelegate ); setCentralWidget( view ); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } #include "main.moc" -
Your model can return a Qt::SizeHintRole.