私は Qt が初めてなので、ご容赦ください。
StringList と Object* の QList から ListView を作成することに成功しました
私が今苦労しているのは、QAbstractListModel を派生させる C++ で定義されたクラスを使用して QML に ListView を設定することです。
これが私の CPP クラスのプロトタイプです:
class MessageListEntryModel : public QAbstractListModel
{
Q_OBJECT
public:
enum eMLERoleTypes
{
MLERT_MSG = Qt::UserRole+1,
MLERT_COLOR
};
MessageListEntryModel(QObject* parent=0);
virtual ~MessageListEntryModel();
void AddEntry(QString aMessage, QColor aColor);
// pure virtuals implementations
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const ;
int columnCount(const QModelIndex &parent = QModelIndex()) const ;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const ;
QHash<int,QByteArray> roleNames();
private:
QList<MessageEntry*> m_vpMessages;
MessageEntry は、QColor と QString の 2 つのメンバーを含む単純なクラスです (このクラスは QObject を拡張しません)。
上記のすべての関数は、基礎となるクラスで純粋な仮想であるため、実装する必要がありました (これは正常ですか? これまでのところ、チュートリアル/サンプルでは、roleNames とデータについてのみ言及されています)。
roleNames と data の実装は次のとおりです。
QHash<int,QByteArray> MessageListEntryModel::roleNames()
{
QHash<int,QByteArray> rez;
rez[MLERT_MSG]="message";
rez[MLERT_COLOR]="messagecolor";
return rez;
}
QVariant MessageListEntryModel::data(const QModelIndex &index, int role) const
{
qDebug()<<" Data asked for "<<index.row()<<" and role "<<role;
if (index.row()<0 || index.row()>=m_vpMessages.size())
{
return QVariant();
}
MessageEntry* entry = m_vpMessages[index.row()];
if (role == MLERT_MSG)
{
return QVariant::fromValue(entry->message);
} else if (role == MLERT_COLOR)
{
return QVariant::fromValue(entry->messageColor);
}
// should be unreachable code
return QVariant();
}
リスト ビューの QML 部分は次のようなものです。
ListView {
id: quickMessageListdata
model: quickListModel
delegate: Rectangle {
width: 400
height: 25
color:"#000000"
Text{
text: model.message
color: model.messagecolor
}
}
これまでのところ、これは CPP と QML で物事を実装する方法についての私の理解です。これら 2 つをリンクするには、次のコードを使用します。
MessageListEntryModel* model =new MessageListEntryModel();
// Add various entries
...
// assign model in QML
m_pViewRef->rootContext()->setContextProperty("quickListModel",model);
上記のコードでは、実行時に ListView に何も表示されず、次のエラーが発生します。
Unable to assign [undefined] to QString
Unable to assign [undefined] to QColor
QMLにエクスポートするモデルクラスも登録しています(これが必要かどうかはわかりません):
qmlRegisterType<MessageListEntryModel> ("dlti.exported",1,0,"MessageListEntryModel");
したがって、QAbstractListItem 派生クラスの適切な使用法を誤解したか、単純な重要なキー情報を見逃していることは明らかです。
関連するいくつかのサンプル/チュートリアルへのポインタをいただければ幸いです(CPPではデータ関数を決して通過しないことに気付いたので、QMLでモデルからデータに適切にアクセスする方法も示しています)。
また、私は qt5 を使用しているため、qt4.8 サンプルではうまくいかないことに注意してください。
編集
何時間もフラストレーションを感じた後、私はついに何が問題だったのかを突き止めました。
私の roleNames 関数の署名が間違っていました! オーバーロードの正しい署名は次のとおりです。
protected :
QHash<int,QByteArray> roleNames() const;
protected および const 修飾子に注意してください。
関数を正しい方法で宣言した後、すべて正常に機能しました。
さらに注意するには、 data と rowCount を実装するだけで十分でした:)。
助けてくれてありがとう。例のコードを調べた後にこれを理解できただけなので、BaCaRoZzoの回答を受け入れます。
補足として、これは message と model.message の両方でうまく機能します。