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. How get content width of a QListView
QtWS25 Last Chance

How get content width of a QListView

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 3.5k 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.
  • F Offline
    F Offline
    floreal797
    wrote on last edited by
    #1

    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
    0
    • F Offline
      F Offline
      floreal797
      wrote on last edited by
      #2

      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
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        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
        0
        • F Offline
          F Offline
          floreal797
          wrote on last edited by
          #4

          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
          0
          • F Offline
            F Offline
            floreal797
            wrote on last edited by
            #5

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

            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