Hi,
ich bin dabei ein kleines Programm in c++ mit Qt zu programmieren. Im
Wesentlichen soll es ein GUI-Aufsatz für ein Konsolenprogramm sein.
Mittels QProcess (welches intern Pipse benutzt) wird das externe
Konsolenprogramm gestartet. Danach kann mit write() eine Eingabe
getätigt werden. Um die Ausgabe des Programms abzufangen, habe ich den
Event "onReadyRead()" in einem entsprechenden Eventhandler abgefangen.
Das funktioniert auch: jedes mal, wenn das externe Konsolenprogramm
einen Wert ausgibt, wird onReadyRead() aufgerufen und ich kann meine
Daten zusammen sammeln.
Beispiel:
Wenn also mein externes Programm fertig ist, würde auf der Konsole in
stdout eine Liste von Files ausgegeben. Dies fange ich mit oben
gezeigtem Code ab und zerlege die Liste mit einem regulären Ausdruck.
Danach werden die einzelnen Teile in eine Map gefüllt. Wenn alles fertig
ist, dann wird der Event console_done() aufgerufen.
Denn ich möchte das GUI und die "Businesslogik" streng trennen. In
meiner GUI-Klasse würde ich dann mittels connect() einen Eventhandler
implementieren, welcher dann von emit aufgerufen wird. Und in diesem
Eventhandler möchte ich die Daten dann für die Präsentation im ListView
aufbereiten.
Bloss, wie wäre es klug, die Daten zu übergeben? soll der Handler die
Map als Referenz übernehmen, oder als Pointer (und die Map dann auf dem
Heap alloziieren mit new?). Ich möchte schlussendlich meine Daten mit
einem Model/View nsatz darstellen.
Könnt ihr mir da Ratschläge geben?
Kommt drauf an was du damit machen willst, die Map ist halt gut wenn du
Einträge zu einem bestimmten Wert finden musst, ansonsten ist ein Vektor
aus structs auch prima.
Ah, du würdest mit std::vector arbeiten?
spricht etwas gegen QList?
ich werde die Daten eh durchsuchen müssen, das Problem ist aber dass man
mal nach dem Titel sucht, mal nach dem Full Path. Dann nützt die Map
eher wenig.
Ich würde QVector nehmen, std::vector ist auch ok, wie du willst --
kommt ziemlich auf dasselbe raus. QList ist alt und schlecht und sollte
überhaupt gar nie wieder benutzt werden.
Sven B. schrieb:> Ich würde QVector nehmen, std::vector ist auch ok, wie du willst --> kommt ziemlich auf dasselbe raus.
Nein, std::vector ist etwas völlig anderes. Insbesondere ist der
Kopie-Konstruktor von std::vector mitunter sehr aufwändig, verglichen
mit den Qt-eigenen Containern.
std::vector wenn überhaupt, dann als Referenz. Da Referenzen nicht
thread-übergreifend im Signal/Slot übergeben werden können, eher
auto_ptr oder sowas. Also letztlich lieber QVector, der macht das
automatisch.
> QList ist alt und schlecht und sollte> überhaupt gar nie wieder benutzt werden.
Warum? QList ist nach wie vor die Standardliste.
Nesbit schrieb:> typedef struct> {> QString title;> QString fullpath;> } record;
typedef sieht in C++ immer komisch aus. Erstens brauchst du es hier
nicht und zweitens gibts bei Bedarf oft bessere Alternativen (using).
Verpack das Ding in eine kleine Klasse und gut ist.
Nase schrieb:> Sven B. schrieb:>> Ich würde QVector nehmen, std::vector ist auch ok, wie du willst -->> kommt ziemlich auf dasselbe raus.> Nein, std::vector ist etwas völlig anderes.
std::vector ist quasi genau dasselbe nur ohne das implicit sharing.
> Insbesondere ist der> Kopie-Konstruktor von std::vector mitunter sehr aufwändig, verglichen> mit den Qt-eigenen Containern.
Ja.
> std::vector wenn überhaupt, dann als Referenz.
Ja.
> eher auto_ptr oder sowas.
auto_ptr ist deprecated.
1
template <class X> class auto_ptr;
2
3
Automatic Pointer [deprecated]
>> QList ist alt und schlecht und sollte>> überhaupt gar nie wieder benutzt werden.> Warum? QList ist nach wie vor die Standardliste.
Nein, QList ist ein riesiger Murks und ich würde mal davon ausgehen dass
in der Qt-API in 6.0 alle QList durch QVector ersetzt und QList
vielleicht sogar deprecated wird.
Nimm einfach QVector. Es gibt keine Fall in dem du QList willst.
Nase schrieb:> typedef sieht in C++ immer komisch aus. Erstens brauchst du es hier> nicht und zweitens gibts bei Bedarf oft bessere Alternativen (using).
Ich frage mich schon länger, warum man jetzt using statt typedef
verwenden soll. Was ist daran besser, dass es die weniger intuitive
Syntax rechtfertigt?
Rolf Magnus schrieb:> Nase schrieb:>> typedef sieht in C++ immer komisch aus. Erstens brauchst du es hier>> nicht und zweitens gibts bei Bedarf oft bessere Alternativen (using).>> Ich frage mich schon länger, warum man jetzt using statt typedef> verwenden soll. Was ist daran besser, dass es die weniger intuitive> Syntax rechtfertigt?
Das using ist viel intuitiver, weil ich bei using T = U; sofort weiß
dass T der neue Typ ist und U der alte und bei typedef A B weiß ich nach
zehn Jahren immer noch nicht wie rum die Argumentreihenfolge ist :D
Rolf Magnus schrieb:> Nase schrieb:>> typedef sieht in C++ immer komisch aus. Erstens brauchst du es hier>> nicht und zweitens gibts bei Bedarf oft bessere Alternativen (using).>> Ich frage mich schon länger, warum man jetzt using statt typedef> verwenden soll. Was ist daran besser, dass es die weniger intuitive> Syntax rechtfertigt?
Weil using mit Templates kompatibel ist.
Sven B. schrieb:>>> QList ist alt und schlecht und sollte>>> überhaupt gar nie wieder benutzt werden.>> Warum? QList ist nach wie vor die Standardliste.> Nein, QList ist ein riesiger Murks und ich würde mal davon ausgehen dass> in der Qt-API in 6.0 alle QList durch QVector ersetzt und QList> vielleicht sogar deprecated wird.
Glaube ich nicht, ich denke das ist zu pauschal.
Grundsätzlich halte ich das Konzept, solch eine Brot-und-Butter-Liste
für alle Fälle zu haben, für garnicht so verkehrt. Effizient
programmieren bedeutet nämlich auch, effizient zum Ziel zu kommen.
Natürlich kann man quasi für jeden Anwendungsfall von QList eine bessere
Alternative finden. Dasselbe gilt aber für QVector/std::vector genauso.
Manchmal sind es z.B. speichersparendere Alternativen, manchmal
schnellere.
Für die 99% der Anwendungsfälle, wo das aber keinen Unterschied macht,
ist die "beste" Alternative m.M.n. aber tatsächlich ersteinmal die
universellste/intuitivste/naheliegendste/... Und das ist per Konvention
in Qt halt die QList. Sollte die mal Performanceprobleme machen, was ja
durchaus denkbar ist, kann man schließlich jederzeit noch optimieren und
etwas schnelleres/kleineres/... substituieren.
Und das:
> Nimm einfach QVector. Es gibt keine Fall in dem du QList willst.
ist, so finde ich, eben zu pauschal. Du sollst dir bei QList ja
explizit keine Gedanken darum machen, wie sie implementiert ist. Darum
gibt es ja auch keine Garantien über ihr Speicherlayout wie bei QVector
zum Beispiel. Oder eine Charakterisierung wie bei QLinkedList.
Nimm QList, wenn du eine Liste ohne besondere Ansprüche brauchst,
fertig.
Ich gebe dir aber vollumfänglich Recht darin, dass die aktuelle
Implementierung von QList nicht besonders gelungen ist. Aber wenn man
QList nimmt, meint man ja auch keine besondere Implementierung.
QList wird so schnell auch nicht verschwinden. Viel eher würde ich mir
wünschen, dass sie einfach besser implementiert wird. Man könnte sie
z.B. problemlos als QVector implementieren. Der Unterschied wäre dann
semantischer Natur, was ja völlig in Ordnung ist. Vielleicht kommt ja
irgendwann wieder eine andere Implementierung.
Mir gefällt QList einfach als Universalliste, solange man nichts anderes
braucht. Also explizit kein Vektor und keine verkettete Liste oder
sowas. Soll sie sich doch selbst aussuchen, wie sie sich am besten
implementiert.
Grundsätzlich hat Qt halt noch mehr solcher Relikte. Das ganze
Signal/Slot-Konzept mit Meta-Object-Compiler datiert noch aus einer
Zeit, wo Templates nicht so breit unterstützt wurden. Ebenfalls
historisch unbenutzt sind aktuelle Mechanismen wie expliziter Besitz
(unique_ptr, ...).
Nase schrieb:> Sven B. schrieb:>>>> QList ist alt und schlecht und sollte>>>> überhaupt gar nie wieder benutzt werden.>>> Warum? QList ist nach wie vor die Standardliste.>> Nein, QList ist ein riesiger Murks und ich würde mal davon ausgehen dass>> in der Qt-API in 6.0 alle QList durch QVector ersetzt und QList>> vielleicht sogar deprecated wird.> Glaube ich nicht, ich denke das ist zu pauschal.>> QList will not be Qt 6. Not in the current form. – Marc Mutz ->> mmutz Mar 1 '16 at 22:32
Naja, der Mensch will immer alles löschen, und ich finde das auch nicht
immer besonders gut, aber er hat einen gewissen Einfluss.
> Grundsätzlich halte ich das Konzept, solch eine Brot-und-Butter-Liste> für alle Fälle zu haben, für garnicht so verkehrt.
Ja, ich ja auch nicht, aber das ist QVector bzw. sollte QVector sein.
Nicht QList.
> Und das:>> Nimm einfach QVector. Es gibt keine Fall in dem du QList willst.> ist, so finde ich, eben zu pauschal. Du sollst dir bei QList ja> explizit keine Gedanken darum machen, wie sie implementiert ist. Darum> gibt es ja auch keine Garantien über ihr Speicherlayout wie bei QVector> zum Beispiel. Oder eine Charakterisierung wie bei QLinkedList.> Nimm QList, wenn du eine Liste ohne besondere Ansprüche brauchst,> fertig.
Nimm QVector, wenn du eine Liste ohne besondere Ansprüche brauchst,
fertig. Ist in 99% der Fälle wo du nicht darüber nachdenken willst
besser. Warum willst du unbedingt diese wirre QList haben -- nur weil
sie "list" im Namen hat? Der Vektor legt einfach alle Items
nebeneinander, das ist doch das einfachste was man sich vorstellen kann
...
> Grundsätzlich hat Qt halt noch mehr solcher Relikte. Das ganze> Signal/Slot-Konzept mit Meta-Object-Compiler datiert noch aus einer> Zeit, wo Templates nicht so breit unterstützt wurden.
Naja, das ist ja in Qt5 deutlich renoviert worden. Der moc macht auch
andere Sachen, und sparen könnte man den auch mit modernem C++ nicht.
Sven B. schrieb:> Rolf Magnus schrieb:>> Nase schrieb:>>> typedef sieht in C++ immer komisch aus. Erstens brauchst du es hier>>> nicht und zweitens gibts bei Bedarf oft bessere Alternativen (using).>>>> Ich frage mich schon länger, warum man jetzt using statt typedef>> verwenden soll. Was ist daran besser, dass es die weniger intuitive>> Syntax rechtfertigt?>> Das using ist viel intuitiver, weil ich bei using T = U; sofort weiß> dass T der neue Typ ist und U der alte und bei typedef A B weiß ich nach> zehn Jahren immer noch nicht wie rum die Argumentreihenfolge ist :D
Typedef ist das einfachste, was man sich da vorstellen kann, weil es
genau wie eine entsprechende Variablendefinition aussieht, nur eben mit
typedef davor:
1
intarray[5];// Ein Array aus 5 Integern
2
typedefintarray[5];// Ein neuer Name für den Typ "Array aus 5 Integern"
3
usingarray=int[5];// Ein "array" vom Typ using, das mit dem 5. Element von "int" initialisiert wird?
Vincent H. schrieb:>> Ich frage mich schon länger, warum man jetzt using statt typedef>> verwenden soll. Was ist daran besser, dass es die weniger intuitive>> Syntax rechtfertigt?>> Weil using mit Templates kompatibel ist.
Und typedef nicht?
Hallo
danke für die ausführlichen Antworten. Ich habe das jetzt entsprechend
implementiert und es funktioniert. Nun habe ich noch ein anderes
Qt-Problem,
ich hoffe ihr könnt mir da auch helfen. Und zwar möchte ich Elemente in
einem
TreeView darstellen. Dazu habe ich ein eigenes Datenmodel erstellt:
Für den booleschen Wert von einem breakpoint möchte ich eine Checkbox im
Treeview haben. Da ich gelesen habe, dass man hierzu einen Delegate
benötigt,
habe ich einen erstellt:
voidupdateEditorGeometry(QWidget*editor,constQStyleOptionViewItem&option,constQModelIndex&/* index */)const
33
{
34
editor->setGeometry(option.rect);
35
}
36
};
Das funktioniert auch so weit. Mein TreeView wird dargestellt und ich
kann die
Checkboxen toggeln. Was allerdings nicht geht: ich möchte als Text neben
jeder
Checkbox die Zeilennummer. Das mache ich hier:
editor->setText(QString(index.row()));
das hat aber nicht funktioniert, weshalb ich mal einen Teststring rein
gesetzt
habe. Hat auch nicht funktioniert. Dann habe ich mal ein in meinem
CheckboxDelegate
gedebuggt. Der Konstruktor wird aufgerufen; ich übergebe den Delegate
mit
treeview->setItemDelegateForColumn(0, mydelegate)
und dann wird aber in meinem Delegate überhaupt nie was aufgerufen. Ich
habe ihn
dann testweise mal entfernt, und die Checkboxen sind trotzdem da! d.h.
die
Checkboxen kommen vom Standard Datenmodell irgendwo her und mein
Delegate wird
gar nie ausgeführt. Was mache ich da falsch?
Du hast sehr viel Code gepostet, aber nicht den, wo du das Delegate
erzeugst und setzt, und ich denke das wäre der interessante Teil.
Warum ein eigenes Delegate, wenn der Treeview die Checkbox schon kann
als Editor?
Dass der TreeView die Checkbox schon von Haus aus kann wusste ich, aber
ich habe nicht herausgefunden wie. Dann habe ich gelesen, man brauche
dazu einen Delegate, und jetzt wo ich diesen erstellt habe, geht es
irgend auf eine magische Weise doch ohne :o
Sven B. schrieb:> Ja, ich ja auch nicht, aber das ist QVector bzw. sollte QVector sein.> Nicht QList.> [...]
Weiß ich nicht. Bei großen statischen Strukturen ist QVector eben
elendig ineffizient beim Einfügen in der Mitte usw.
QList ist halt ein Mittelweg a.k.a. Kompromiss. U.a. lag damals ja ein
Schwerpunkt darauf, dass QList zu möglichst wenig Code expandiert, und
das tut es letztlich ja auch.
Sven B. schrieb:> Naja, der Mensch will immer alles löschen, und ich finde das auch nicht> immer besonders gut, aber er hat einen gewissen Einfluss.
Er hat auch durchaus die rechtfertigenden Kompetenzen :-)
Sven B. schrieb:> Naja, das ist ja in Qt5 deutlich renoviert worden. Der moc macht auch> andere Sachen, und sparen könnte man den auch mit modernem C++ nicht.
Joa, man ist von der String-basierten Syntax weg.
Aber z.B. sig++ gibts ja nun auch schon ein paar Jährchen.
Rolf M. schrieb:> using array = int[5]; // Ein "array" vom Typ using, das mit dem 5.> Element von "int" initialisiert wird?
Böse Zungen behaupten C++ hätte überhaupt keine Grammatik ;-)