什麼是呈現點擊網址的最佳途徑QTableView
(或QTreeView
,QListView
,等...)如何在QTableView中
打開一個URL給定一個QStandardItemModel
,其中一些列包含帶有URL的文本我希望它們變得可點擊,然後使用QDesktopServices::openURL()
我希望有一些簡單的方法可以利用QLabel
的textInteraction標誌並將它們塞進表中。我不敢相信沒有更簡單的方法來處理這個問題。我真的很希望我錯過了一些東西。
什麼是呈現點擊網址的最佳途徑QTableView
(或QTreeView
,QListView
,等...)如何在QTableView中
打開一個URL給定一個QStandardItemModel
,其中一些列包含帶有URL的文本我希望它們變得可點擊,然後使用QDesktopServices::openURL()
我希望有一些簡單的方法可以利用QLabel
的textInteraction標誌並將它們塞進表中。我不敢相信沒有更簡單的方法來處理這個問題。我真的很希望我錯過了一些東西。
您需要創建一個委託來完成繪畫。代碼應該是這個樣子:
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();
}
那麼,你可以使用委託與定製代表重新實現paint方法,如QTableView中呈現富文本:
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。重新實現table/list視圖的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列。請注意,您需要取消模型中的顯示角色以避免重疊數據。
無論如何,我會對基於代表的更好的解決方案感興趣。
不幸的是,當使用QTableView
(而不是使用QTableWidget
)時,使用setOpenExternalLinks()
呈現QLabel
並不容易。沒有什麼神奇的兩行代碼可以調用並完成工作。
QTextDocument
與組合以呈現的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();
}
卡萊布,這是在tableview中繪製超鏈接的唯一方法,topicstarter希望瞭解如何在那裏創建可點擊的鏈接,而不需要將QTextBrowser放入每個單元格中。 – 2012-11-11 17:49:41
我非常擔心,如果您知道方式,請告訴我們,怎麼樣才能做到這一點。 – 2012-11-11 17:50:24
然後,您將重新實現QAbstractItemDelegate :: editorEvent()以接收鼠標點擊,並且如果點擊位於鏈接上,請使用QDesktopServices :: openUrl()打開URL。 – 2015-06-09 21:20:02