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. QListWidget doesn't show properly custom QWidget

QListWidget doesn't show properly custom QWidget

Scheduled Pinned Locked Moved Solved General and Desktop
custom widgetlist
16 Posts 2 Posters 6.2k 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.
  • I Offline
    I Offline
    Ioseph12
    wrote on 8 Jun 2017, 12:49 last edited by Ioseph12 6 Aug 2017, 12:50
    #3

    I'll have only FilterWindows and one QCalendarWidget

    0_1496926167564_final.jpg

    1 Reply Last reply
    0
    • V Offline
      V Offline
      VRonin
      wrote on 8 Jun 2017, 12:51 last edited by
      #4

      Then move the QCalendarWidget outside the QListWidget, subclass QStyledItemDelegate to make it use a FilterWindows and use QListWidget::setItemDelegate to apply it

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      I 1 Reply Last reply 8 Jun 2017, 13:14
      2
      • V VRonin
        8 Jun 2017, 12:51

        Then move the QCalendarWidget outside the QListWidget, subclass QStyledItemDelegate to make it use a FilterWindows and use QListWidget::setItemDelegate to apply it

        I Offline
        I Offline
        Ioseph12
        wrote on 8 Jun 2017, 13:14 last edited by
        #5

        @VRonin

        So the right way to do this would be as there?

        filterwindow.h

        #ifndef FILTERWINDOW_H
        #define FILTERWINDOW_H
        
        #include <QtCore/QVariant>
        #include <QtWidgets/QAction>
        #include <QtWidgets/QApplication>
        #include <QtWidgets/QButtonGroup>
        #include <QtWidgets/QCheckBox>
        #include <QtWidgets/QFrame>
        #include <QtWidgets/QHeaderView>
        #include <QtWidgets/QPushButton>
        #include <QtWidgets/QTableWidget>
        #include <QtWidgets/QWidget>
        #include <QtWidgets/qstyleditemdelegate.h>	
        
        class FilterWindow : public QStyledItemDelegate
        {
            Q_OBJECT
        
        public:
            FilterWindow(QWidget*);
        	FilterWindow(std::string, std::vector<std::string>);
        
        	void setList(std::vector<std::string>);
        .....
        }
        #endif
        

        main.cpp

        	QListWidgetItem * myItem = new QListWidgetItem();
        	myItem->setSizeHint(QSize(281, 89));
        	FilterWindow* fwn_sn = new FilterWindow( "Serial Number", cfg.serialNumber);
        	
        	ui.LoadConfTable->setItemDelegate(fwn_sn);
        	ui.LoadConfTable->addItem(myItem);	
        

        I can't display the Widget properly yet

        1 Reply Last reply
        0
        • V Offline
          V Offline
          VRonin
          wrote on 8 Jun 2017, 13:28 last edited by
          #6

          That's not how it works: http://doc.qt.io/qt-5/qstyleditemdelegate.html#subclassing-qstyleditemdelegate

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          I 2 Replies Last reply 8 Jun 2017, 13:55
          3
          • V VRonin
            8 Jun 2017, 13:28

            That's not how it works: http://doc.qt.io/qt-5/qstyleditemdelegate.html#subclassing-qstyleditemdelegate

            I Offline
            I Offline
            Ioseph12
            wrote on 8 Jun 2017, 13:55 last edited by
            #7

            @VRonin

            Right, I will try it. Thank's a lot!

            1 Reply Last reply
            1
            • V VRonin
              8 Jun 2017, 13:28

              That's not how it works: http://doc.qt.io/qt-5/qstyleditemdelegate.html#subclassing-qstyleditemdelegate

              I Offline
              I Offline
              Ioseph12
              wrote on 9 Jun 2017, 08:42 last edited by
              #8

              @VRonin

              Hi VRonin,

              First of all, thanks for your help. The document you linked has been very usefull. I have been trying to subclass the Qstyle delegate as it states there, but I'm still having some problems to display the custom widget. I think that the problem is on how I reimplemented the paint function, because, to be honest, It was some kind of empirical try (my bad). So here is the code:

              FilterWindow.h (custom class and delegate inside)

              #ifndef FILTERWINDOW_H
              #define FILTERWINDOW_H
              
              #include <QtCore/QVariant>
              #include <QtWidgets/QAction>
              #include <QtWidgets/QApplication>
              #include <QtWidgets/QButtonGroup>
              #include <QtWidgets/QCheckBox>
              #include <QtWidgets/QFrame>
              #include <QtWidgets/QHeaderView>
              #include <QtWidgets/QPushButton>
              #include <QtWidgets/QTableWidget>
              #include <QtWidgets/qstyleditemdelegate.h>	
              #include <QtGui/qpainter.h>
              #include <QtWidgets>
              
              class FilterWindow : public QWidget
              {
                  Q_OBJECT
              
              public:
              	FilterWindow(QWidget *parent = 0);
              	FilterWindow(QWidget *, std::string, std::vector<std::string>);
              	FilterWindow(const FilterWindow &);
              
              	void paint(QPainter *painter, const QRect &rect, const QPalette &palette) const;
              	QSize sizeHint() const;
              
              	void setList(std::vector<std::string>);
              	void setTittle(std::string tittle);
              
              private slots:
              	void pressArrow();
              	void apply();
              	void reset();
              	void checkMark();
              
              signals:
              	void applyPressed(std::vector<std::string>);
              
              private:
              	void setUi(QWidget *parent);
              	void setUi(QWidget *parent, std::string tittle);
              
                  QFrame *Frame;
                  QCheckBox *checkBox;
                  QPushButton *ArrowBtn;
                  QTableWidget *Table;
                  QPushButton *ResetBtn;
                  QPushButton *AplyBtn;
              
              	bool open;
              	std::vector<std::string> list;
              	std::string tittle;
              };
              
              class customQStyledItemDelegate : public QStyledItemDelegate
              {
              	Q_OBJECT
              
              public: 
              	customQStyledItemDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {}
              
              	void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
              	QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
              };
              
              Q_DECLARE_METATYPE(FilterWindow)
              
              #endif //FILTERWINDOW_H
              

              FilterWindow.cpp

              
              FilterWindow::FilterWindow(QWidget *parent)
              {
              	open = false;
              	list.clear();
              	setUi(parent);
              	Frame->setFixedSize(281, 35);
              	ArrowBtn->setEnabled(false);
              
              	connect(ArrowBtn, SIGNAL(released()), this, SLOT(pressArrow()));
              	connect(ResetBtn, SIGNAL(released()), this, SLOT(reset()));
              	connect(AplyBtn, SIGNAL(released()), this, SLOT(apply()));
              	connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(checkMark()));
              }
              
              FilterWindow::FilterWindow(QWidget *parent, std::string tittle, std::vector<std::string> _list)
              {
              	setUi(parent, tittle);
              	setList(_list);
              	this->tittle = tittle;
              		
              	Frame->setFixedSize(281, 35);
              	open = false;
              	ArrowBtn->setEnabled(false);
              
              	connect(ArrowBtn, SIGNAL(released()), this, SLOT(pressArrow()));
              	connect(ResetBtn, SIGNAL(released()), this, SLOT(reset()));
              	connect(AplyBtn, SIGNAL(released()), this, SLOT(apply()));
              	connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(checkMark()));
              }
              
              FilterWindow::FilterWindow(const FilterWindow &input)
              {
              	setUi(input.parentWidget(), input.tittle);
              	
              	list.clear();
              	list = input.list;
              	this->tittle = input.tittle;
              
              	Frame->setFixedSize(281, 35);
              	open = false;
              	ArrowBtn->setEnabled(false);
              
              }
              
              void FilterWindow::setList(std::vector<std::string> _List)
              {
              	list.clear();
              	Table->clear();
              	list = _List;
              
              	Table->verticalHeader()->setHidden(true);
              	Table->horizontalHeader()->setHidden(true);
              
              	Table->setRowCount(list.size());
              	Table->setColumnCount(2);
              	Table->setShowGrid(false);
              	Table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
              
              	Qt::ItemFlags eFlags;
              	eFlags = Qt::ItemIsEnabled;
              	eFlags &= ~Qt::ItemIsEditable;;
              
              	for (int i = 0; i < list.size(); i++)
              	{
              		Table->setCellWidget(i, 0, new QCheckBox());
              		((QCheckBox*)(Table->cellWidget(i, 0)))->setChecked(true);
              		Table->setItem(i, 1, new QTableWidgetItem(list.at(i).c_str()));
              		Table->item(i, 1)->setFlags(eFlags);
              	}
              
              	Table->resizeColumnsToContents();
              	Table->resizeRowsToContents();
              	Table->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
              	Table->setFocusPolicy(Qt::FocusPolicy::NoFocus);
              }
              
              QSize FilterWindow::sizeHint() const
              {
              	return QSize(281, 35);
              }
              
              void FilterWindow::paint(QPainter *painter, const QRect &rect, const QPalette &palette) const
              {
              	Frame->repaint(rect);
              	ArrowBtn->repaint(rect);
              	checkBox->repaint(rect);
              	Table->repaint(rect);
              	ResetBtn->repaint(rect);
              	AplyBtn->repaint(rect);
              }
              
              //PRIVATE FUNCTIONS
              void FilterWindow::setUi(QWidget *parent)
              {
                  Frame = new QFrame(parent);
                  Frame->setObjectName(QStringLiteral("Frame"));
              	Frame->setFixedWidth(281);
              	Frame->setFixedHeight(89);
                  Frame->setStyleSheet(QLatin1String("QFrame\n"
              "{\n"
              "	border-style: solid;\n"
              "	border-size: 0px;\n"
              "	border-radius: 4px;\n"
              "	border-color: transparent;\n"
              "}"));
                  Frame->setFrameShape(QFrame::StyledPanel);
                  Frame->setFrameShadow(QFrame::Raised);
                  checkBox = new QCheckBox(Frame);
                  checkBox->setObjectName(QStringLiteral("checkBox"));
                  checkBox->setGeometry(QRect(0, 0, 248, 35));
                  checkBox->setAutoFillBackground(false);
                  checkBox->setStyleSheet(QLatin1String("QCheckBox\n"
              "{\n"
              "	background-color: rgb(128,139,143);\n"
              "	color: white;\n"
              "	border-radius: 4px;\n"
              "	padding-left: 8px;\n"
              "}\n"
              "\n"
              "QCheckBox::indicator:unchecked {\n"
              "    image: url(:/OptiNanoPro/uchk);\n"
              "}\n"
              "\n"
              "\n"
              "QCheckBox::indicator:checked {\n"
              "    image: url(:/OptiNanoPro/chk);\n"
              "}\n"
              ""));
                  checkBox->setChecked(false);
                  ArrowBtn = new QPushButton(Frame);
                  ArrowBtn->setObjectName(QStringLiteral("ArrowBtn"));
                  ArrowBtn->setGeometry(QRect(246, 0, 36, 35));
                  ArrowBtn->setAutoFillBackground(true);
                  QIcon icon;
                  icon.addFile(QStringLiteral(":/OptiNanoPro/DownArrwLd"), QSize(), QIcon::Normal, QIcon::Off);
                  ArrowBtn->setIcon(icon);
                  ArrowBtn->setIconSize(QSize(36, 35));
                  ArrowBtn->setFlat(true);
                  Table = new QTableWidget(Frame);
                  Table->setObjectName(QStringLiteral("Table"));
                  Table->setGeometry(QRect(0, 35, 281, 36));
                  Table->setStyleSheet(QLatin1String("QTableWidget\n"
              "{\n"
              "	background-color: white;\n"
              "	border-radius: 0px;\n"
              "}\n"
              "QCheckBox\n"
              "{\n"
              "	color: white;\n"
              "	border-radius: 4px;\n"
              "	padding-left: 8px;\n"
              "}\n"
              "\n"
              "QCheckBox::indicator:unchecked {\n"
              "    image: url(:/OptiNanoPro/uchk);\n"
              "}\n"
              "\n"
              "\n"
              "QCheckBox::indicator:checked {\n"
              "    image: url(:/OptiNanoPro/chk);\n"
              "}\n"
              "QTableWidgetItem\n"
              "{\n"
              "	color: black;"
              "}\n"));
                  ResetBtn = new QPushButton(Frame);
                  ResetBtn->setObjectName(QStringLiteral("ResetBtn"));
              	ResetBtn->setText(QStringLiteral("Reset"));
                  ResetBtn->setGeometry(QRect(0, 66, 169, 23));
                  ResetBtn->setStyleSheet(QLatin1String("QPushButton\n"
              "{\n"
              "	background-color: white;\n"
              "	border-width: 1px;\n"
              "    border-style: solid;\n"
              "    border-color: rgb(86,86,84);\n"
              "	border-radius: 3px;\n"
              "	color: rgb(86,86,84);\n"
              "}"));
                  AplyBtn = new QPushButton(Frame);
                  AplyBtn->setObjectName(QStringLiteral("AplyBtn"));
              	AplyBtn->setText(QStringLiteral("Apply"));
                  AplyBtn->setGeometry(QRect(169, 66, 111, 23));
                  AplyBtn->setStyleSheet(QLatin1String("QPushButton\n"
              "{\n"
              "	background-color: white;\n"
              "	border-width: 1px;\n"
              "    border-style: solid;\n"
              "    border-color: rgb(86,86,84);\n"
              "	border-radius: 3px;\n"
              "	color: rgb(86,86,84);\n"
              "}"));
              }
              
              void FilterWindow::setUi(QWidget *parent,std::string tittle)
              {
              	Frame = new QFrame(parent);
              	Frame->setObjectName(QStringLiteral("Frame"));
              	Frame->setFixedWidth(281);
              	Frame->setFixedHeight(89);
              	Frame->setStyleSheet(QLatin1String("QFrame\n"
              		"{\n"
              		"	border-style: solid;\n"
              		"	border-size: 0px;\n"
              		"	border-radius: 4px;\n"
              		"	border-color: transparent;\n"
              		"}"));
              	Frame->setFrameShape(QFrame::StyledPanel);
              	Frame->setFrameShadow(QFrame::Raised);
              	Frame->setAttribute(Qt::WA_DeleteOnClose);
              	checkBox = new QCheckBox(Frame);
              	checkBox->setText(tittle.c_str());
              	checkBox->setObjectName(QStringLiteral("checkBox"));
              	checkBox->setGeometry(QRect(0, 0, 248, 35));
              	checkBox->setAutoFillBackground(false);
              	checkBox->setStyleSheet(QLatin1String("QCheckBox\n"
              		"{\n"
              		"	background-color: rgb(128,139,143);\n"
              		"	color: white;\n"
              		"	border-radius: 4px;\n"
              		"	padding-left: 8px;\n"
              		"}\n"
              		"\n"
              		"QCheckBox::indicator:unchecked {\n"
              		"    image: url(:/OptiNanoPro/uchk);\n"
              		"}\n"
              		"\n"
              		"\n"
              		"QCheckBox::indicator:checked {\n"
              		"    image: url(:/OptiNanoPro/chk);\n"
              		"}\n"
              		""));
              	checkBox->setChecked(false);
              	ArrowBtn = new QPushButton(Frame);
              	ArrowBtn->setObjectName(QStringLiteral("ArrowBtn"));
              	ArrowBtn->setGeometry(QRect(246, 0, 36, 35));
              	ArrowBtn->setAutoFillBackground(true);
              	QIcon icon;
              	icon.addFile(QStringLiteral(":/OptiNanoPro/DownArrwLd"), QSize(), QIcon::Normal, QIcon::Off);
              	ArrowBtn->setIcon(icon);
              	ArrowBtn->setIconSize(QSize(36, 35));
              	ArrowBtn->setFlat(true);
              	Table = new QTableWidget(Frame);
              	Table->setObjectName(QStringLiteral("Table"));
              	Table->setGeometry(QRect(0, 35, 281, 31));
              	Table->setStyleSheet(QLatin1String("QTableWidget\n"
              		"{\n"
              		"	background-color: white;\n"
              		"	border-radius: 0px;\n"
              		"}"));
              	ResetBtn = new QPushButton(Frame);
              	ResetBtn->setObjectName(QStringLiteral("ResetBtn"));
              	ResetBtn->setGeometry(QRect(0, 66, 169, 23));
              	ResetBtn->setStyleSheet(QLatin1String("QPushButton\n"
              		"{\n"
              		"	background-color: white;\n"
              		"	border-width: 1px;\n"
              		"    border-style: solid;\n"
              		"    border-color: rgb(86,86,84);\n"
              		"	border-radius: 3px;\n"
              		"	color: rgb(86,86,84);\n"
              		"}"));
              	AplyBtn = new QPushButton(Frame);
              	AplyBtn->setObjectName(QStringLiteral("AplyBtn"));
              	AplyBtn->setGeometry(QRect(169, 66, 111, 23));
              	AplyBtn->setStyleSheet(QLatin1String("QPushButton\n"
              		"{\n"
              		"	background-color: white;\n"
              		"	border-width: 1px;\n"
              		"    border-style: solid;\n"
              		"    border-color: rgb(86,86,84);\n"
              		"	border-radius: 3px;\n"
              		"	color: rgb(86,86,84);\n"
              		"}"));
              }
              
              //SLOTS
              void FilterWindow::pressArrow()
              {
              	if (open) //It was opened
              	{
              		ArrowBtn->setIcon(QIcon(":/OptiNanoPro/DownArrwLd"));
              		Frame->setFixedSize(281, 35);
              	}
              
              	else //It was closed
              	{
              		ArrowBtn->setIcon(QIcon(":/OptiNanoPro/UpArrwLd"));
              		Frame->setFixedSize(281, 89);
              	}
              
              	open = !open;
              }
              
              void FilterWindow::apply()
              {
              	std::vector<std::string> list_out;
              
              	for (int i = 0; i < Table->rowCount(); i++)
              	{
              		if (((QCheckBox*)(Table->cellWidget(i, 0)))->isChecked())
              		{
              			list_out.push_back(Table->item(i,1)->text().toStdString());
              		}
              	}
              
              	emit applyPressed(list_out);
              }
              
              void FilterWindow::reset()
              {
              	for (int i = 0; i < Table->rowCount(); i++)
              	{
              		((QCheckBox*)(Table->cellWidget(i, 0)))->setChecked(true);
              	}
              }
              
              void FilterWindow::checkMark()
              {
              	if (checkBox->isChecked())
              	{
              		ArrowBtn->setEnabled(true);
              	}
              
              	else
              	{
              		ArrowBtn->setIcon(QIcon(":/OptiNanoPro/DownArrwLd"));
              		Frame->setFixedSize(281, 35);
              		open = false;
              		ArrowBtn->setEnabled(false);
              	}
              }
              
              
              //Delegate
              
              void customQStyledItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
              {
              	if (index.data().canConvert<FilterWindow>()) 
              	{
              		FilterWindow filt = qvariant_cast<FilterWindow>(index.data());
              
              		filt.paint(painter, option.rect, option.palette);
              	}
              
              	else 
              	{
              		QStyledItemDelegate::paint(painter, option, index);
              	}
              }	
              
              QSize customQStyledItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
              

              And that's what I'm doing:

              ui.LoadConfTable->setItemDelegate(new customQStyledItemDelegate); //Add delegate
              QListWidgetItem * myItem = new QListWidgetItem();
              wndw = new FilterWindow(ui.LoadFrame, "Serial Number", cfg.serialNumber); //Create a FilterWindow
              myItem->setSizeHint(QSize(281, 89));
              myItem->setData(0, QVariant::fromValue(*wndw)); //The tutorial settled that it should be casted to QVariant to save it in an item
              ui.LoadConfTable->addItem(myItem); //And just after this it should be painted?
              

              This is how it looks like:

              0_1496997768940_Sin título.jpg

              1 Reply Last reply
              0
              • V Offline
                V Offline
                VRonin
                wrote on 9 Jun 2017, 08:49 last edited by VRonin 6 Sept 2017, 08:58
                #9

                Not quite there yet, the widget is not the data. The data should be what's in the widget.

                take a look at AQP page 193. They use a QLabel as a delegate but its basically the same in your case (just as disclaimer: I don't like that example as it's inefficient, you should paint directly the delegate, not use a separate QWidget but it works and it's a good enough start)

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                I 1 Reply Last reply 13 Jun 2017, 10:10
                2
                • V VRonin
                  9 Jun 2017, 08:49

                  Not quite there yet, the widget is not the data. The data should be what's in the widget.

                  take a look at AQP page 193. They use a QLabel as a delegate but its basically the same in your case (just as disclaimer: I don't like that example as it's inefficient, you should paint directly the delegate, not use a separate QWidget but it works and it's a good enough start)

                  I Offline
                  I Offline
                  Ioseph12
                  wrote on 13 Jun 2017, 10:10 last edited by
                  #10

                  @VRonin

                  Good morning,

                  Thank you so much for your advice. After getting stucked in some points and trying to understand the QStyledItemDelegate overrided functions I managed to draw perfectly the widgets inside a QTableWidget . So after achieve that, I started to implement the item edition part getting some odd bugs. Here is the curent code:

                  FilterWindow.h

                  #ifndef FILTERWINDOW_H
                  #define FILTERWINDOW_H
                  
                  #include <QtWidgets/QStyledItemDelegate>
                  
                  #include <QtWidgets/QButtonGroup>
                  #include <QtWidgets/QCheckBox>
                  #include <QtWidgets/QFrame>
                  #include <QtWidgets/QHeaderView>	
                  #include <QtWidgets/QPushButton>
                  #include <QtWidgets/QTableWidget>
                  #include <QtWidgets/QTableView>
                  #include <QWidget>
                  #include <QPainter>
                  
                  class FilterWindow : public QWidget
                  {
                  	Q_OBJECT
                  
                  public:
                  	explicit FilterWindow(QWidget* parent = NULL);
                  	FilterWindow(QWidget* parent, std::string);
                  	FilterWindow(FilterWindow&);
                  	~FilterWindow();
                  
                  	void setUi(QWidget* parent, std::string tittle);
                  	void press();
                  	void setData(std::string, std::vector<std::string> = std::vector<std::string>(), int rw = -1);
                  	
                  	//Overrided
                  	QSize size() const;
                  	void render(QPaintDevice * target, const QPoint & targetOffset = QPoint(), const QRegion & sourceRegion = QRegion(), RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
                  
                  signals:
                  	void btnprsd(int row, bool prsd);
                  
                  public slots:
                  	void pressedSlot();
                  
                  private:
                  	QFrame* Frame;
                  	QCheckBox* checkBox;
                  	QPushButton* ArrowBtn;
                  	QTableWidget* Table;
                  	QPushButton* ResetBtn;
                  	QPushButton* AplyBtn;
                  	std::vector<std::string> list;
                  
                  	int rw;
                  	bool pressed;
                  };
                  
                  class FilterWindowDelegate : public QStyledItemDelegate
                  {
                      Q_OBJECT
                  
                  public:	
                  	explicit FilterWindowDelegate(QObject* parent);
                  	~FilterWindowDelegate();
                  
                  	void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;	
                  	QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem &option, const QModelIndex&) const;
                  	void updateEditorGeometry(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const;
                  	void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
                  	void setEditorData(QWidget * editor, const QModelIndex & index) const;
                  
                  	void insertElement(std::string tittle, std::vector<std::string> = std::vector<std::string>());
                  
                  public slots:
                  	void btn_pressed(int row, bool prsd);
                  
                  private:
                  	//Vars
                  	std::vector<FilterWindow*> FrmWindows;
                  
                  	//Others
                  	QTableWidget* prnt;
                  };
                  
                  #endif //FILTERWINDOW_H
                  
                  

                  FilterWindow.cpp

                  #include <filterwindow.h>
                  
                  ///Filter window
                  //Public Functions
                  
                  FilterWindow::FilterWindow(QWidget* parent) : QWidget(parent)
                  {
                  	setUi(parent, "");
                  	pressed = false;
                  	press();
                  
                  	connect(ArrowBtn, SIGNAL(pressed()), this, SLOT(pressedSlot()));
                  }
                  
                  FilterWindow::FilterWindow(QWidget* parent, std::string ttle)
                  {
                  	setUi(parent, ttle);
                  	pressed = false;
                  	press();
                  
                  	connect(ArrowBtn, SIGNAL(pressed()), this, SLOT(pressedSlot()));
                  }
                  
                  FilterWindow::FilterWindow(FilterWindow& in)
                  {
                  	setUi(in.Frame->parentWidget(), in.checkBox->text().toStdString());
                  	pressed = false;
                  	press();
                  	rw = in.rw;
                  
                  	connect(ArrowBtn, SIGNAL(pressed()), this, SLOT(pressedSlot()));
                  }
                  
                  FilterWindow::~FilterWindow()
                  {
                  	delete Frame;
                  	delete checkBox;
                  	delete ArrowBtn;
                  	delete Table;
                  	delete ResetBtn;
                  	delete AplyBtn;
                  }
                  
                  void FilterWindow::setUi(QWidget* parent, std::string tittle)
                  {
                  	Frame = new QFrame(parent);
                  	Frame->setObjectName(QStringLiteral("Frame"));
                  	Frame->setFixedWidth(281);
                  	Frame->setFixedHeight(89);
                  	Frame->setStyleSheet(QLatin1String("QFrame\n"
                  		"{\n"
                  		"	border-style: solid;\n"
                  		"	border-size: 0px;\n"
                  		"	border-radius: 4px;\n"
                  		"	border-color: transparent;\n"
                  		"}"));
                  	Frame->setFrameShape(QFrame::StyledPanel);
                  	Frame->setFrameShadow(QFrame::Raised);
                  	Frame->setAttribute(Qt::WA_DeleteOnClose);
                  	checkBox = new QCheckBox(Frame);
                  	checkBox->setText(tittle.c_str());
                  	checkBox->setObjectName(QStringLiteral("checkBox"));
                  	checkBox->setGeometry(QRect(0, 0, 248, 35));
                  	checkBox->setAutoFillBackground(false);
                  	checkBox->setStyleSheet(QLatin1String("QCheckBox\n"
                  		"{\n"
                  		"	background-color: rgb(128,139,143);\n"
                  		"	color: white;\n"
                  		"	border-radius: 4px;\n"
                  		"	padding-left: 8px;\n"
                  		"}\n"
                  		"\n"
                  		"QCheckBox::indicator:unchecked {\n"
                  		"    image: url(:/OptiNanoPro/uchk);\n"
                  		"}\n"
                  		"\n"
                  		"\n"
                  		"QCheckBox::indicator:checked {\n"
                  		"    image: url(:/OptiNanoPro/chk);\n"
                  		"}\n"
                  		""));
                  	checkBox->setChecked(false);
                  	ArrowBtn = new QPushButton(Frame);
                  	ArrowBtn->setObjectName(QStringLiteral("ArrowBtn"));
                  	ArrowBtn->setGeometry(QRect(246, 0, 36, 35));
                  	ArrowBtn->setAutoFillBackground(true);
                  	QIcon icon;
                  	icon.addFile(QStringLiteral(":/OptiNanoPro/DownArrwLd"), QSize(), QIcon::Normal, QIcon::Off);
                  	ArrowBtn->setIcon(icon);
                  	ArrowBtn->setIconSize(QSize(36, 35));
                  	ArrowBtn->setFlat(true);
                  	Table = new QTableWidget(Frame);
                  	Table->setObjectName(QStringLiteral("Table"));
                  	Table->setGeometry(QRect(0, 35, 281, 31));
                  	Table->setStyleSheet(QLatin1String("QTableWidget\n"
                  		"{\n"
                  		"	background-color: white;\n"
                  		"	border-radius: 0px;\n"
                  		"}"));
                  	ResetBtn = new QPushButton(Frame);
                  	ResetBtn->setText("Reset");
                  	ResetBtn->setObjectName(QStringLiteral("ResetBtn"));
                  	ResetBtn->setGeometry(QRect(0, 66, 169, 23));
                  	ResetBtn->setStyleSheet(QLatin1String("QPushButton\n"
                  		"{\n"
                  		"	background-color: white;\n"
                  		"	border-width: 1px;\n"
                  		"    border-style: solid;\n"
                  		"    border-color: rgb(86,86,84);\n"
                  		"	border-radius: 3px;\n"
                  		"	color: rgb(86,86,84);\n"
                  		"}"));
                  	AplyBtn = new QPushButton(Frame);
                  	AplyBtn->setText("Apply");
                  	AplyBtn->setObjectName(QStringLiteral("AplyBtn"));
                  	AplyBtn->setGeometry(QRect(169, 66, 111, 23));
                  	AplyBtn->setStyleSheet(QLatin1String("QPushButton\n"
                  		"{\n"
                  		"	background-color: white;\n"
                  		"	border-width: 1px;\n"
                  		"    border-style: solid;\n"
                  		"    border-color: rgb(86,86,84);\n"
                  		"	border-radius: 3px;\n"
                  		"	color: rgb(86,86,84);\n"
                  		"}"));
                  }
                  
                  void FilterWindow::press()
                  {
                  	if (pressed)
                  	{
                  		Frame->setFixedHeight(89);
                  		ArrowBtn->setIcon(QIcon(":/OptiNanoPro/UpArrwLd"));
                  	}
                  
                  	else
                  	{
                  		Frame->setFixedHeight(35);
                  		ArrowBtn->setIcon(QIcon(":/OptiNanoPro/DownArrwLd"));
                  	}
                  }
                  
                  void FilterWindow::setData(std::string name, std::vector<std::string> _list, int _rw)
                  {
                  	if (!name.empty())
                  	{
                  		checkBox->setText(name.c_str());
                  	}
                  
                  	if (!list.empty())
                  	{
                  		list = _list;
                  	}
                  
                  	if (rw != -1)
                  	{
                  		rw = _rw;
                  	}
                  }
                  
                  QSize FilterWindow::size() const
                  {
                  	return Frame->size();
                  }
                  
                  void FilterWindow::render(QPaintDevice * target, const QPoint & targetOffset, const QRegion & sourceRegion, RenderFlags renderFlags)
                  {
                  	Frame->render(target);
                  }
                  
                  //Slots
                  void FilterWindow::pressedSlot()
                  {
                  	pressed = !pressed;
                  	press();
                  
                  	emit(btnprsd(rw,pressed));
                  }
                  
                  ///Filter Window Delegate
                  //PUBLIC FUNCTIONS
                  FilterWindowDelegate::FilterWindowDelegate(QObject* parent) : QStyledItemDelegate(parent)
                  {
                  	prnt = qobject_cast<QTableWidget*>(parent);
                  	FrmWindows.clear();
                  }
                  
                  FilterWindowDelegate::~FilterWindowDelegate()
                  {
                  	FrmWindows.clear();
                  }
                  
                  void FilterWindowDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                  {
                  	QPixmap pixmap(FrmWindows.at(index.row())->size());
                  	FrmWindows.at(index.row())->render(&pixmap);
                  		
                  	painter->drawPixmap(option.rect.x(),option.rect.y(), pixmap);
                  	prnt->setRowHeight(index.row(), FrmWindows.at(index.row())->size().height() + 1);
                  }
                  
                  ////AQUI EXTRAER EL QWIDGET DEL INDICE Y DEVOLVERLO PARA QUE PERMITA ACTUALIZAR LOS VALORES. TERMINAR MAÑANA!!!!!
                  QWidget* FilterWindowDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem &option, const QModelIndex&idx) const
                  {
                  	return new FilterWindow(*FrmWindows.at(idx.row()));
                  }
                  
                  void FilterWindowDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& idx) const
                  {
                  	editor->setGeometry(option.rect);
                  }
                  
                  void FilterWindowDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
                  {
                  }
                  
                  void FilterWindowDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
                  {
                  }
                  
                  void FilterWindowDelegate::insertElement(std::string tittle, std::vector<std::string> _list)
                  {
                  	//Internal part
                  	FrmWindows.push_back(new FilterWindow(prnt, tittle));
                  	FrmWindows.at(FrmWindows.size() - 1)->setData(tittle, _list, FrmWindows.size() - 1);
                  	
                  	//Conect widget signal with delegate to resize rows
                  	connect(FrmWindows.at(FrmWindows.size() - 1), SIGNAL(btnprsd(int, bool)), this, SLOT(btn_pressed(int, bool)));
                  
                  	//External part
                  	prnt->insertRow(FrmWindows.size()-1);
                  }
                  
                  //Slots
                  void FilterWindowDelegate::btn_pressed(int row, bool prsd)
                  {
                  	if (prsd)
                  	{
                  		prnt->setRowHeight(row, 90);
                  	}
                  
                  	else
                  	{
                  		prnt->setRowHeight(row, 36);
                  	}
                  }
                  

                  And that's is how I call it:

                  fltr = new FilterWindowDelegate(ui.LoadConfTable);
                  	ui.LoadConfTable->setItemDelegate(fltr);
                  	ui.LoadConfTable->setRowCount(0);
                  	ui.LoadConfTable->setColumnCount(1);
                  	ui.LoadConfTable->verticalHeader()->setHidden(true);
                  	ui.LoadConfTable->horizontalHeader()->setHidden(true);
                  	ui.LoadConfTable->setColumnWidth(0, 282);
                  	ui.LoadConfTable->setShowGrid(false);
                  	ui.LoadConfTable->setRowHeight(0, 36);
                  
                  	fltr->insertElement("HOLA");
                  	fltr->insertElement("ADIOS");
                  

                  So with all this code, this is how i get it

                  0_1497348420819_adadadasd.jpg

                  By some reason, it selects the last item and starts an editor placed in a wrong position. (I'm aware that is not an optimal code)

                  Once more, thanks for your help. This book has been a good resource to improve my skills,

                  José

                  1 Reply Last reply
                  0
                  • V Offline
                    V Offline
                    VRonin
                    wrote on 13 Jun 2017, 10:18 last edited by
                    #11

                    I would have many comments on the implementation but for now let's leave them in the drawer.

                    return new FilterWindow(*FrmWindows.at(idx.row())); should become return FrmWindows.at(idx.row());.
                    Don't return a copy (that you can't do anyway) but the widget itself

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    I 2 Replies Last reply 13 Jun 2017, 10:28
                    1
                    • V VRonin
                      13 Jun 2017, 10:18

                      I would have many comments on the implementation but for now let's leave them in the drawer.

                      return new FilterWindow(*FrmWindows.at(idx.row())); should become return FrmWindows.at(idx.row());.
                      Don't return a copy (that you can't do anyway) but the widget itself

                      I Offline
                      I Offline
                      Ioseph12
                      wrote on 13 Jun 2017, 10:28 last edited by
                      #12

                      @VRonin

                      It's still having the same bug. The upper windget is the editor of the second element in the table, which it appears by default even whitout selecting that element and appears at this place (The right place would be the second row of the table and whitout that skew if it would have been called)

                      1 Reply Last reply
                      0
                      • V Offline
                        V Offline
                        VRonin
                        wrote on 13 Jun 2017, 10:33 last edited by
                        #13

                        Image uploads in this forum are broken at the moment (update should come out in the near future) so it's difficult to understand. could you upload on postimg?

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        I 1 Reply Last reply 13 Jun 2017, 10:35
                        0
                        • V VRonin
                          13 Jun 2017, 10:33

                          Image uploads in this forum are broken at the moment (update should come out in the near future) so it's difficult to understand. could you upload on postimg?

                          I Offline
                          I Offline
                          Ioseph12
                          wrote on 13 Jun 2017, 10:35 last edited by
                          #14

                          @VRonin

                          Of course

                          https://postimg.org/image/m1d45i71z/

                          I 1 Reply Last reply 13 Jun 2017, 12:22
                          0
                          • I Ioseph12
                            13 Jun 2017, 10:35

                            @VRonin

                            Of course

                            https://postimg.org/image/m1d45i71z/

                            I Offline
                            I Offline
                            Ioseph12
                            wrote on 13 Jun 2017, 12:22 last edited by
                            #15

                            @Ioseph12

                            I solved this. It seems as if the TableWidget is not cleared before starting to add items it keeps some residual widgets (weird behaviour) . Now I'm getting what I think that is the last error with this issue. When I click in a table row to edit one of the widgets, it happens this:

                                                                                                                           1st - Editor called
                              
                                                                                                                           2nd - Someone calls the widget destructor throwed as editor (internal signal)
                            
                                                                                                                           3rd - Tries to paint it (Obviously it crashes)
                            

                            Here is the call stack

                            !FilterWindow::~FilterWindow() Línea 28 C++
                            [External Code]
                            Qt5Cored.dll!qDeleteInEventHandler(QObject * o) Línea 4552 C++
                            Qt5Cored.dll!QObject::event(QEvent * e) Línea 1255 C++
                            Qt5Widgetsd.dll!QWidget::event(QEvent * event) Línea 9220 C++
                            Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Línea 3745 C++
                            Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Línea 3708 C++

                            1 Reply Last reply
                            0
                            • V VRonin
                              13 Jun 2017, 10:18

                              I would have many comments on the implementation but for now let's leave them in the drawer.

                              return new FilterWindow(*FrmWindows.at(idx.row())); should become return FrmWindows.at(idx.row());.
                              Don't return a copy (that you can't do anyway) but the widget itself

                              I Offline
                              I Offline
                              Ioseph12
                              wrote on 14 Jun 2017, 13:41 last edited by
                              #16

                              @VRonin

                              After some headache days I found the problem. The FilterWindow widget had set wrong the parent in children widgets, so, the right way would be :

                              void FilterWindow::setUi(std::string tittle)
                              {
                              	Frame = new QFrame(this); //Here it must be this, to set the widget itself as the parent
                              	Frame->setObjectName(QStringLiteral("Frame"));
                              	Frame->setFixedWidth(281);
                              	Frame->setFixedHeight(89);
                              	Frame->setStyleSheet(QLatin1String("QFrame\n"
                              		"{\n"
                              		"	border-style: solid;\n"
                              		"	border-width: 0px;\n"
                              		"	border-radius: 4px;\n"
                              		"	border-color: transparent;\n"
                              		"}"));
                              	Frame->setFrameShape(QFrame::StyledPanel);
                              	Frame->setFrameShadow(QFrame::Raised);
                              	Frame->setAttribute(Qt::WA_DeleteOnClose);
                              	checkBox = new QCheckBox(Frame);
                              	checkBox->setText(tittle.c_str());
                              	checkBox->setObjectName(QStringLiteral("checkBox"));
                              	checkBox->setGeometry(QRect(0, 0, 248, 35));
                              	checkBox->setAutoFillBackground(false);
                              	checkBox->setStyleSheet(QLatin1String("QCheckBox\n"
                              		"{\n"
                              		"	background-color: rgb(128,139,143);\n"
                              		"	color: white;\n"
                              		"	border-radius: 4px;\n"
                              		"	padding-left: 8px;\n"
                              		"}\n"
                              		"\n"
                              		"QCheckBox::indicator:unchecked {\n"
                              		"    image: url(:/OptiNanoPro/uchk);\n"
                              		"}\n"
                              		"\n"
                              		"\n"
                              		"QCheckBox::indicator:checked {\n"
                              		"    image: url(:/OptiNanoPro/chk);\n"
                              		"}\n"
                              		""));
                              	checkBox->setChecked(true);
                              	ArrowBtn = new QPushButton(Frame);
                              	ArrowBtn->setObjectName(QStringLiteral("ArrowBtn"));
                              	ArrowBtn->setGeometry(QRect(246, 0, 36, 35));
                              	ArrowBtn->setAutoFillBackground(true);
                              	QIcon icon;
                              	icon.addFile(QStringLiteral(":/OptiNanoPro/DownArrwLd"), QSize(), QIcon::Normal, QIcon::Off);
                              	ArrowBtn->setIcon(icon);
                              	ArrowBtn->setIconSize(QSize(36, 35));
                              	ArrowBtn->setFlat(true);
                              	Table = new QTableWidget(Frame);
                              	Table->setObjectName(QStringLiteral("Table"));
                              	Table->setGeometry(QRect(0, 35, 281, 31));
                              	Table->setStyleSheet(QLatin1String("QTableWidget\n"
                              		"{\n"
                              		"	background-color: white;\n"
                              		"	border-radius: 0px;\n"
                              		"}"
                              		"\n"
                              		"QCheckBox\n"
                              		"{\n"
                              		"	color: white;\n"
                              		"	padding-left: 8px;\n"
                              		"}\n"
                              		"\n"
                              		"QCheckBox::indicator:unchecked {\n"
                              		"    image: url(:/OptiNanoPro/uchk);\n"
                              		"}\n"
                              		"\n"
                              		"QCheckBox::indicator:checked {\n"
                              		"    image: url(:/OptiNanoPro/chk);\n"
                              		"}\n"
                              		""));
                              	ResetBtn = new QPushButton(Frame);
                              	ResetBtn->setText("Reset");
                              	ResetBtn->setObjectName(QStringLiteral("ResetBtn"));
                              	ResetBtn->setGeometry(QRect(0, 66, 169, 23));
                              	ResetBtn->setStyleSheet(QLatin1String("QPushButton\n"
                              		"{\n"
                              		"	background-color: white;\n"
                              		"	border-width: 1px;\n"
                              		"    border-style: solid;\n"
                              		"    border-color: rgb(86,86,84);\n"
                              		"	border-radius: 3px;\n"
                              		"	color: rgb(86,86,84);\n"
                              		"}"));
                              	AplyBtn = new QPushButton(Frame);
                              	AplyBtn->setText("Apply");
                              	AplyBtn->setObjectName(QStringLiteral("AplyBtn"));
                              	AplyBtn->setGeometry(QRect(169, 66, 111, 23));
                              	AplyBtn->setStyleSheet(QLatin1String("QPushButton\n"
                              		"{\n"
                              		"	background-color: white;\n"
                              		"	border-width: 1px;\n"
                              		"    border-style: solid;\n"
                              		"    border-color: rgb(86,86,84);\n"
                              		"	border-radius: 3px;\n"
                              		"	color: rgb(86,86,84);\n"
                              		"}"));
                              }
                              
                              
                              1 Reply Last reply
                              0

                              12/16

                              13 Jun 2017, 10:28

                              • Login

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