As suggested by @Sgaist, I've implemented a "simple" demonstration of my QTableView below using a QItemDelegate to render the cell contents. I selected this delegate type instead of QStyledItemDelegate to have access to functions like drawDisplay() and drawFocus() instead of using painter->save() and painter->restore(). I moved the font settings from QTableModel::data() to QItemDelegate::paint() just to ensure the delegate was working.
The code produces a QTableView with 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 the QStyleOptionViewItem class?
#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"