- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 Qt 新手,所以请耐心等待。
我已经成功地从 StringList 和对象的 QList 填充 ListView*
我现在正在努力解决的是使用 C++ 中定义的派生 QAbstractListModel 的类来填充 QML 中的 ListView。
这是我的 CPP 类的原型(prototype):
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 是一个简单的类,包含 2 个成员、一个 QColor 和一个 QString(该类不扩展 QObject)。
我必须实现上述所有函数,因为它们在底层类中是纯虚拟的(这正常吗?到目前为止,在教程/示例中,人们只提到了角色名称和数据)。
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();
}
ListView 的 QML 部分是这样的:
ListView {
id: quickMessageListdata
model: quickListModel
delegate: Rectangle {
width: 400
height: 25
color:"#000000"
Text{
text: model.message
color: model.messagecolor
}
}
到目前为止,这是我对如何在 CPP 和 QML 中实现事物的理解。为了链接这两者,我使用以下代码:
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 派生类的正确使用,要么我错过了一个简单的重要关键信息。
我希望获得一些相关示例/教程的指示(还向您展示如何正确访问 QML 中模型的数据,因为我注意到在 CPP 中它永远不会通过数据函数)。
另请注意,我使用的是 qt5 ,因此 qt4.8 示例无法解决问题。
编辑
经过长时间的挫折,我终于解决了这个该死的东西的问题:
我的 roleNames 函数签名错误!过载的正确签名是:
protected :
QHash<int,QByteArray> roleNames() const;
请注意 protected 和 const 修饰符。
以正确的方式声明函数后,一切正常。
为了进一步说明,实现 data 和 rowCount 就足够了:)。
感谢您的帮助。我会接受 BaCaRoZzo 的回答,因为我在查看示例中的代码后才设法弄清楚这一点。
顺便说一句,它可以很好地与 message 和 model.message 配合使用。
最佳答案
如何实现加法?您应该使用我的评论中提供的示例中的方法。
来自docs :
An insertRows() implementation must call beginInsertRows() before inserting new rows into the data structure, and it must call endInsertRows() immediately afterwards.
你应该有这样的东西:
void MessageListEntryModel::add(params...)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount()); // kindly provided by superclass
// object creation based on params...
m_vpMessages << objectCreated;
endInsertRows(); // kindly provided by superclass
}
与
int MessageListEntryModel::rowCount(const QModelIndex & parent) const {
Q_UNUSED(parent);
return m_vpMessages.count();
}
此外,@Jonathan Mee 评论是正确的:仅使用您在模型中定义的委托(delegate)内的角色名称。如果其他一切都正确这就是访问数据的方式。
<小时/>了解 C++ 模型实现和使用的最佳文档之一是 Model subclassing reference 。本文档清楚地描述了哪些是最重要的子类方法以及目的。
至于实现什么方法,那就看需求了。根据模型上可能的操作,应实现不同的方法(有关完整详细信息,请参阅上面的链接)。 ListView
的模型其中可以添加/删除的项目可以继承QAbstractListModel
并且仅依赖于大多数功能的默认实现。您只需要data()
, roleNames()
和rowCount()
,正如您在大多数示例中已经看到的那样。
如果您还需要编辑数据而不仅仅是添加/删除数据,那么您还需要其他功能,特别是setData()
。 您还有责任通知所附 View setData()
中发生的任何模型修改。 ,通过信号dataChanged()
。再次引用上面提供的子类化引用。
另请注意,如果 add
方法修改为 Q_INVOKABLE
修饰符,即它被声明为
Q_INVOKABLE void add(params...);
在模型 header 中,您还可以从 QML 调用它(因为模型被设置为上下文属性),并且您可以编写,例如:
ListView {
id: quickMessageListdata
model: quickListModel
delegate: Rectangle {
width: 400
height: 25
color:"#000000"
Text{
text: model.message
color: model.messagecolor
}
}
Component.onCompleted: {
quickListModel.add(params)
quickListModel.add(params)
}
}
创建 View 后立即将项目插入 View 中。显然,相同的方法可以应用于其他 QML 信号,以便您可以对 QML 事件使用react并触发添加/删除行为。
最后,您不需要使用 qmlRegisterType
注册模型。对于您当前的要求来说,这是多余的。
关于qt - 在 ListView 中使用 QAbstractListModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27400025/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!