【Qt】QListView 显示富文本,设置文本内容颜色
文章目录
- I - 控件使用
- II - 显示富文本
- III - 注意事项
I - 控件使用
Qt 的 MVC 架构为 MV ,Controller 部分继承到了 View 里,View(视图) 设置 Model(模型),Model 设置数据
这里使用 QStringListModel ,设置 Model 后,只需要设置字符串链表数据就可以了。
头文件中声明 QStringListModel ,这里使用前置声明防止强依赖。
class QStringListModel;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// ...
private:
//...
QStringListModel* m_model;
};
源文件中包含 QStringListModel 头文件
#include <QStringListModel>
构造函数中初始化 QStringListModel,设置 QListView 的 Model ,给要显示的 QStringList 赋值
// 初始化
m_model = new QStringListModel();
// 设置模型
ui->listView->setModel(m_model);
// 给 QStringList 赋值
m_list << "Text is Keyword aaa"<< "Keyword ddd"<< "Keyword ccc"
<< "in some Text Keyword nanana" << "blablabla Keyword";
另外设置 QListView 的其他属性:
- 设置无编辑触发 NoEditTriggers
- 设置行间交替显示不同的颜色 setAlternatingRowColors
- 设置不显示水平滚动条
// 其他设置
ui->listView->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers);
ui->listView->setAlternatingRowColors(true);
ui->listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
使用时,只需要操作 Model 设置数据,就可以显示了
m_model->setStringList(m_list);
效果如下图
II - 显示富文本
QListView 无法直接显示富文本,可以通过设置其他控件来显示富文本,调用 setIndexWidget 接口。
在 Qt 的帮助文档中可以看到 ownership 转移了,就是说不需要担心内存泄漏的问题,且在同一个索引位置,如果设置了另一个控件,则前一个控件会被删除释放掉。 注意:设置的控件如果 autoFillBackground 没有设置,则控件背景为透明显示。
将 QStringList 中的 Keyword 设置为富文本
QString keyword("Keyword");
for (int i = 0; i < m_list.size(); ++i)
{
int index = m_list[i].indexOf(keyword);
m_list[i].insert(index+ keyword.size(), "</font>");
m_list[i].insert(index, "<font color='#5050ff'>");
}
设置 StringList 并在每个索引处依次添加 QLabel 控件显示富文本
m_model->setStringList(m_list);
for (int i = 0; i < m_list.size(); ++i)
{
QLabel* label = new QLabel(m_list[i]);
label->setTextFormat(Qt::RichText); // 设置显示格式为富文本
label->setAutoFillBackground(true); // 设置自动填充背景
ui->listView->setIndexWidget(m_model->index(i), label); // 设置控件
}
效果如下图:
III - 注意事项
此处添加 QLabel 的自动填充背景,会导致 QListView 的控件样式失效,也会导致原来的 QListView 中的项无法被点击、触发
等等。
处理该问题需要设置 QLabel 不自动填充背景色,且设置鼠标事件透明
//label->setAutoFillBackground(true);
label->setAttribute(Qt::WA_TransparentForMouseEvents);
此时由于无自动填充背景,会显示两个控件的文本内容,原始的 QListView item 和新增的 QLabel。
解决此问题可以用两种方法
- 设置数据时,设置为空的字符串,显示时显示实际的
- 设置 QListView item 的样式为前景色透明
setStyleSheet("QListView::item {color:transparent}");
最终效果如下:
另外,富文本中的大于号小于号需要使用特殊符号替换掉,否则无法显示
符号 | 富文本替换 |
---|---|
> | > |
< | < |