Fragen zur Model-View-Programmierung

Alles rund um die Programmierung mit Qt
Antworten
Brownie
Beiträge: 15
Registriert: 2. März 2007 10:40

Fragen zur Model-View-Programmierung

Beitrag von Brownie »

Hallo,

ich habe ein paar Fragen zur Umsetzung vom Model-View-Konzept in QT.
Und zwar habe ich ein Programm, dass einen QWorkspace zur Verwaltung von Editorfenstern besitzt.

Nun möchte ich die Namen der Editorfenster als Liste in einem Fenster darstellen und dort auch die Möglichkeit anbieten z.B. die Namen der Workspace-Editorfenster direkt zu ändern.

Wenn ich das Ganze nun als QListView umsetze, kann ich ja die Fensterliste des workspaces mit Verweis auf die Originaldaten in ein Model packen und über Delegates usw. eine Editiermöglichkeit anbieten.

Meine Frage wäre jetzt, ob ich nun nur noch auf dem Modell der Workspace-Fensterliste operieren darf oder ob es auch möglich ist, dem Modell quasi zu sagen, dass sich seine Daten geändert haben (Wenn ja, wie? ), so dass ich normal mit dem workspace weiterarbeiten und z.B. mit addWindow Fenster hinzufügen kann. Vielleicht hat ja auch noch jemand eine ganz andere bessere Lösung?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Das läßt sich leider nicht so ganz realisieren, da QWorkspace nur sehr wenig Informationen über seine enthaltenen Fenster rausgibt.
Brownie
Beiträge: 15
Registriert: 2. März 2007 10:40

Beitrag von Brownie »

Also kann ich das Problem nicht vernünftig mit QListView und dem Model-View-Kram lösen?
Ist die Alternative dann, zu versuchen, das Ganze in ein QListWidget zu packen und halt mittels Signals und Slots zu versuchen alles synchron zu halten?

@upsala: Welche Informationen fehlen eigentlich aus deiner Sicht?

(Bin um jeden Tipp dankbar, da QT für mich noch neu ist...)
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Änderungen von windowTitle, windowIcon. Keine Information darüber welches Widget hinzugefügt bzw. entfernt wurde.

QListWidget ist nichts anderes als eine QListView mit einem Model.
Brownie
Beiträge: 15
Registriert: 2. März 2007 10:40

Beitrag von Brownie »

hmm, aber wie macht man es dann besser ? sollte ich mir statt dem workspace von QT lieber etwas eigenes schreiben?

Also irgendwie muss das doch halbwegs geschickt zu lösen sein...

Momentan probiere ich gerade mit einer von QListWidget abgeleiteten Klasse rum, wo ich den workspace als Membervariable mitgespeichert habe und beim Hinzufügen von Fenstern zum workspace halt per Slot ein Update der Liste mache, aber gut ist das ja irgendwie net gerade :-/ .
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Verknüpf die Childs direkt mit deinem Model. Damit hast du mehr Erfolg.
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

Brownie hat geschrieben:hmm, aber wie macht man es dann besser ? sollte ich mir statt dem workspace von QT lieber etwas eigenes schreiben?

Also irgendwie muss das doch halbwegs geschickt zu lösen sein...

Momentan probiere ich gerade mit einer von QListWidget abgeleiteten Klasse rum, wo ich den workspace als Membervariable mitgespeichert habe und beim Hinzufügen von Fenstern zum workspace halt per Slot ein Update der Liste mache, aber gut ist das ja irgendwie net gerade :-/ .

In der mainwindow deklariere
QList<Edit_Member *> userpages;
eine liste der QWidget class die in den QWorkspace *workspace; hinzukommen.... in den einzelne QWidget machst du eine nummer oder namen id die man jederzeit abrufen kann ... um zu sehen ob es offen ist... aktiv oder gueltig.

So kann man beim hinzufuegen sehen ob es nicht bereits offen ist ....
wenn ja in den vordergrund stellen ....

Code: Alles auswählen

