2010-03-03 10 views
6

là gì cách tốt nhất để trình bày một nhấp được URL trong một QTableView (hoặc QTreeView, QListView, vv ...)Làm thế nào để mở một URL trong một QTableView

Cho một QStandardItemModel nơi một số các các cột chứa văn bản có URL tôi muốn chúng có thể nhấp và sau đó xử lý nhấp chuột bằng cách sử dụng QDesktopServices::openURL()

Tôi hy vọng sẽ có một số cách dễ dàng để tận dụng các cờ textInteraction của QLabel và nhồi nhét chúng vào bảng. Tôi không thể tin rằng không có cách nào dễ dàng hơn để xử lý việc này. Tôi thực sự hy vọng tôi đang thiếu một cái gì đó.

Trả lời

5

Bạn sẽ cần phải tạo một đại biểu để làm bức tranh. Mã nên tìm kiếm một cái gì đó như thế này:

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 , đây là cách duy nhất để vẽ các siêu liên kết trong một khung nhìn, và topicstarter muốn nhận ra, làm thế nào để tạo các liên kết có thể nhấp ở đó, mà không cần cắt một QTextBrowser vào mọi ô. –

+0

Tôi rất quan tâm, làm thế nào tôi có thể làm điều đó, quá, nếu bạn biết cách, xin vui lòng, cho chúng tôi biết, làm thế nào. –

+0

Sau đó, bạn cũng sẽ thực hiện lại QAbstractItemDelegate :: editorEvent() để nhận được các cú click chuột, và nếu bấm vào một liên kết, hãy dùng QDesktopServices :: openUrl() để mở URL. –

2

Vâng, bạn có thể sử dụng các đại biểu để làm rich text trong một qtableview với đại biểu tùy chỉnh reimplementing phương pháp sơn như:

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

Tuy nhiên, nó sẽ không làm cho siêu liên kết có thể nhấp được.

Để thực hiện việc này, bạn có thể sử dụng bản hack sau. Thực hiện lại phương thức setModel của khung nhìn bảng/danh sách của bạn và sử dụng 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); 
    } 
} 

Trong ví dụ trên, tôi thay thế cột 1 bằng qlabels. Lưu ý rằng bạn cần vô hiệu hóa vai trò hiển thị trong mô hình để tránh trùng lặp dữ liệu.

Dù sao, tôi sẽ quan tâm đến giải pháp tốt hơn dựa trên các đại biểu.

0

Rất tiếc, không dễ để hiển thị QLabel với setOpenExternalLinks() khi sử dụng QTableView (trái với việc sử dụng QTableWidget). Không có ma thuật hai dòng mã bạn có thể gọi và hoàn thành công việc.

  1. sử dụng một đại biểu
  2. thiết lập các đại biểu đến cột của bảng của bạn
  3. sử dụng QTextDocument kết hợp với setHTML() để render một liên kết html
  4. này nghĩa là mô hình của bạn cần phải cung cấp một đoạn HTML có chứa a href
  5. tính hình học của liên kết và cung cấp trình xử lý sự kiện để chặn chuột
    • thay đổi con trỏ khi nó kết thúc vào liên kết
    • thực hiện thao tác khi liên kết được nhấp
  6. gì một mớ hỗn độn :(tôi muốn 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(); 
}