Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Qt Academy Launch in California!

    How get content width of a QListView

    General and Desktop
    2
    5
    3046
    Loading More Posts
    • 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.
    • F
      floreal797 last edited by

      Hi,

      I want to get the width of the content of a QListView. Indeed, this width is different if vertical scrollbar is visible or not. In my application, scrollbar of QListView is visible only if it is needed.

      So, I know I can get the width of the QListView, but this width include the scrollbar.

      So to know the width without the scrollbar, I have two solutions:

      • Find a solution to get the information of the scrollbar is visible or not (because I know how get the scrollbar witdh)
      • Find the size of the QListView that does not include the scrollbar.

      But I don't know how do any one of this methods... Can you help me please?

      Floréal.

      1 Reply Last reply Reply Quote 0
      • F
        floreal797 last edited by

        Hi,

        I have not found how do that with QFontMetrics as I don't know how set wordwrap with it.

        Anyway, Y have succeeded to make something that works almost fine with QLabels. But it works only if I don't resize the window.

        See these screenshots:

        Normal size, when the program is launched:
        !http://www.hostingpicture.fr/upload/e5ff0755d35ce721ddcc3cc03c7be5bb.png(Avant)!

        When I enlarge the window, I see that:
        !http://www.hostingpicture.fr/upload/fcb1add302955f12e8cfa1b4213874ea.png(Après)!

        So, the items are resized BUT the following item was placed always at the same place as if the size of items are always the same.

        How correct that?

        To help you, I post my code :

        MainWindow.h:
        @#ifndef MAINWINDOW_H
        #define MAINWINDOW_H

        #include <QMainWindow>
        #include <QStandardItemModel>
        #include <QListView>
        #include <QStandardItem>

        namespace Ui {
        class MainWindow;
        }

        class MainWindow : public QMainWindow
        {
        Q_OBJECT

        public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();

        private:
        Ui::MainWindow *ui;

        private:
        QStandardItemModel *model1;

        public slots:
        void init();
        };

        #endif // MAINWINDOW_H@

        MainWindow.cpp:
        @#include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include "listviewdelegate.h"

        MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
        {
        ui->setupUi(this);
        }

        MainWindow::~MainWindow()
        {
        delete ui;
        }

        void MainWindow::init()
        {
        model1 = new QStandardItemModel(this);
        ui->listView->setIconSize(QSize(15,15));
        ui->listView->setModel(model1);
        ui->listView->setItemDelegate(new ListViewDelegate(0));
        for (int var = 0; var < 5; ++var) {
        QStandardItem* item = new QStandardItem("1.2.0|Bonjour le monde Bonjour le monde Bonjour le monde Bonjour le monde Bonjour le monde Bonjour le monde Bonjour le monde Bonjour le monde Bonjour le monde Bonjour le monde le monde Bonjour le monde le monde ");
        model1->appendRow(item);
        }
        show();
        }@

        listviewdelegate.h:
        @#ifndef LISTVIEWDELEGATE_H
        #define LISTVIEWDELEGATE_H

        #include <QApplication>
        #include <QFlags>
        #include <QLabel>
        #include <QPainter>
        #include <QStyledItemDelegate>
        #include <QTextDocument>

        class ListViewDelegate : public QStyledItemDelegate
        {
        public:
        ListViewDelegate(int wiLu);

        protected:
        void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
        QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const;
        int wi;
        };

        #endif // LISTEVIEWDELEGATE_H
        @

        @#include "listviewdelegate.h"
        #include <QScrollBar>
        #include <QStringList>
        #include <QFontMetrics>

        ListViewDelegate::ListViewDelegate(int wiLu)
        {
        wi = wiLu;
        }

        void ListViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
        {
        QStyleOptionViewItemV4 opt = option;
        initStyleOption(&opt, index);

        QString allLine = opt.text;
        QStringList parts = allLine.split("|");
        QString indexItem = parts[0];
        QString line = parts[1];
        QSize s = opt.widget->baseSize();
        
        // draw correct background
        opt.text = "";
        QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
        style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
        
        QTextDocument doc;
        doc.setHtml(opt.text);
        doc.setTextWidth(s.width());
        
        //QRect rect = opt.rect;
        QRect rect (opt.rect.left(), opt.rect.top(), opt.rect.width(),opt.rect.height());
        QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
        if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
            cg = QPalette::Inactive;
        
        // set pen color
        if (opt.state & QStyle::State_Selected)
            painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
        else
            painter->setPen(opt.palette.color(cg, QPalette::Text));
        
        // draw puce
        int level = 0;
        if (indexItem.contains(".")) {
            QStringList nums = indexItem.split('.');
            QString puce = nums[nums.length() - 2];
            level = nums.length() - 2;
            painter->drawText(rect.left() + 2 + level * 30, rect.top(), 18, 20, 0, puce+'.');
        }
        else {
            level = indexItem.toInt();
            painter->fillRect(rect.left() + 2 + level * 30, rect.top() + 2, 8, 8, Qt::black);
        }
        
        // draw text
        painter->drawText(QRect(rect.left() + 24 + (level * 30), rect.top(), rect.width() - 28 - (level * 30), rect.height()),
                          Qt::AlignJustify | Qt::AlignVCenter | Qt::TextWordWrap, line);
        

        }
        QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const
        {
        QStyleOptionViewItemV4 opt = option;
        initStyleOption(&opt, index);

        QString allLine = opt.text;
        QStringList parts = allLine.split("|");
        QString line = parts[1];
        QString indexItem = parts[0];
        
        int level = 0;
        if (indexItem.contains(".")) {
        
        }
        else {
            level = indexItem.toInt();
        }
        
        QLabel* text = new QLabel();
        text->setWordWrap(true);
        
        int sizeScroll = QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent);
        text->setMaximumWidth(opt.widget->width() - 28 - (level * 30) - 8 - sizeScroll);
        text->setMinimumWidth(opt.widget->width() - 28 - (level * 30) - 8 - sizeScroll);
        text->setText(line);
        text->adjustSize();
        return QSize(opt.widget->width() - 8 - sizeScroll, text->size().height());
        

        }
        @

        So, may be we have to define some repaint while window is resized, I don't know...

        Please help me,

        Thank you for your help, and in advance for your future help,

        Floréal.

        1 Reply Last reply Reply Quote 0
        • SGaist
          SGaist Lifetime Qt Champion last edited by

          Do you mean with "this function":http://qt-project.org/doc/qt-4.8/qfontmetrics.html#boundingRect-6 and "Qt::TextWordWrap":http://qt-project.org/doc/qt-4.8/qt.html#TextFlag-enum ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply Reply Quote 0
          • F
            floreal797 last edited by

            Thank you for your help.

            Now I use QFontMetrics well, but the problem is still the same. I have a little bit simplified the code so maybe you will better understand where is the problem.

            When I launch the application, the list is shown very well:
            !http://www.hostingpicture.fr/upload/c8f1b2b307e9d2d2f5a563c76aa89991.png(Before)!

            But if I enlarge the window, increasing width, The list is bad:
            !http://www.hostingpicture.fr/upload/b23c2faed70cf29ac18c52eab347f631.png(After)!

            So if I understand the problem it was like it:

            • Height is effectively changed and adapted to the text
            • But y value where each item of the list is painted is never changed

            So, now, I need to find a solution to make the y value of each item when window is resized refreshed.

            Below is my new code for listviewdelegate.cpp :
            @#include "listviewdelegate.h"
            #include <QScrollBar>
            #include <QStringList>
            #include <QFontMetrics>

            ListViewDelegate::ListViewDelegate(int wiLu)
            {
            wi = wiLu;
            }

            void ListViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
            {
            QStyleOptionViewItemV4 opt = option;
            initStyleOption(&opt, index);

            QString allLine = opt.text;
            QStringList parts = allLine.split("|");
            QString indexItem = parts[0];
            QString line = parts[1];
            QSize s = opt.widget->baseSize();
            
            // draw correct background
            opt.text = "";
            QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
            style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
            
            QTextDocument doc;
            doc.setHtml(opt.text);
            doc.setTextWidth(s.width());
            
            //QRect rect = opt.rect;
            QRect rect (opt.rect.left(), opt.rect.top(), opt.rect.width(),opt.rect.height());
            QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
            if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
                cg = QPalette::Inactive;
            
            // set pen color
            if (opt.state & QStyle::State_Selected)
                painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
            else
                painter->setPen(opt.palette.color(cg, QPalette::Text));
            
            // draw text
            painter->drawText(QRect(rect.left() + 24, rect.top(), rect.width() - 28, rect.height()),
                              Qt::AlignJustify | Qt::AlignVCenter | Qt::TextWordWrap, line);
            

            }
            QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const
            {
            QStyleOptionViewItemV4 opt = option;
            initStyleOption(&opt, index);

            QString allLine = opt.text;
            QStringList parts = allLine.split("|");
            QString line = parts[1];
            QString indexItem = parts[0];
            
            int sizeScroll = QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent);
            
            QFont font;
            
            QFontMetrics text (font);
            QRect rect = text.boundingRect(0, 0, opt.widget->width() - 8 - sizeScroll, 0, Qt::TextWordWrap, line);
            
            return QSize(rect.width(), rect.height());
            

            }
            @

            The other files where not modified, you can find the code in my previous post.

            Thank you for your help, and in advance for your future help :)

            Floréal.

            1 Reply Last reply Reply Quote 0
            • F
              floreal797 last edited by

              Up please... There is no solution to solve my problem?

              1 Reply Last reply Reply Quote 0
              • First post
                Last post