void Gui_Main::RegisterPanelMember( int whereid  )
{
    bool alreadyOpen = false;
    if (!db->CheckUser(whereid)) {
    QMessageBox::warning(this, tr("Table error...."),tr("User id %1 not valid!").arg(whereid));
    return;
    } else {
      
     for (int i = 0; i < userpages.size(); ++i) {
           alreadyOpen = userpages[i]->WorkYou(whereid); 
           if (alreadyOpen) {
               workspace->cascade();   /* zeige widget im tree */
               workspace->setActiveWindow(userpages[i]);  /* zeige in vordergrund  wenn aktiv ... */
               return;
           }
     }
        
    if (db->Active() and !alreadyOpen) {    /* noch nicht offen != */
     Edit_Member *userpage = new Edit_Member(db->currentDatabase(),whereid);
     workspace->addWindow(userpage);
     userpage->show();
     userpage->showMaximized();
     userpages.append(userpage);
    connect(userpage, SIGNAL(UpdateRequest(QString,QString)),db, SLOT(UpdateQuery(QString,QString)));
    connect(userpage, SIGNAL(FluhClose(int)),this, SLOT(RemoveGui(int)));
    connect(userpage, SIGNAL(CleanDBUserFile(int)),db, SLOT(RemoveFileDB(int)));
    connect(userpage, SIGNAL(TakeZip(QString,int)),db, SLOT(PackTakeZip(QString,int)));
    }
      
    return;
    }
}

die einzelne widget mussen ein close event haben ... wenn der user sie schleisst .... sendet er ein signal um die id XX aus der mainwindow zu loeschen.....

Code: Alles auswählen


void Edit_Member::closeEvent( QCloseEvent* e )
{
    DownDir_RM(USERTMPDIR);   /* andere aufraumarbeiten */
    emit FluhClose(ids);
	return;
}
und in der mainwindow der geschlossene rauswerfen ....

Code: Alles auswählen

void Gui_Main::RemoveGui( int whereid  )
{
    bool alreadyOpen = false;
    for (int i = 0; i < userpages.size(); ++i) {
           alreadyOpen = userpages[i]->WorkYou(whereid); 
           if (alreadyOpen) {
              delete  userpages[i];
              userpages.removeAt(i);
               return;
           }
     }
}

nun kann man sich mit der liste wen widget eine darstellung machen als combobox oder sonst ne liste wie man will .... und man kann auf jedes child zugreifen wie mann will....


ich habe mir ein table model gemacht mit einen qmenu... auf colonne 0, mit der liste.. die mann sogar editieren kann...

Code: Alles auswählen

QWidget *BaseDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
     if (index.column() == 11 || index.column() == 7 ) {
        QDateTimeEdit *editor = new QDateTimeEdit(parent);
        editor->setDisplayFormat("dd.MM.yyyy");
        editor->setCalendarPopup(true);
        return editor;
     } else if (index.column() == 0) {
        Base_Button *editora = new Base_Button(parent);
        connect( editora , SIGNAL(OpenItem(int)), this , SLOT(Omodusa(int)));
        connect( editora , SIGNAL(OpenItemb(int)), this , SLOT(Omodusb(int)));
         connect( editora , SIGNAL(OpenItemc(int)), this , SLOT(Omodusc(int)));
         connect( editora , SIGNAL(OpenItemd(int)), this , SLOT(Omodusd(int)));
         connect( editora , SIGNAL(OpenIteme(int)), this , SLOT(Omoduse(int)));
        return editora;
     }  else {
        return QItemDelegate::createEditor(parent, option, index);
    }
}
Base_Button ist nichts ander als ein QWidget mit einem QPushButton setFlat(true); so bekommt die kolonne 0 einen QMenu....

so das ich die untere child auf meherere methoden zugrefinen kann...


Anders geht es sicher auch ... ob komplizierter oder einfacher musst du entscheiden....
.........................
speack português italiano deutsch english castellà qt
Brownie
Beiträge: 15
Registriert: 2. März 2007 10:40

Beitrag von Brownie »

@patrik08: Vielen Dank noch für deine ausführliche Antwort!

Ich habe das Ganze jetzt noch etwas anders gelöst gehabt und nicht direkt die windowList() vom Workspace genommen, sondern mir meine eigene Projektstruktur geschrieben, was noch einige andere Vorteile mit sich brachte.
Antworten