QListWidget doesn't show properly custom QWidget



  • Hi all,

    I'm trying to make some kind of list where I can add an undefined number of custom widgets. After reading a bit in the forum I found this code, but it doesn't seem to work properly as the widget is not displayed. Here is the code:

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

    The custom widget (FilterWindow) looks like this

    0_1496918621590_Custom widget 2.jpg

    And this is how it looks like

    0_1496918670301_wrong.jpg

    Could anyone give me a hint?

    Thank you so much



  • will all widgets in the list be of type FilterWindow?



  • I'll have only FilterWindows and one QCalendarWidget

    0_1496926167564_final.jpg



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



  • @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





  • @VRonin

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



  • @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



  • 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)



  • @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é



  • 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



  • @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)



  • 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?





  • @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++



  • @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"
    		"}"));
    }
    
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.