在QTableView
(或QTreeView
,QListView
等)中提供可点击网址的最佳方式是什么?)< / b>
给定QStandardItemModel
,其中某些列包含带有网址的文字,我希望它们可以点击,然后使用QDesktopServices::openURL()
我希望能有一些简单的方法来利用QLabel
的textInteraction标志并将它们塞进表中。我无法相信没有更简单的方法来处理这个问题。我真的希望我错过了什么。
答案 0 :(得分:6)
您需要创建一个委托来进行绘画。代码看起来像这样:
void RenderLinkDelegate::paint(
QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index
) const
{
QString text = index.data(Qt::DisplayRole).toString();
if (text.isEmpty())
return;
painter->save();
// I only wanted it for mouse over, but you'll probably want to remove
// this condition
if (option.state & QStyle::State_MouseOver)
{
QFont font = option.font;
font.setUnderline(true);
painter->setFont(font);
painter->setPen(option.palette.link().color());
}
painter->drawText(option.rect, Qt::AlignLeft | Qt::AlignVCenter, text);
painter->restore();
}
答案 1 :(得分:5)
好吧,您可以使用委托在qtableview中呈现富文本,并使用自定义委托重新实现paint方法,例如:
void CHtmlDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt(option);
QLabel *label = new QLabel;
label->setText(index.data().toString());
label->setTextFormat(Qt::RichText);
label->setGeometry(option.rect);
label->setStyleSheet("QLabel { background-color : transparent; }");
painter->translate(option.rect.topLeft());
label->render(painter);
painter->translate(-option.rect.topLeft());
}
但是,它不会使超链接可以点击。
为此,您可以使用以下hack。重新实现表/列表视图的setModel方法并使用setIndexWidget。
void MyView::setModel(QAbstractItemModel *m)
{
if (!m)
return;
QTableView::setModel(m);
const int rows = model()->rowCount();
for (int i = 0; i < rows; ++i)
{
QModelIndex idx = model()->index(i, 1);
QLabel *label = new QLabel;
label->setTextFormat(Qt::RichText);
label->setText(model()->data(idx, CTableModel::HtmlRole).toString());
label->setOpenExternalLinks(true);
setIndexWidget(idx, label);
}
}
在上面的例子中,我用qlabels替换了第1列。请注意,您需要使模型中的显示角色无效,以避免重叠数据。
无论如何,我会对基于代表的更好的解决方案感兴趣。
答案 2 :(得分:1)
遗憾的是,使用QLabel
(而不是使用setOpenExternalLinks()
)时,使用QTableView
呈现QTableWidget
并不容易。没有神奇的两行代码可以调用并完成工作。
QTextDocument
与setHTML()
相结合来呈现html链接a href
painter->setWidgetToCell()
-
void LabelColumnItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if( option.state & QStyle::State_Selected )
painter->fillRect( option.rect, option.palette.highlight() );
painter->save();
QTextDocument document; // <---- RichText
document.setTextWidth(option.rect.width());
QVariant value = index.data(Qt::DisplayRole);
if (value.isValid() && !value.isNull())
{
document.setHtml(value.toString()); // <---- make sure model contains html
painter->translate(option.rect.topLeft());
document.drawContents(painter);
}
painter->restore();
}