2010-05-07 6 views
3

J'utilise QTableView et QStandardItemModel pour afficher certaines données.Comment interagir avec les actions de case à cocher? (QTableView avec QStandardItemModel)

Pour chaque ligne, il y a une colonne qui a une case à cocher, cette case à cocher est insérée par setItem, le code est le suivant:

int rowNum; 
QStandardItemModel *tableModel; 
QStandardItem* __tmpItem = new QStandardItem(); 

__tmpItem->setCheckable(true); 
__tmpItem->setCheckState(Qt::Unchecked); 

tableModel->setItem(rowNum,0,__tmpItem); 

Maintenant, je veux interagir avec la case à cocher. Si une case à cocher change d'état par utilisateur (de cochée à non cochée ou vice versa), je veux faire quelque chose sur la ligne de données correspondante. Je sais que je peux utiliser le slot de signal pour attraper le changement de case à cocher, mais comme il y a beaucoup de ligne de données, je ne veux pas connecter chaque ligne une par une.

Est-il possible d'interagir avec l'action de vérification de manière plus efficace? Merci :)

Répondre

3

gérer l'événement de clic, il vous obtiendrez le modelindex, obtenir les données et modifier la même

si vous allez insérer plus d'un texte ou d'une icône, vous devez définir le délégué pour votre listview

+0

Merci beaucoup, Cela fonctionne sans utiliser QItemDelegate !!! : D J'ai juste besoin d'ajouter une fente et tout fonctionne, c'est génial !! –

4

Je ne traite pas avec QTableView + QStandardItemModel, mais peut-être par exemple ci-dessous vous aidera à:

1). fichier table.h:

#ifndef TABLE__H 
#define TABLE__H 

#include <QtGui> 

class ItemDelegate : public QItemDelegate 
{ 
public: 
    ItemDelegate(QObject *parent = 0) 
     : QItemDelegate(parent) 
    { 
    } 
    virtual void drawCheck(QPainter *painter, const QStyleOptionViewItem &option, 
     const QRect &, Qt::CheckState state) const 
    { 
     const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; 

     QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, 
      check(option, option.rect, Qt::Checked).size(), 
      QRect(option.rect.x() + textMargin, option.rect.y(), 
      option.rect.width() - (textMargin * 2), option.rect.height())); 
     QItemDelegate::drawCheck(painter, option, checkRect, state); 
    } 
    virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, 
     const QModelIndex &index) 
    { 
     Q_ASSERT(event); 
     Q_ASSERT(model); 

     // make sure that the item is checkable 
     Qt::ItemFlags flags = model->flags(index); 
     if (!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled)) 
      return false; 
     // make sure that we have a check state 
     QVariant value = index.data(Qt::CheckStateRole); 
     if (!value.isValid()) 
      return false; 
     // make sure that we have the right event type 
     if (event->type() == QEvent::MouseButtonRelease) { 
      const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; 
      QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, 
       check(option, option.rect, Qt::Checked).size(), 
       QRect(option.rect.x() + textMargin, option.rect.y(), 
       option.rect.width() - (2 * textMargin), option.rect.height())); 
      if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos())) 
       return false; 
     } else if (event->type() == QEvent::KeyPress) { 
      if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space 
       && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select) 
       return false; 
     } else { 
      return false; 
     } 
     Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked 
      ? Qt::Unchecked : Qt::Checked); 

     QMessageBox::information(0, 
      QString((state == Qt::Checked) ? "Qt::Checked" : "Qt::Unchecked"), 
      QString("[%1/%2]").arg(index.row()).arg(index.column())); 

     return model->setData(index, state, Qt::CheckStateRole); 
    } 
    virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const 
    { 
     QItemDelegate::drawFocus(painter, option, option.rect); 
    } 
}; 


static int ROWS = 3; 
static int COLS = 1; 
class Table : public QTableWidget 
{ 
    Q_OBJECT 
public: 
    Table(QWidget *parent = 0) 
     : QTableWidget(ROWS, COLS, parent) 
    { 
     setItemDelegate(new ItemDelegate(this)); 
     QTableWidgetItem *item = 0; 
     for (int i=0; i<rowCount(); ++i) { 
      for (int j=0; j<columnCount(); ++j) { 
       setItem(i, j, item = new QTableWidgetItem); 
       item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable); 
       item->setCheckState((i+j) % 2 == 0 ? Qt::Checked : Qt::Unchecked); 
      } 
     } 
    } 
}; 

#endif 

2). fichier main.cpp:

#include <QApplication> 

#include "table.h" 

int main(int argc, char **argv) 
{ 
    QApplication a(argc, argv); 
    Table w; 
    w.show(); 
    return a.exec(); 
} 

Bonne chance. PS: voici le text original.

+0

Merci beaucoup! Cela fonctionne: D ~ \ n Cependant, de cette façon, chaque élément de la vue de table contiendra une case à cocher, si je veux juste que la case à cocher apparaisse dans certaines colonnes spécifiques, quelle partie je dois modifier ?? Merci encore, cet exemple est vraiment utile: D –

+0

@Claire Huang Vous pouvez éditer * Table * classe pour gagner des cases à cocher dans une colonne sélectionnée, par exemple: pour (...) pour (...) { setItem (...); if (j == mySelectedColumn) élément-> setFlags (Qt :: ItemIsEnabled | Qt :: ItemIsUserCheckable); else item-> setFlags (Qt :: ItemIsEnabled); } ... etc Je pense quelque chose comme ça. :) – mosg

Questions connexes