Seite 1 von 1

Fragen zur Model-View-Programmierung

Verfasst: 1. April 2007 09:35
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?

Verfasst: 1. April 2007 19:16
von upsala
Das läßt sich leider nicht so ganz realisieren, da QWorkspace nur sehr wenig Informationen über seine enthaltenen Fenster rausgibt.

Verfasst: 1. April 2007 19:47
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...)

Verfasst: 1. April 2007 19:57
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.

Verfasst: 1. April 2007 20:11
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 :-/ .

Verfasst: 1. April 2007 20:45
von upsala
Verknüpf die Childs direkt mit deinem Model. Damit hast du mehr Erfolg.

Verfasst: 2. April 2007 09:42
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....

Verfasst: 5. April 2007 13:54
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.