2013-02-07 91 views
4

所以我想要的是一個qlistview,顯示可選擇的小部件(標籤,顯示圖像和文本的按鈕(小部件是基於qwidget的小部件,其水平佈局與QLabelQPushButton))。模型應該存儲每個項目的圖像路徑和按鈕文本(這似乎不成問題)。我成功創建了一個QListView派生的窗口小部件,但它只顯示第一個列表項(這是自定義窗口小部件)並且不可選。我創建了一個自定義模型,視圖和委託,但我無法弄清楚如何在所有列表項上顯示小部件,而不僅僅是第一個。 這裏是完整的源代碼鏈接:SOURCE CODE LINKQWidget as查看項目(Qt模型視圖控制器)

我運行的應用程序與5小工具項目的列表和一個小工具項目列表分開。我認爲它添加小部件,但它與重疊所有的人都在第一個(在5個項目建設對按鈕更密集的陰影): Widget compiled and ran with 5 widget items defined in the loop

1小部件:名單上

5小部件清單: Widget compiled and ran with 1 widget item defined in the loop

正如你所看到的那樣,陰影有所不同。

下面是代碼的另一個副本:

Delegate.h 下面是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包含列表視圖:

#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 窗口小部件被用作列表項

#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 

檔案。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()); 
} 

誰能幫我填寫的所有列表項與通緝的小部件或告訴我我做錯了什麼或一些提示?是否有可能在這個MVC風格的小部件作爲列表/表項目?我無法在任何地方找到任何參考資料。在C++中使用Qt進行GUI編程,高級Qt編程,在C++中使用Qt 4和其他幾個地方介紹設計模式,但是找不到與QAbstractItemView::setIndexWidget相關的任何東西,我認爲這是將小部件添加爲列表查看項目。

謝謝!

+0

究竟 「不工作」?也許嘗試在ProfileItem中重新實現QSize sizeHint()const。 –

+1

「index = new QModelIndex(model-> index(0,0));」 < - 在堆上創建QModelIndex沒有意義(對於QStringList也是如此)。將索引存儲爲成員也很糟糕,因爲索引在返回到事件循環時可能變得無效。如果您需要存儲索引,請使用QPersistentModelIndex。 –

+0

我更新了代碼。那麼,如果我將該按鈕設置爲setIndexWidget的第二個參數,那麼視圖的第一個元素變成了一個按鈕,但是當我將它設置爲我的小部件時,第一個元素就像文本從未發生過的那樣。 –

回答