Mehere Tabellen und Models, Selection?

Alles rund um die Programmierung mit Qt
Antworten
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Mehere Tabellen und Models, Selection?

Beitrag von gast23 »

Hi,

ich habe 5 Tabellen und ein Model. Jede Tabelle hat ein Proxymodel auf das eigentliche Model.

Es darf immer nur eine Tabelle selektiert sein (Also eine Row). Dies habe ich per Code durch Deselection gelößt. D.h. wenn in einer Tabelle etwas selektiert wird werden alle andern auf -1 gesetzt.

Nun ist die Frage wie kann ich an die Selection im eigentlich Ausgangsmodel kommen? (Row Index reicht).

Viele Grüße
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Der Workaround:
In den Proxymodels werden die aktzeptierten SrcRows in einer Liste gespeichert (Jede Row ist in meinem Fall eindeutig einem ProxyModel zugeordnet).

Anhand einer Selection und den Tabellen kann ich dann mit Hilfe der SrcRows Liste die eigentliche Row des orginal Models erhalten :)
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

http://doc.trolltech.com/4.3/qabstractproxymodel.html
virtual QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const = 0

virtual QItemSelection mapSelectionFromSource ( const QItemSelection & sourceSelection ) const

virtual QItemSelection mapSelectionToSource ( const QItemSelection & proxySelection ) const

virtual QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const = 0
?
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Oh hab ich überlesen :D

Danke!

mapToSource(table->currentIndex());

Ist das so gedacht?
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

wenn table dein view ist, ja.
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Direkt über die Models hat man aber keine Selection odeR?
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Wie wäre es wenn du selbst in die API schaust ....

http://doc.trolltech.com/4.6/model-view ... mming.html

http://doc.trolltech.com/4.6/qabstractitemview.html && abgeleitete Klassen
http://doc.trolltech.com/4.6/qabstractproxymodel.html && abgeleitete Klasse(n)
http://doc.trolltech.com/4.6/qitemselectionmodel.html

Model und View sind getrennt. Hast du ein Proxymodel dazwischen fungiert das als intermediäres Model.
View -> Proxy -> Model
Im View hast du die Möglichkeit zu Selektieren ... da kannst du auch vorgeben wie (Spalte, ganze Row, ... & garnicht, einzeln, durchgehend oder willkürliche Selektion -> propertys QAbstractItemView).

Dann hat jede die View ein QItemSelectionModel das du mit .selectionModel() bekommst. Das hat verschiedene Methoden mit der du zB die currentSelection oder eine Liste von selektierten Columns, Indexes oder Rows bekommst ... als QModelIndexList. Das sind Indexe im View (und imho das selbe wie die Indexe in dessen Model). Proxy models können umindizieren - je nach zB Filterung usw - daher sind die nicht identisch mit Indexen aus dem Model). Daher steckste die in die Methoden vom Proxymodel reins um sie in QModelIndexe in deinem Model zu wandeln ...

zB:

Code: Alles auswählen

 
View:       Proxy:       Model:
A             A               A
  aa            aa             aa
  b              b               ab
                                   b
Filter Regexp: (A,aa,b)

das b hat nun unterschiedliche Indexe im Model gegebüber der View da das Proxy vom Model was versteckt ... A und aa sind identisch ...
b nicht da das Proxy das "umsortiert".

Schau mal in den Link über Model/View ... http://doc.trolltech.com/4.6/model-view ... ween-views da ist auch eins mit Selection drin .. du kannst nämlich auch EIN Selection Modell für mehrereViews setzen ... dann würde sich das "Ich habe das gelöst mit Deselektierung" von alleine Lösen wenn du deine views auf ROW + SINGLE selektion primst. Wenn deine Views paarweise Verschieden sind würde sich sobald du woanders was selektierst die alte Selektion verschwinden. Sollten deine 5 Views sich überschneiden, siehst du die Selektion überall dort wo der entsprechende ModelIndex präsent ist ...
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Hm ich habe das ja gelesen und nicht probiert weil ich mir dachte das es nicht funktioniert:

Wenn ich jeder Tabelle außer der ersten das Selektionmodel gebe, erhalte ich diese Meldung:

"QAbstractItemView::setSelectionModel() failed: Trying to set a selection model, which works on a different model than the view."

