qT: Dynamisches Gridlayout?



  • Ich wage mich zum erstem mal an c++ Programme mit interface ran. Meine Wahl ist auf qT gefallen, und dazu benutze ich auch gleich die qT Creator IDE.

    Die theorie von dem ganzen hab ich verstanden, und einfache programme erstellen klappt.

    Jetzt benötige ich aber folgendes:
    Auf drücken eines shortcuts öffnet sich ein dialog.
    In diesem dialog sollte ein Gridlayout mit z.b. 20 zellen sein (alle gleich groß)
    [0][0][0][0][0][0][0][0][0][0]
    [0][0][0][0][0][0][0][0][0][0]
    (in dieser anordnung)

    Anfangs ist in jedem element eine leere (oder mit spez. bild) picturebox.
    Auf bestimmte aktionen hin, werden die boxen gefüllt. (und zwar nach einem stapelprinzip)
    [Die Daten werden erst in ein Array eingetragen, und daraufhin soll für jedes element eine box gefüllt werden]

    das könnte z.b. dann mal so aussehen:

    [1][2][3][4][5][6][7][8][9][0]
    [0][0][0][0][0][0][0][0][0][0]

    Es kommt aber vor dass ein eintrag gelöscht werden soll, z.b. eintrag 5

    [1][2][3][4][0][6][7][8][9][0]
    [0][0][0][0][0][0][0][0][0][0]

    Jetzt sollte das aber nicht aussehen wie hier, sondern die nächsten sollten aufrutschen, und den platz von 5 einnehmen.
    SO:
    [1][2][3][4][5][6][7][8][0][0]
    [0][0][0][0][0][0][0][0][0][0]

    Von der theorie her, müsste ich also beim löschen eines elements, alle folgenden elemente eins nach links verschieben.
    Wenn ich allerdings 20 elemente habe, und element 2 oder so rausnehme, würden 17 elemente verschoben werden (neuzuweisung der pictureboxen)
    Das ganze scheint mir aber recht ressourcenintensiv zu sein, und ich befürchte dass wartezeiten entstehen. Gibt es eine bessere lösung?
    Wie stark verbessert/schlechtert sich die performance, wenn ich statt zu berechnen welche boxen wieviel verschoben werden müssen, sämtliche boxen neu zuweise?
    Oder gibt es eine Möglichkeit, das Array mit den Boxen zu verknüpfen, sodass jede Box IMMER ihr entsprechendes element des arrays benutzt, auch wenn das array bearbeitet wird?

    vielen Dank schonmal, ich hoffe es ist klar was ich will 😉

    Screeze

    P.s.: zusatzfrage: muss eigentlich auf dem pc auf dem ein qT programm läuft etwas bestimmtes installiert sein, oder ist alles was benötigt wird im programm enthalten?



  • Ich glaube nicht dass du eine andere Möglichkeit hast, als alle nachfolgenden Boxen so zu verschieben, bis dir die Reihenfolge wieder passt.
    Wie das performance-mäßig aussieht kann ich dir nicht sagen, müsstest du einfach mal ausprobieren.

    Wenn du Qt statisch gelinkt hast, musst du mit deinem Programm überhaupt nichts zusätzliches mehr ausliefern. Statisches Linken ist allerdings nicht zu empfehlen, da dadurch erstens dein eigentliches Programm ziemlich "übergewichtig" wird, und zweitens meist auch Lizenz-technische Probleme auftreten (LGPL/GPL).

    Die weitaus bessere Lösung ist es also, dynamisch zu linken (standardmäßig wird Qt sowieso für dynamisches Linken kompiliert). Du musst dann allerdings die von deinem Programm benutzten Qt DLLs mitliefern. Welche das sind, findest du am besten mit dem Dependency Walker heraus.

    Nachlesen kannst du dazu noch das wichtigste hier:

    http://doc.qtsoftware.com/4.5/deployment.html



  • Hmm ok danke, ich wollts schon versuchen, aber ich scheitere schon an der verwendung der GraphicsView.

    Ich habe neben der MainForm noch ein Dialog, welcher mit dem programm öffnet.
    In dem dialog sind einige GraphicsViews.

    ich hab einen einfach mal test genannt.

    Nur... wie übergeb ich der graphicsview ein bild??
    und wo?

    Ich habs im constructor der dialog Form versucht, hab schon etliche codes ausm netz versucht, aber leider find ich nirgends einen gut beschriebenen zu dem thema.
    Ich hatte es immer nach der zeile

    m_ui->setupUi(this);
    

    versucht, mit irgendwas

    m_ui->test->...
    

    mäßigem.
    Ich habe es weder geschafft ein Bild noch ein rechteck o.ä. in die box zu bekommen. Könnte mir das einer erklären? (oder ein link zu nem tutorial geben)
    Danke



  • Screeze schrieb:

    Nur... wie übergeb ich der graphicsview ein bild??
    und wo?

    In einem QGraphicsView kannst du eine "scene" anzeigen lassen.
    http://doc.qtsoftware.com/4.5/qgraphicsview.html#setScene

    Und in dieser "scene" kannst du wiederum alles mögliche zeichnen, hinein malen, usw..
    http://doc.qtsoftware.com/4.5/qgraphicsscene.html



  • ok, und ist der weg, wie ich auf meinen graphviewer zugreife richtig? scheint mir irgendwie nicht so, da ich auch schon mit scenes ect. gearbeitet habe, es aber nichts geändert hatte.



  • Also laut dem was ich gelesen habe, müsste doch dann dieser code funktionieren (nur mal um schrift in die box zu schreiben)

    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        m_ui(new Ui::Dialog)
    {
    
        m_ui->setupUi(this);
    
        QGraphicsScene scene;
        scene.addText("GraphicsView rotated clockwise");
    
        m_ui->test->setScene(&scene);
        m_ui->test->rotate(90); // the text is rendered with a 90 degree clockwise rotation
        m_ui->test->show();
    }
    

    Leider wird nichts angezeigt in der test-box. hab ich was falsch verstanden?



  • Das Problem in deinem Code ist, dass du deine "scene" Variable auf dem Stack anlegst, dadurch wird sie schon am Ende deiner Dialog::Dialog() Funktion wieder zerstört und folglich kann nichts mehr angezeigt werden.

    Prinzipiell ist es bei Qt eigentlich nie ein Fehler, so gut wie alle Qt-Objekte auf dem Heap anzulegen, also dynamisch. Qt ist schließlich in der Lage den für die Objekte dynamisch allokierten Speicher selber wieder frei zu geben sobald sie nicht mehr gebraucht werden.

    Was du versuchst, sollte verallgemeinert ungefähr so funktionieren:

    QGraphicsScene *graphicsScene = new QGraphicsScene(this);
    graphicsScene->addText("Some text to be displayed...");
    
    QGraphicsView *graphicsView = new QGraphicsView(this);
    graphicsView->setScene(graphicsScene);
    


  • vielen dank, dass war der entscheidende hinweis. Damit komm ich denk ich weiter, danke!


Anmelden zum Antworten