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 can I add custom widget to QListView?
Forum Updated to NodeBB v4.3 + New Features

How can I add custom widget to QListView?

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 4 Posters 2.7k Views 3 Watching
  • 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.
  • B Offline
    B Offline
    BushyAxis793
    wrote on last edited by
    #8

    Here is my paint():

    void OperationWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    
        if(!index.isValid())
        {
            return;
        }
    
        painter->save();
    
        if(option.state & QStyle::State_Selected)
        {
            painter->fillRect(option.rect,option.palette.highlight());
        }
    
    
        OperationWidget* widget = index.data().value<OperationWidget*>();
    
        QRect boundRect = QRect(0,00,275,70);
        
        painter->setPen(QPen(Qt::black,0.5,Qt::SolidLine));
       
        painter->drawRect(boundRect);
    
        QRect operationNameRect = QRect(0,10,275,70);
        QRect operationToolsRect =  QRect(10,40,275,70);
        QRect operationTimeRect = QRect(-10,40,275,70);
        QFont bold("Roboto",10);
        bold.setBold(true);
        painter->setFont(bold);
        painter->setPen(Qt::black);
    
        painter->drawText(operationNameRect,Qt::AlignTop | Qt::AlignHCenter,widget->GetOperationName());
        painter->drawText(operationToolsRect,Qt::AlignLeft,QString::number(widget->GetToolsQuantity())+ " [szt.]");
        painter->drawText(operationTimeRect,Qt::AlignRight,QString::number(widget->GetOperationTime())+ " [min.]");
    
    
    
    
    
    }
    
    M 1 Reply Last reply
    0
    • B BushyAxis793

      Here is my paint():

      void OperationWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
      {
      
          if(!index.isValid())
          {
              return;
          }
      
          painter->save();
      
          if(option.state & QStyle::State_Selected)
          {
              painter->fillRect(option.rect,option.palette.highlight());
          }
      
      
          OperationWidget* widget = index.data().value<OperationWidget*>();
      
          QRect boundRect = QRect(0,00,275,70);
          
          painter->setPen(QPen(Qt::black,0.5,Qt::SolidLine));
         
          painter->drawRect(boundRect);
      
          QRect operationNameRect = QRect(0,10,275,70);
          QRect operationToolsRect =  QRect(10,40,275,70);
          QRect operationTimeRect = QRect(-10,40,275,70);
          QFont bold("Roboto",10);
          bold.setBold(true);
          painter->setFont(bold);
          painter->setPen(Qt::black);
      
          painter->drawText(operationNameRect,Qt::AlignTop | Qt::AlignHCenter,widget->GetOperationName());
          painter->drawText(operationToolsRect,Qt::AlignLeft,QString::number(widget->GetToolsQuantity())+ " [szt.]");
          painter->drawText(operationTimeRect,Qt::AlignRight,QString::number(widget->GetOperationTime())+ " [min.]");
      
      
      
      
      
      }
      
      M Offline
      M Offline
      mpergand
      wrote on last edited by
      #9

      @BushyAxis793 said in How can I add custom widget to QListView?:

      QRect boundRect = QRect(0,00,275,70);

      You must set the origin with option.rect.
      Look at the Y position : qDebug()<<option.rect.y();

      see an example Here

      B 1 Reply Last reply
      3
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #10

        Beside what @mpergand pointed, are you still using one widget per row ? This is bad design. The proper use of the delegate means you can drop that widget completely.

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

        B 1 Reply Last reply
        1
        • M mpergand

          @BushyAxis793 said in How can I add custom widget to QListView?:

          QRect boundRect = QRect(0,00,275,70);

          You must set the origin with option.rect.
          Look at the Y position : qDebug()<<option.rect.y();

          see an example Here

          B Offline
          B Offline
          BushyAxis793
          wrote on last edited by
          #11

          @mpergand I think I don't understand. I change my origin for :

          QRect boundRect = op.rect;
          

          Now I have the same issue but without border.

          89be88e1-21b0-44a5-83e5-2b08f06645a6-image.png

          1 Reply Last reply
          0
          • SGaistS SGaist

            Beside what @mpergand pointed, are you still using one widget per row ? This is bad design. The proper use of the delegate means you can drop that widget completely.

            B Offline
            B Offline
            BushyAxis793
            wrote on last edited by
            #12

            @SGaist To be honest, I ultimately wanted to use QListWidget, but it doesn't have all the features. And I've been struggling with QListView + Model + Delegate for a few weeks now.

            M 1 Reply Last reply
            0
            • B BushyAxis793

              @SGaist To be honest, I ultimately wanted to use QListWidget, but it doesn't have all the features. And I've been struggling with QListView + Model + Delegate for a few weeks now.

              M Offline
              M Offline
              mpergand
              wrote on last edited by mpergand
              #13

              @BushyAxis793

              I think you need to implement sizeHint() as well.

              As @SGaist noted, your code is confusing :)

              Can you post a skech of what you want to do, is it a single list of text cells ?

              1 Reply Last reply
              0
              • B Offline
                B Offline
                BushyAxis793
                wrote on last edited by
                #14

                Let me describe as simply as I can. I have added a QListWidget in the main window of my program. I created a new class called OperationWidget, which inherits from QWidget. It has all the methods and variables it needs. In an additional QDialog window, I set the parameters of the OperationWidget object and then add it to QListWidget. I can add and remove items from QListWidget, but I cannot change the position of the items. So I have to use QListView + OperationWidgetModel + OperationWidgetDelegate. I have never worked with models and delegates, but I know there is no other way. I want the whole thing to look like the QListWidget.

                OperationWidget.h

                #ifndef OPERATIONWIDGET_H
                #define OPERATIONWIDGET_H
                
                #include <QWidget>
                
                namespace Ui {
                class OperationWidget;
                }
                
                class OperationWidget : public QWidget
                {
                    Q_OBJECT
                
                public:
                    explicit OperationWidget(QWidget *parent = nullptr);
                    ~OperationWidget();
                
                    void SetOperationName(const QString&);
                    QString GetOperationName()const;
                
                    void SetWorkplaceName(const QString&);
                    QString GetWorkplaceName()const;
                
                    void SetToolQuantity(const int&);
                    int GetToolsQuantity()const;
                
                    void SetOperationTime(const double&);
                    double GetOperationTime() const;
                
                    void SetOperationDescription(const QString&);
                    QString GetOperationDescription()const;
                
                    void SetPreparationAndCompletionTime(const int&);
                    int GetPreparationAndCompletionTime()const;
                
                    void SetWorkplaceNumber(const QString&);
                    QString GetWorkplaceNumber()const;
                
                    void SetWorkplaceCost(const int&);
                    int GetWorkplaceCost()const;
                
                    void SetUnitTime(const int&);
                    int GetUnitTime()const;
                
                    void LoadToolTip();
                
                private:
                    Ui::OperationWidget *ui;
                    QString operationName;
                    QString workplaceName;
                    int toolsQuantity;
                    double operationTime;
                    QString operationDescription;
                    int preparationAndCompletionTime;
                    QString workplaceNumber;
                    int workplaceCost;
                    int unitTime;
                
                };
                
                #endif // OPERATIONWIDGET_H
                
                

                OperationWidget.cpp

                #include "operationwidget.h"
                #include "ui_operationwidget.h"
                #include <QFrame>
                
                OperationWidget::OperationWidget(QWidget *parent) :
                    QWidget(parent),
                    ui(new Ui::OperationWidget)
                {
                    ui->setupUi(this);
                
                
                }
                
                OperationWidget::~OperationWidget()
                {
                    delete ui;
                }
                
                void OperationWidget::SetOperationName(const QString &name)
                {
                    operationName = name;
                    ui->operationNameLabel->setText(name);
                }
                
                QString OperationWidget::GetOperationName() const
                {
                    return operationName;
                }
                
                void OperationWidget::SetWorkplaceName(const QString &name)
                {
                    workplaceName = name;
                }
                
                QString OperationWidget::GetWorkplaceName() const
                {
                    return workplaceName;
                }
                
                void OperationWidget::SetToolQuantity(const int &tools)
                {
                    toolsQuantity = tools;
                    ui->toolsQuantityLabel->setText(QString::number(tools)+ " "+"[szt.]");
                }
                
                int OperationWidget::GetToolsQuantity() const
                {
                    return toolsQuantity;
                }
                
                void OperationWidget::SetOperationTime(const double &time)
                {
                    operationTime = time;
                    ui->timeOperationLabel->setText(QString::number(GetOperationTime())+ " "+ "[min.]");
                }
                
                double OperationWidget::GetOperationTime() const
                {
                    return operationTime;
                }
                
                void OperationWidget::SetOperationDescription(const QString &description)
                {
                    operationDescription = description;
                }
                
                QString OperationWidget::GetOperationDescription() const
                {
                    return operationDescription;
                }
                
                void OperationWidget::SetPreparationAndCompletionTime(const int &tpz)
                {
                    preparationAndCompletionTime = tpz;
                }
                
                int OperationWidget::GetPreparationAndCompletionTime() const
                {
                    return preparationAndCompletionTime;
                }
                
                void OperationWidget::SetWorkplaceNumber(const QString &number)
                {
                    workplaceNumber = number;
                }
                
                QString OperationWidget::GetWorkplaceNumber() const
                {
                    return workplaceNumber;
                }
                
                void OperationWidget::SetWorkplaceCost(const int &cost)
                {
                    workplaceCost = cost;
                }
                
                int OperationWidget::GetWorkplaceCost() const
                {
                    return workplaceCost;
                }
                
                void OperationWidget::SetUnitTime(const int &unitT)
                {
                    unitTime = unitT;
                }
                
                int OperationWidget::GetUnitTime() const
                {
                    return unitTime;
                }
                
                void OperationWidget::LoadToolTip()
                {
                    this->setToolTip("Nazwa stanowiska: "+GetWorkplaceName()+"\n"+
                                     "Nazwa operacji: "+GetOperationName()+ "\n"+
                                     "Numer stanowiska: "+GetWorkplaceNumber()+"\n"+
                                     "Koszt stanowiska: "+QString::number(GetWorkplaceCost())+ " [zł]"+"\n"+
                                     "Czas przygotowawczy: "+QString::number(GetPreparationAndCompletionTime())+" [min.]"+"\n"+
                                     "Czas jednostkowy: "+QString::number(GetUnitTime())+" [min.]"+"\n"+
                                     "Ilość narzędzi: "+QString::number(GetToolsQuantity())+"\n"+
                                     "Czas operacji: "+QString::number(GetOperationTime())+" [min.]"+"\n"+
                                     "Opis operacji: "+GetOperationDescription());
                }
                
                

                QListWidget in mainwindow:

                cab0e9cd-6220-4085-8c3d-7cab8c607321-image.png

                Put simply. I want to add my own widget to the QListView.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #15

                  As written in the documentation and here as well: setCellWidget should only be used to show some static content not as a replacement of a properly implemented delegate.

                  There's no need for that widget of yours unless it's an editor.

                  You really should take the time to build a proper model to store your data. It will be a table of some sort. Which you can use with a QListView.

                  Basically, your delegate will have to pull the data from the model when drawing. You will essentially have to position the text properly. There really isn't more to it than that.

                  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
                  1
                  • B BushyAxis793 referenced this topic on
                  • B Offline
                    B Offline
                    BushyAxis793
                    wrote on last edited by
                    #16

                    I found the solution. The problem was in paint(). Now it looks much better

                    78c8e6f5-99f5-4984-90f9-3677c9d8a826-image.png

                    Thanks everyone for help!

                    Unfortunatelly, I found another issue. In slot when I add my widget to list:

                    void QueriesCreator::ReceiveOperationData(QString workplaceName, QString operationName, int tools, double time, QString description,int tpz, QString number, int cost, int unitT)
                    {
                    
                        OperationWidget* operationWidget = new OperationWidget(new QWidget);
                    
                        operationWidget->SetWorkplaceName(workplaceName);
                        operationWidget->SetOperationName(operationName);
                        operationWidget->SetToolQuantity(tools);
                        operationWidget->SetOperationTime(time);
                        operationWidget->SetOperationDescription(description);
                        operationWidget->SetPreparationAndCompletionTime(tpz);
                        operationWidget->SetWorkplaceNumber(number);
                        operationWidget->SetWorkplaceCost(cost);
                        operationWidget->SetUnitTime(unitT);
                        operationWidget->LoadToolTip();
                    
                        model.AddItem(operationWidget);
                    }
                    

                    As you can see I call LoadToolTip() method:

                    void OperationWidget::LoadToolTip()
                    {
                        this->setToolTip("Nazwa stanowiska: "+GetWorkplaceName()+"\n"+
                                         "Nazwa operacji: "+GetOperationName()+ "\n"+
                                         "Numer stanowiska: "+GetWorkplaceNumber()+"\n"+
                                         "Koszt stanowiska: "+QString::number(GetWorkplaceCost())+ " [zł]"+"\n"+
                                         "Czas przygotowawczy: "+QString::number(GetPreparationAndCompletionTime())+" [min.]"+"\n"+
                                         "Czas jednostkowy: "+QString::number(GetUnitTime())+" [min.]"+"\n"+
                                         "Ilość narzędzi: "+QString::number(GetToolsQuantity())+"\n"+
                                         "Czas operacji: "+QString::number(GetOperationTime())+" [min.]"+"\n"+
                                         "Opis operacji: "+GetOperationDescription());
                    }
                    

                    But I can see any tooltip when I move cursor over widget. How can I enable it? Any ideas?

                    SGaistS 1 Reply Last reply
                    0
                    • B BushyAxis793 has marked this topic as solved on
                    • B BushyAxis793

                      I found the solution. The problem was in paint(). Now it looks much better

                      78c8e6f5-99f5-4984-90f9-3677c9d8a826-image.png

                      Thanks everyone for help!

                      Unfortunatelly, I found another issue. In slot when I add my widget to list:

                      void QueriesCreator::ReceiveOperationData(QString workplaceName, QString operationName, int tools, double time, QString description,int tpz, QString number, int cost, int unitT)
                      {
                      
                          OperationWidget* operationWidget = new OperationWidget(new QWidget);
                      
                          operationWidget->SetWorkplaceName(workplaceName);
                          operationWidget->SetOperationName(operationName);
                          operationWidget->SetToolQuantity(tools);
                          operationWidget->SetOperationTime(time);
                          operationWidget->SetOperationDescription(description);
                          operationWidget->SetPreparationAndCompletionTime(tpz);
                          operationWidget->SetWorkplaceNumber(number);
                          operationWidget->SetWorkplaceCost(cost);
                          operationWidget->SetUnitTime(unitT);
                          operationWidget->LoadToolTip();
                      
                          model.AddItem(operationWidget);
                      }
                      

                      As you can see I call LoadToolTip() method:

                      void OperationWidget::LoadToolTip()
                      {
                          this->setToolTip("Nazwa stanowiska: "+GetWorkplaceName()+"\n"+
                                           "Nazwa operacji: "+GetOperationName()+ "\n"+
                                           "Numer stanowiska: "+GetWorkplaceNumber()+"\n"+
                                           "Koszt stanowiska: "+QString::number(GetWorkplaceCost())+ " [zł]"+"\n"+
                                           "Czas przygotowawczy: "+QString::number(GetPreparationAndCompletionTime())+" [min.]"+"\n"+
                                           "Czas jednostkowy: "+QString::number(GetUnitTime())+" [min.]"+"\n"+
                                           "Ilość narzędzi: "+QString::number(GetToolsQuantity())+"\n"+
                                           "Czas operacji: "+QString::number(GetOperationTime())+" [min.]"+"\n"+
                                           "Opis operacji: "+GetOperationDescription());
                      }
                      

                      But I can see any tooltip when I move cursor over widget. How can I enable it? Any ideas?

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #17

                      A delegate does not handle tooltips, you should return them through the model for the Qt::ToolTipRole role.

                      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
                      1

                      • Login

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