2010-03-03 2 views
6

Что такое лучший способ представить интерактивными URL в QTableView (или QTreeView, QListView, и т.д ...)Как открыть URL в QTableView

QStandardItemModel Учитывая, где некоторые из столбцы содержат текст с URL, я хотел бы, чтобы они стали интерактивными, а затем обработать щелчок с помощью QDesktopServices::openURL()

Я надеялся, что будет какая-то простой способ использовать QLabel «s textInteraction флаги и втиснуть их в таблицу. Я не могу поверить, что нет более простого способа справиться с этим. Я очень надеюсь, что я что-то упустил.

ответ

5

Вам нужно будет создать делегат, чтобы сделать картину. Код должен выглядеть примерно так:

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(); 
} 
+0

Kaleb , это единственный способ рисовать гиперссылки в tableview, а topicstarter хотел бы реализовать, как сделать доступными для него ссылки, без ввода QTextBrowser в каждую ячейку. –

+0

Я очень обеспокоен, как я могу это сделать, если вы знаете путь, пожалуйста, расскажите нам, как. –

+0

Затем вы также переопределите QAbstractItemDelegate :: editorEvent(), чтобы получить щелчки мыши, а если клик по ссылке, используйте QDesktopServices :: openUrl(), чтобы открыть URL-адрес. –

2

Ну, вы можете использовать делегат оказывать форматированный текст в 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()); 
} 

Тем не менее, не будет делать гиперссылки интерактивными.

Для этого вы можете использовать следующий взлом. Переопределите метод 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); 
    } 
} 

В приведенном выше примере я заменяю столбцы 1 метками. Обратите внимание, что вам необходимо аннулировать роль отображения в модели, чтобы избежать дублирования данных.

В любом случае, меня будет интересовать лучшее решение на основе делегатов.

0

К сожалению, его не так легко вынести QLabel с setOpenExternalLinks() при использовании QTableView (в отличие от использования QTableWidget). Нет волшебных двух строк кода, которые вы можете вызвать и выполнить эту работу.

  1. использовать делегат
  2. установить делегат в столбце вашей таблицы
  3. использования QTextDocument в сочетании с setHTML(), чтобы сделать ссылку HTML
  4. это означает, что модель должна обеспечить фрагмент HTML, содержащий a href
  5. вычислить геометрию ссылки и предоставить обработчики событий для перехвата мыши
    • изменить курсор, когда он находится над ссылкой
    • выполнить действие при щелчке на ссылке
  6. что беспорядок :(я хочу 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(); 
} 
Смежные вопросы