我想要一个显示可选小部件的 qlistview(包括显示图像和按钮文本的标签小部件)。该模型应存储每个项目的图像路径和按钮文本。我成功创建了一个 QListView 派生小部件,但它仅显示第一项(自定义小部件),且无法选择。我创建了一个自定义模型、视图和代理,但我不知道如何在所有列表项上显示小部件,而不仅是第一个。
以下是完整的源代码链接:SOURCE CODE LINK
我分别使用了包含 5 个小部件项目和包含 1 个小部件项目的列表来运行应用程序。我认为它确实添加了这些小部件,但是所有的小部件都重叠在第一个小部件上(包含 5 个小部件的版本中按钮有更浓的阴影效果):
包含 5 个小部件的列表:
包含 1 个小部件的列表:
您可以看到阴影存在差异。
以下是代码备份:
有谁能帮我用所需的小部件填充所有列表项,或告诉我我做错了什么或给我一些提示吗?在qt中是否有可能以这种MVC风格将小部件作为列表/表项?在任何地方都找不到实现此功能的参考资料。在《C ++ GUI编程与Qt》、《高级Qt编程》、《C ++中的设计模式入门》以及互联网上的其他几个地方搜索过,但找不到与
包含 5 个小部件的列表:
![Widget compiled and ran with 5 widget items defined in the loop](https://istack.dev59.com/KIDvu.webp)
![Widget compiled and ran with 1 widget item defined in the loop](https://istack.dev59.com/F926Y.webp)
以下是代码备份:
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
包含列表视图的小部件:
#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
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());
}
有谁能帮我用所需的小部件填充所有列表项,或告诉我我做错了什么或给我一些提示吗?在qt中是否有可能以这种MVC风格将小部件作为列表/表项?在任何地方都找不到实现此功能的参考资料。在《C ++ GUI编程与Qt》、《高级Qt编程》、《C ++中的设计模式入门》以及互联网上的其他几个地方搜索过,但找不到与
QAbstractItemView ::setIndexWidget
相关的任何内容,我认为它是将小部件添加为列表视图项的方法。
谢谢!
QSize ProfileItem::sizeHint() const { return QSize(300, 100); }
,在头文件中使用了QSize sizeHint() const;
。 - Jacob Krieg