QWidget as a view item (Qt Model View Controller)

So what I want is a qlistview that displays selectable widgets (a shortcut that displays the image and text for the button (the widget is a qwidget-based widget that has a horizontal layout with QLabel and QPushButton )). The model should store the image path and button text for each element (which seems to be no problem). I have successfully created a QListView widget, but it only displays the first element of the list (which is custom widgets) and it is not selectable. I created a custom model, view and delegation, but I can’t figure out what to do to show widgets in all elements of the list, and not just in the first place. Here is the complete link to the source code: SOURCE CODE LINK

I launched the application with a list of 5 widget elements and a list of 1 widget elements. And I think that it adds widgets, but it overlaps all of them on the first (5 elements have a denser shadow on the button):

5 widgets listed: Widget compiled and ran with 5 widget items defined in the loop

1 widget in the list: Widget compiled and ran with 1 widget item defined in the loop

As you can see, there is a difference in shadow.

Here is another copy of the code:

delegate.h Here is the code for delegate :

 #include <QtGui> #include <QAbstractItemDelegate> class WidgetDelegate : public QAbstractItemDelegate { public: WidgetDelegate(QObject *parent = 0); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; }; 

delegate.cpp

 #include <QtGui> #include "Delegate.h" #include "Profile.h" WidgetDelegate::WidgetDelegate(QObject *parent) : QAbstractItemDelegate(parent) { } void WidgetDelegate::paint(QPainter */*painter*/, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const { } QSize WidgetDelegate::sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const { return QSize(ProfileItem().geometry().width(), ProfileItem().geometry().height()); } 

model.h

 #ifndef MODEL_H #define MODEL_H #include <QStringList> #include <QAbstractListModel> #include <QList> #include "Profile.h" class StringListModel : public QAbstractListModel { Q_OBJECT public: StringListModel(const QStringList &strings, QObject *parent = 0) : QAbstractListModel(parent), stringList(strings) {} int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; private: QStringList stringList; }; #endif // MODEL_H 

model.cpp

 #include "Model.h" #include <QVariant> int StringListModel::rowCount(const QModelIndex &/*parent*/) const { return stringList.count(); } QVariant StringListModel::data(const QModelIndex &/*index*/, int /*role*/) const { } QVariant StringListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const { } 

Prefs.h Widget containing a list view:

 #ifndef PREFERENCES_H #define PREFERENCES_H #include "Model.h" #include <QDialog> class QPushButton; class ProfileItem; class QVBoxLayout; class View; class StringListModel; class Preferences : public QDialog { public: Preferences(QWidget *parent = 0); private: QVBoxLayout *m_pVerticalLayout; View *myList; QPushButton *button; ProfileItem *item; StringListModel *customModel; }; #endif // PREFERENCES_H 

Prefs.cpp

 #include "Profile.h" #include <QPixmap> #include <QHBoxLayout> #include <QBitmap> #include <QMessageBox> ProfileItem::ProfileItem(QWidget *parent) : QWidget(parent) { pixmap = QPixmap(":/avatar"); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); m_avatarTextButton.setText("Test"); connect(&m_avatarTextButton, SIGNAL(clicked()), this, SLOT(buttonPushed())); m_pHorizontalLayout = new QHBoxLayout; m_pHorizontalLayout->addWidget(&m_avatarImageLabel); m_pHorizontalLayout->addWidget(&m_avatarTextButton); setLayout(m_pHorizontalLayout); } void ProfileItem::setAvatarImage(const QString &avatarImage) { pixmap = QPixmap(avatarImage); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); } void ProfileItem::setAvatarName(const QString &avatarName) { m_avatarTextButton.setText(avatarName); } void ProfileItem::buttonPushed() { QMessageBox msg; msg.setText("Button was pushed!"); msg.exec(); } 

Profile.h Widget to be used as a list item.

 #ifndef PROFILEITEM_H #define PROFILEITEM_H #include <QWidget> #include <QLabel> #include <QPushButton> #include <QPixmap> class QHBoxLayout; class ProfileItem : public QWidget { Q_OBJECT public: explicit ProfileItem(QWidget *parent = 0); public slots: void setAvatarImage(const QString &avatarImage); void setAvatarName(const QString &avatarName); void buttonPushed(); private: QPixmap pixmap; QLabel m_avatarImageLabel; QPushButton m_avatarTextButton; QHBoxLayout *m_pHorizontalLayout; }; #endif // PROFILEITEM_H 

Profile.cpp

 #include "Profile.h" #include <QPixmap> #include <QHBoxLayout> #include <QBitmap> #include <QMessageBox> ProfileItem::ProfileItem(QWidget *parent) : QWidget(parent) { pixmap = QPixmap(":/avatar"); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); m_avatarTextButton.setText("Test"); connect(&m_avatarTextButton, SIGNAL(clicked()), this, SLOT(buttonPushed())); m_pHorizontalLayout = new QHBoxLayout; m_pHorizontalLayout->addWidget(&m_avatarImageLabel); m_pHorizontalLayout->addWidget(&m_avatarTextButton); setLayout(m_pHorizontalLayout); } void ProfileItem::setAvatarImage(const QString &avatarImage) { pixmap = QPixmap(avatarImage); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); } void ProfileItem::setAvatarName(const QString &avatarName) { m_avatarTextButton.setText(avatarName); } void ProfileItem::buttonPushed() { QMessageBox msg; msg.setText("Button was pushed!"); msg.exec(); } 

view.h

 #ifndef VIEW_H #define VIEW_H #include <QListView> class View : public QListView { public: View(); void setModel(QAbstractItemModel *model); QSize sizeHint(); }; #endif // VIEW_H 

view.cpp

 #include "View.h" #include "Profile.h" View::View() { viewport()->setAutoFillBackground(false); setSelectionMode(QAbstractItemView::SingleSelection); } void View::setModel(QAbstractItemModel* model) { QListView::setModel(model); for (int i = 0; i < 5; ++i) { QModelIndex index = model->index(i, 0); ProfileItem* widget = new ProfileItem(); setIndexWidget(index, widget); } } QSize View::sizeHint() { return QSize(ProfileItem().width(), ProfileItem().height()); } 

Can someone help me fill out all the elements of the list with the necessary widgets or tell me what I'm doing wrong or some hints? Is it possible in qt to have widgets as list / table elements in this MVC style? I could not find any links to achieve this anywhere. Search in C ++ GUI Programming with Qt, Advanced Qt programming, Introduction to C ++ design patterns with Qt 4 and a few more places on the Internet, but could not find anything related to QAbstractItemView::setIndexWidget , which I think is A method that adds a widget as an element of a list.

Thanks!

+4
source share

All Articles