Note that there are some explanatory texts on larger screens.

plurals
  1. POQWidget as View Item (Qt Model View Controller)
    text
    copied!<p>So what I want is a qlistview that displays selectable widgets(label that displays an image and text for a button(widget is a qwidget based widget which has a horizontal layout with a <code>QLabel</code> and a <code>QPushButton</code>)). The model should store image path and button text for each item(which doesn't seem to be a problem). I successfully created a QListView derived widget but it displays only the first list item(which is the custom widget) and it's not selectable. I created a custom model, view and delegate but I can't figure out what to do to show widgets on all the list items, not just first. Here is the complete source code link: <a href="http://www.4shared.com/zip/HqTVzqHu/WidgetListView.html" rel="nofollow noreferrer">SOURCE CODE LINK</a></p> <p>I ran the application with a list of 5 widgets items and with a list of 1 widget item separatly. And I think it adds the widgets but it overlaps all of them on the first one(the 5 items build has a denser shadow on the button):</p> <p>5 widgets on the list: <img src="https://i.stack.imgur.com/KIDvu.png" alt="Widget compiled and ran with 5 widget items defined in the loop"></p> <p>1 widget in the list: <img src="https://i.stack.imgur.com/F926Y.png" alt="Widget compiled and ran with 1 widget item defined in the loop"></p> <p>As you can see there is a difference in the shadow.</p> <p>Here is another copy of the code:</p> <blockquote> <p>Delegate.h Here is the code for the <code>delegate</code>:</p> </blockquote> <pre><code>#include &lt;QtGui&gt; #include &lt;QAbstractItemDelegate&gt; class WidgetDelegate : public QAbstractItemDelegate { public: WidgetDelegate(QObject *parent = 0); void paint(QPainter *painter, const QStyleOptionViewItem &amp;option, const QModelIndex &amp;index) const; QSize sizeHint(const QStyleOptionViewItem &amp;option, const QModelIndex &amp;index) const; }; </code></pre> <blockquote> <p>Delegate.cpp</p> </blockquote> <pre><code>#include &lt;QtGui&gt; #include "Delegate.h" #include "Profile.h" WidgetDelegate::WidgetDelegate(QObject *parent) : QAbstractItemDelegate(parent) { } void WidgetDelegate::paint(QPainter */*painter*/, const QStyleOptionViewItem &amp;/*option*/, const QModelIndex &amp;/*index*/) const { } QSize WidgetDelegate::sizeHint(const QStyleOptionViewItem &amp;/*option*/, const QModelIndex &amp;/*index*/) const { return QSize(ProfileItem().geometry().width(), ProfileItem().geometry().height()); } </code></pre> <blockquote> <p>Model.h</p> </blockquote> <pre><code>#ifndef MODEL_H #define MODEL_H #include &lt;QStringList&gt; #include &lt;QAbstractListModel&gt; #include &lt;QList&gt; #include "Profile.h" class StringListModel : public QAbstractListModel { Q_OBJECT public: StringListModel(const QStringList &amp;strings, QObject *parent = 0) : QAbstractListModel(parent), stringList(strings) {} int rowCount(const QModelIndex &amp;parent = QModelIndex()) const; QVariant data(const QModelIndex &amp;index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; private: QStringList stringList; }; #endif // MODEL_H </code></pre> <blockquote> <p>Model.cpp</p> </blockquote> <pre><code>#include "Model.h" #include &lt;QVariant&gt; int StringListModel::rowCount(const QModelIndex &amp;/*parent*/) const { return stringList.count(); } QVariant StringListModel::data(const QModelIndex &amp;/*index*/, int /*role*/) const { } QVariant StringListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const { } </code></pre> <blockquote> <p>Prefs.h Widget containing the list view:</p> </blockquote> <pre><code>#ifndef PREFERENCES_H #define PREFERENCES_H #include "Model.h" #include &lt;QDialog&gt; 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 </code></pre> <blockquote> <p>Prefs.cpp</p> </blockquote> <pre><code>#include "Profile.h" #include &lt;QPixmap&gt; #include &lt;QHBoxLayout&gt; #include &lt;QBitmap&gt; #include &lt;QMessageBox&gt; ProfileItem::ProfileItem(QWidget *parent) : QWidget(parent) { pixmap = QPixmap(":/avatar"); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); m_avatarTextButton.setText("Test"); connect(&amp;m_avatarTextButton, SIGNAL(clicked()), this, SLOT(buttonPushed())); m_pHorizontalLayout = new QHBoxLayout; m_pHorizontalLayout-&gt;addWidget(&amp;m_avatarImageLabel); m_pHorizontalLayout-&gt;addWidget(&amp;m_avatarTextButton); setLayout(m_pHorizontalLayout); } void ProfileItem::setAvatarImage(const QString &amp;avatarImage) { pixmap = QPixmap(avatarImage); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); } void ProfileItem::setAvatarName(const QString &amp;avatarName) { m_avatarTextButton.setText(avatarName); } void ProfileItem::buttonPushed() { QMessageBox msg; msg.setText("Button was pushed!"); msg.exec(); } </code></pre> <blockquote> <p>Profile.h Widget that has to be used as list item</p> </blockquote> <pre><code>#ifndef PROFILEITEM_H #define PROFILEITEM_H #include &lt;QWidget&gt; #include &lt;QLabel&gt; #include &lt;QPushButton&gt; #include &lt;QPixmap&gt; class QHBoxLayout; class ProfileItem : public QWidget { Q_OBJECT public: explicit ProfileItem(QWidget *parent = 0); public slots: void setAvatarImage(const QString &amp;avatarImage); void setAvatarName(const QString &amp;avatarName); void buttonPushed(); private: QPixmap pixmap; QLabel m_avatarImageLabel; QPushButton m_avatarTextButton; QHBoxLayout *m_pHorizontalLayout; }; #endif // PROFILEITEM_H </code></pre> <blockquote> <p>Profile.cpp</p> </blockquote> <pre><code>#include "Profile.h" #include &lt;QPixmap&gt; #include &lt;QHBoxLayout&gt; #include &lt;QBitmap&gt; #include &lt;QMessageBox&gt; ProfileItem::ProfileItem(QWidget *parent) : QWidget(parent) { pixmap = QPixmap(":/avatar"); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); m_avatarTextButton.setText("Test"); connect(&amp;m_avatarTextButton, SIGNAL(clicked()), this, SLOT(buttonPushed())); m_pHorizontalLayout = new QHBoxLayout; m_pHorizontalLayout-&gt;addWidget(&amp;m_avatarImageLabel); m_pHorizontalLayout-&gt;addWidget(&amp;m_avatarTextButton); setLayout(m_pHorizontalLayout); } void ProfileItem::setAvatarImage(const QString &amp;avatarImage) { pixmap = QPixmap(avatarImage); m_avatarImageLabel.setPixmap(pixmap); m_avatarImageLabel.setMask(pixmap.mask()); } void ProfileItem::setAvatarName(const QString &amp;avatarName) { m_avatarTextButton.setText(avatarName); } void ProfileItem::buttonPushed() { QMessageBox msg; msg.setText("Button was pushed!"); msg.exec(); } </code></pre> <blockquote> <p>View.h</p> </blockquote> <pre><code>#ifndef VIEW_H #define VIEW_H #include &lt;QListView&gt; class View : public QListView { public: View(); void setModel(QAbstractItemModel *model); QSize sizeHint(); }; #endif // VIEW_H </code></pre> <blockquote> <p>View.cpp</p> </blockquote> <pre><code>#include "View.h" #include "Profile.h" View::View() { viewport()-&gt;setAutoFillBackground(false); setSelectionMode(QAbstractItemView::SingleSelection); } void View::setModel(QAbstractItemModel* model) { QListView::setModel(model); for (int i = 0; i &lt; 5; ++i) { QModelIndex index = model-&gt;index(i, 0); ProfileItem* widget = new ProfileItem(); setIndexWidget(index, widget); } } QSize View::sizeHint() { return QSize(ProfileItem().width(), ProfileItem().height()); } </code></pre> <p>Can anyone help me populate all the list items with the wanted widget or tell me what i'm doing wrong or some hints? Is it possible in qt to have widgets as list/table items in this MVC style? I couldn't find any references for achieving this anywhere. Searched in C++ GUI Programming with Qt, Advanced Qt Programming, Introduction to Design Patterns in C++ with Qt 4 and a few more places on the internet but couldn't find anything related to <code>QAbstractItemView::setIndexWidget</code> which I think it's the method that adds the widget as a list view item.</p> <p>Thank you!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload