2016-07-28 3 views
1

J'essaye d'obtenir le listview et la tableview fonctionnant ensemble.Comment définir la source de données d'une vue de liste pour qu'elle contienne des données personnalisées? (et associer avec QTableView)

La liste doit être utilisée pour l'affichage, la vue de table doit être utilisée pour éditer les données. La vue de table est créée à la demande dans un widget contextuel (et elle peut ne jamais être nécessaire).

Je remplis la liste, au démarrage, à partir d'un fichier texte - chaque ligne une ligne, avec 2 entrées séparées par un onglet. Facile.

Le tableview devra modifier 2 colonnes séparément ... aussi, le clic listview, je dois être en mesure de récupérer la première partie de la scission ...

J'ai créé une sous-classe de modèle de QStringListModel.

QListView *m_myView = new QListView(); 
StringList *m_myList = new StringList(); 
QTextStream in(&myFile); 
while (!in.atEnd()) 
{ 
    QString temp = in.readLine(); 
    if(!temp.isEmpty()) 
     m_myList->append(temp); 
} 
myFile.close(); 
m_myView->setModel(m_myList); 

class StringList : public QStringListModel 
{ 
public: 
    void append (const QString& string) 
    { 
     insertRows(rowCount(), 1); 
     QModelIndex m = index(rowCount() - 1); 
     setData(m, string, Qt::EditRole); 
     QStringList splist = string.split('\t'); 
     setData(m, splist.at(0), Qt::ToolTipRole); 
     if(splist.size() > 1) 
      setData(m, splist.at(1), Qt::StatusTipRole); 
     else 
      setData(m, "", Qt::StatusTipRole); 

     qDebug() << data(m, Qt::EditRole).toString() 
       << data(m, Qt::ToolTipRole).toString() 
       << data(m, Qt::StatusTipRole).toString(); 
    } 
}; 

Les EditRole affiche correctement, les autres affichent des chaînes vides.

Il semble que QStringListModel est incapable de stocker quoi que ce soit sauf EditRole.

Donc je me retrouve avec 2 options - soit faire la division sur chaque sélection, et aussi lors de la création de la vue de table, ou - ce que je voudrais essayer mais je ne sais pas comment - créer un QStandardItemModel qui peut agir comme sources de données à la fois pour la vue de liste et la vue de table, et peut facilement récupérer les données partielles dont j'ai besoin lors d'un clic.

Je pensais que je peux simplement l'utiliser pour définir les données sur listview (comme ils le font here).

QListView *m_myView = new QListView(); 
QStandardItemModel *m_myList = new QStandardItemModel(); 
QTextStream in(&myFile); 
int r = 0; 
while (!in.atEnd()) 
{ 
    QString temp = in.readLine(); 
    if(!temp.isEmpty()) 
    { 
     QStringList splist = temp.split('\t'); // assume I know there will be 2 strings always 
     QStandardItem *item = new QStandardItem(splist.at(0)); 
     m_myList->setItem(r, 0, item); 
     QStandardItem *item1 = new QStandardItem(splist.at(1)); 
     m_myList->setItem(r, 1, item1); 
     ++r; 
    } 
} 
myFile.close(); 
m_myView->setModel(m_myList); 

connect(m_myListView, SIGNAL(clicked(QModelIndex)), 
     this, SLOT(listChangedSlot(QModelIndex))); 

Mais cela met à jour la première chaîne de la listview, j'ai vraiment besoin à la fois, et je ne sais toujours pas comment récupérer les données

void listChangedSlot(QModelIndex index) 
{ 
    qDebug() << m_myList->item(index.row(), 0)->data().toString() 
      << m_myList->item(index.row(), 1)->data().toString(); 
} // shows empty strings 

Ou ...
En la section de chargement, essayez:

if(!temp.isEmpty()) 
    { 
     QStringList splist = temp.split('\t'); 
     splist.append(QString()); // so I don't need to test 
     QStandardItem *item = new QStandardItem(temp); 
     m_myList->setItem(r, 0, item); 
     QModelIndex idx = m_myList->index(r, 0); 
     QMap<int, QVariant> roles; 
     roles.insert(Qt::UserRole + 1, QVariant(splist.at(0))); 
     roles.insert(Qt::UserRole + 2, QVariant(splist.at(1))); 
     roles.insert(Qt::DisplayRole, QVariant(temp)); 
     m_myList->setItemData(idx, roles); 
     ++r; 
    } 

Cela fonctionne - affiche bien et obtient le contenu correct sur clic - mais semble être inutilisable pour la tableview.
(Et semble que je fais deux fois le travail, avec setItem et setItemData - si techniquement stocker le contenu 3 fois).

Comment puis-je faire en sorte que ma visionneuse possède une source de données avec 2 éléments de chaîne, afficher les deux, être en mesure de la définir sur une vue de table et être capable de récupérer le premier élément lors du clic?

Répondre

0

I trouvé un moyen pour partager la source de données entre le listview et tableview:

créer des colonnes 3 - 0 colonne avec les composants combinés, et les colonnes 1 et 2 avec les composants séparés.

ListView affiche colonne seulement 0. Pour tableview, je cacherai la colonne 0.

Les données dont j'ai besoin pour le traitement seront stockées dans les colonnes 1 et 2.l'édition par l'utilisateur des données dans tableview nécessitera, lors de l'acceptation des modifications, l'édition de la colonne correspondante 0.