2010-03-03 14 views
6

¿Cuál es la mejor manera de presentar un hacer clic en el URL en un QTableView (o QTreeView, QListView, etc ...)¿Cómo abrir un URL en una QTableView

Dado un QStandardItemModel donde algunos de los columnas contienen texto con direcciones URL que me gustaría que se conviertan en hacer clic y luego manejar el clic mediante el uso de QDesktopServices::openURL()

Tenía la esperanza de que habría alguna forma sencilla de aprovechar QLabel 's banderas textInteraction y de meter ellos en la tabla. No puedo creer que no haya una manera más fácil de manejar esto. Realmente espero que me esté perdiendo algo.

Respuesta

5

Tendrá que crear un delegado para hacer la pintura. El código debe ser algo como esto:

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 , esta es la única forma de pintar hipervínculos en una vista de tabla, y topicstarter quería darse cuenta de cómo hacer enlaces clicables allí, sin poner un QTextBrowser en cada celda. –

+0

Estoy muy preocupado, ¿cómo puedo hacerlo, también, si conoce el camino, por favor, díganos cómo. –

+0

También debe volver a implementar QAbstractItemDelegate :: editorEvent() para recibir clics del mouse, y si el clic está en un enlace, use QDesktopServices :: openUrl() para abrir la URL. –

2

Bueno, se puede utilizar delegados a rendir texto enriquecido en un qtableview con los delegados personalizados reimplementar el método de pintura tales como:

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

Sin embargo, no hará que se pueda hacer clic en los hipervínculos.

Para hacerlo, puede usar el siguiente truco. Vuelva a implementar el método setModel de su vista de tabla/lista y use 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); 
    } 
} 

En el ejemplo anterior, reemplazo la columna 1 con q etiquetas. Tenga en cuenta que debe anular la función de visualización en el modelo para evitar la superposición de datos.

De todos modos, estaría interesado en una mejor solución basada en los delegados.

0

Lamentablemente, no es tan fácil de prestar un QLabel con setOpenExternalLinks() cuando se utiliza un QTableView (en lugar de utilizar un QTableWidget). No hay dos líneas mágicas de código que pueda llamar y hacer el trabajo.

  1. uso un delegado
  2. establece el delegado a la columna de la tabla
  3. uso QTextDocument combinado con setHTML() para representar un enlace HTML
  4. esto significa que su modelo necesita para proporcionar un fragmento de HTML que contiene a href
  5. calcule la geometría del enlace y proporcione controladores de eventos para interceptar el mouse
    • cambiar el cursor cuando está sobre el enlace
    • ejecutar la acción cuando se hace clic en el enlace
  6. qué desastre :(quiero 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(); 
} 
Cuestiones relacionadas