Code: Alles auswählen

currenttable->setSelectionModel(alltables.at(0)->selectionModel());
Jede Tabelle hat ihr eigenes Proxymodel welches das Srcmodel filtert.

Muss man die Proxys noch verbinden?

Danke aber schonmal :)
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Ich habs "grad mal" nachgebaut. Die Proxys scheinen da zu blocken. Du könntest versuchen den Proxy und das Model abzuleiten und die Selection aus dem View ins Proxy ins Model zu schicken ... aber das führt irgendwie Model/View ad absurdum. Sorry, ich hab mal ins blaue Vermutetet das das so tut und nu tuts doch nicht.

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QtGui/QSortFilterProxyModel>


class mySFPM : public QSortFilterProxyModel {
    Q_OBJECT
public:
    mySFPM ( QObject * parent = 0 ) : QSortFilterProxyModel(parent) {}
protected:
    bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const;
};


class QFileSystemModel;
class QTreeView;

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void setSelection(const QItemSelection & current);

private:
    QFileSystemModel * model;
    QTreeView *t1, *t2;
    QSortFilterProxyModel *p1, *p2;
};

#endif // MAINWINDOW_H

Code: Alles auswählen

#include "mainwindow.h"

#include <QtGui/QLineEdit>
#include <QtGui/QGridLayout>
#include <QtGui/QTreeView>
#include <QtGui/QFileSystemModel>
#include <QtGui/QItemSelectionModel>
#include <QDebug>

bool mySFPM::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    QFileSystemModel * fsmp = qobject_cast<QFileSystemModel*>(sourceModel());

    if (fsmp)
    {
        if (fsmp->isDir(sourceModel()->index(sourceRow,0,sourceParent)))
        {
            return true;
        }
        else
        {
            QString data = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).toString();
            return data.contains(filterRegExp());
        }
    }
    return false;
}


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QWidget * w = new QWidget;
    model = new QFileSystemModel(this);

    p1 = new mySFPM(this);
    p2 = new mySFPM(this);

    t1 = new QTreeView(this);
    t2 = new QTreeView(this);

    QLineEdit * l1 = new QLineEdit(this);
    QLineEdit * l2 = new QLineEdit(this);

    connect (l1,SIGNAL(textChanged(QString)),p1,SLOT(setFilterRegExp(QString)));
    connect (l2,SIGNAL(textChanged(QString)),p2,SLOT(setFilterRegExp(QString)));

    model->setRootPath(QDir::homePath());

    p1->setSourceModel(model);
    p2->setSourceModel(model);


    // das tut {
    //     t1->setModel(model);
    //     t2->setModel(model);
    //     t2->setSelectionModel(t1->selectionModel());
    // }


    // so gehts nicht ...  {
        t1->setModel(p1);
        t2->setModel(p2);
         connect (t1->selectionModel(),SIGNAL(selectionChanged(QItemSelection,QItemSelection)),SLOT(setSelection(QItemSelection)));
        connect (t2->selectionModel(),SIGNAL(selectionChanged(QItemSelection,QItemSelection)),SLOT(setSelection(QItemSelection)));
    // }

    QGridLayout * g = new QGridLayout;
    g->addWidget(t1,1,1);
    g->addWidget(t2,1,2);
    g->addWidget(l1,2,1);
    g->addWidget(l2,2,2);
    w->setLayout(g);
    setCentralWidget(w);
}

void MainWindow::setSelection(const QItemSelection & current)
{
    if (sender() == t1->selectionModel())
    {
        t2->selectionModel()->select(
                p2->mapSelectionToSource(
                        p1->mapSelectionFromSource(t1->selectionModel()->selection()
                                                   )
                        )
                ,QItemSelectionModel::ClearAndSelect);
        return;
    }

    t1->selectionModel()->select(
            p1->mapSelectionToSource(
                    p2->mapSelectionFromSource(t2->selectionModel()->selection()
                                               )
                    )
            ,QItemSelectionModel::ClearAndSelect);
    
    
}

MainWindow::~MainWindow()
{
}
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
gast23
Beiträge: 103
Registriert: 11. August 2010 10:43

Beitrag von gast23 »

Ich lass es erstmal so. Ist eh nur ein Prototyp :)
Danke jedoch für den mapToSrc hinweis.
Antworten