Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTableView using setSpan() doesn't resize as expected
Forum Updated to NodeBB v4.3 + New Features

QTableView using setSpan() doesn't resize as expected

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 2 Posters 638 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Cole
    wrote on last edited by
    #1

    Hello! I am relatively new to Qt and am trying to create a QTableView to display a generic Comment structure. I want the table to have 2 rows per model entry where,

    • The first row contains 2 columns, a left-aligned comment title and some right aligned text that can be added later.
    • The second row should span both of the above mentioned columns and contain the comment text.

    The problem occurs when the table width is resized to be very narrow. This causes the height of the row containing the comment text (i.e. the 2nd row per model item) to resize incorrectly. It seems to me that the underlying Qt code may not be accounting for the row spanning both columns. However, I am looking for a way around this so that the comment text only uses the minimum amount of space required to display the text fully.

    I appreciate any an all help! Below is a minimal example and some screen shots. I am using qt version 5.12.8.

    Code:

    main.cpp

    #include "MainWindow.h"
    #include "ui_MainWindow.h"
    
    #include <QWidget>
    #include <QDockWidget>
    #include <QTableView>
    #include <QHeaderView>
    
    #include <vector>
    #include <string>
    
    struct Comment
    {
        Comment(const std::string& title_, const std::string& comment_) :
            title(title_), comment(comment_)
        {
        }
        std::string title;
        std::string comment;
    };
    
    class CommentModel : public QAbstractTableModel
    {
    public:
        CommentModel(QTableView* parent = nullptr) :
            QAbstractTableModel(parent),
            _view(parent)
    
        {
        }
    
        int columnCount(const QModelIndex&) const override { return 2; }
    
        int rowCount(const QModelIndex&) const override { return static_cast<int>( _text.size() * 2); }
    
        QVariant data(const QModelIndex& idx, int role = Qt::DisplayRole) const override
        {
            if(role == Qt::DisplayRole) {
                const auto& comment = _text[idx.row() / 2];
                if(idx.row() % 2 == 0) {
                    if(idx.column() == 0)
                        return QString::fromStdString(comment.title);
                    else if(idx.column() == 1) {
                        return QString::fromStdString("Placeholder");
                    }
                } else {
                    if(idx.column() == 0)
                        return QString::fromStdString(comment.comment);
                }
            } else if(role == Qt::TextAlignmentRole) {
                if(idx.column() == 1)
                    return static_cast<int>(Qt::AlignRight | Qt::AlignVCenter);
                return static_cast<int>(Qt::AlignLeft | Qt::AlignVCenter);
            }
            return QVariant();
        }
    
        QVariant headerData(int, Qt::Orientation, int = Qt::DisplayRole) const override
        {
            return QVariant();
        }
    
        void addText(const Comment& comment)
        {
            beginResetModel();
            _text.push_back(comment);
            for(size_t i = 0; i < _text.size(); ++i)
                _view->setSpan(i*2+1, 0, 1, 2);
            endResetModel();
        }
    
    private:
        std::vector<Comment> _text;
        QTableView* _view{ nullptr };
    };
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        setWindowTitle(tr("Table Test"));
    
        QDockWidget *dock = new QDockWidget(tr("Comment Table"), this);
        auto table = new QTableView(dock);
        auto model = new CommentModel(table);
        table->setModel(model);
        table->horizontalHeader()->hide();
        table->verticalHeader()->hide();
        table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
        table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
        table->horizontalHeader()->resizeSection(1, 130);
        table->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
        table->setFixedHeight(600);
    
        model->addText(Comment("comment 1", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."));
        model->addText(Comment("comment 2", "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."));
        model->addText(Comment("comment 3", "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
                        "non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."));
        model->addText(Comment("comment 4", "Platea dictumst quisque sagittis purus sit amet volutpat. Libero id faucibus nisl tincidunt eget nullam."));
        model->addText(Comment("comment 5", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
                               "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."));
    
        dock->setWidget(table);
        addDockWidget(Qt::TopDockWidgetArea, dock);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
    
    
        w.show();
        return a.exec();
    }
    

    Example of correct spacing:

    Good.png

    Example of undesired spacing:

    Undesired.png

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Please try with 5.15 - there were some changes wrt this.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      C 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        Please try with 5.15 - there were some changes wrt this.

        C Offline
        C Offline
        Cole
        wrote on last edited by
        #3

        @Christian-Ehrlicher thank you for the input! I tested with 5.15.2 and the problem is still present.

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Then please provide a minimal compilable example of your issue so we can take a look on it.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          C 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            Then please provide a minimal compilable example of your issue so we can take a look on it.

            C Offline
            C Offline
            Cole
            wrote on last edited by
            #5

            @Christian-Ehrlicher Sorry about that, this is my first time using the forum. I created the previous file using the generic Qt Creator project setup. However, I stripped down the code to one file main.cpp. Please let me know if this is still not what you are looking for.

            #include <QTableView>
            #include <QLayout>
            #include <QApplication>
            #include <QHeaderView>
            
            struct Comment
            {
                Comment(const std::string& title_, const std::string& comment_) :
                    title(title_), comment(comment_)
                {
                }
                std::string title;
                std::string comment;
            };
            
            class CommentModel : public QAbstractTableModel
            {
            public:
                CommentModel(QTableView* parent = nullptr) :
                    QAbstractTableModel(parent),
                    _view(parent)
            
                {
                }
            
                int columnCount(const QModelIndex&) const override { return 2; }
            
                int rowCount(const QModelIndex&) const override { return static_cast<int>( _text.size() * 2); }
            
                QVariant data(const QModelIndex& idx, int role = Qt::DisplayRole) const override
                {
                    if(role == Qt::DisplayRole) {
                        const auto& comment = _text[idx.row() / 2];
                        if(idx.row() % 2 == 0) {
                            if(idx.column() == 0)
                                return QString::fromStdString(comment.title);
                            else if(idx.column() == 1) {
                                return QString::fromStdString("Placeholder");
                            }
                        } else {
                            if(idx.column() == 0)
                                return QString::fromStdString(comment.comment);
                        }
                    }
                    return QVariant();
                }
            
                QVariant headerData(int, Qt::Orientation, int = Qt::DisplayRole) const override
                {
                    return QVariant();
                }
            
                void addText(const Comment& comment)
                {
                    beginResetModel();
                    _text.push_back(comment);
                    for(size_t i = 0; i < _text.size(); ++i)
                        _view->setSpan(i*2+1, 0, 1, 2);
                    endResetModel();
                }
            
            private:
                std::vector<Comment> _text;
                QTableView* _view{ nullptr };
            };
            
            class TableWidget : public QWidget
            {
            public:
                TableWidget(QWidget *parent = nullptr)
                    : QWidget(parent)
                {
                    setWindowTitle(tr("Table Test"));
            
                    auto table = new QTableView(this);
                    auto model = new CommentModel(table);
                    table->setModel(model);
                    table->horizontalHeader()->hide();
                    table->verticalHeader()->hide();
                    table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
                    table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
                    table->horizontalHeader()->resizeSection(1, 130);
                    table->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
                    table->setFixedHeight(600);
            
                    model->addText(Comment("comment 1", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."));
                    model->addText(Comment("comment 2", "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."));
                    model->addText(Comment("comment 3", "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
                                    "non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."));
                    model->addText(Comment("comment 4", "Platea dictumst quisque sagittis purus sit amet volutpat. Libero id faucibus nisl tincidunt eget nullam."));
                    model->addText(Comment("comment 5", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
                                           "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."));
            
                    this->setLayout(new QVBoxLayout);
                    this->layout()->addWidget(table);
                }
            };
            
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                TableWidget wid;
                wid.show();
                return a.exec();
            }
            
            
            1 Reply Last reply
            0
            • Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Thx for the reproducer and it's clear what happens - QCommonStylePrivate::viewItemSize() does (and currently can) not honor the fact that there is a span. I'll create a bug report for it later on.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              0
              • Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #7

                See https://bugreports.qt.io/browse/QTBUG-89116 . I've also already an idea how to fix it. But don't think it will go into 5.15 though (but I try)

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                1
                • C Offline
                  C Offline
                  Cole
                  wrote on last edited by
                  #8

                  Thank you @Christian-Ehrlicher, I appreciate your help!

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved