{"id":198,"date":"2019-01-18T08:34:32","date_gmt":"2019-01-18T08:34:32","guid":{"rendered":"http:\/\/devblog.cssec.de\/?p=198"},"modified":"2026-01-26T13:17:30","modified_gmt":"2026-01-26T13:17:30","slug":"signals-einfacher-mit-qt-creator","status":"publish","type":"post","link":"https:\/\/www.cssec.de\/blog\/2019\/01\/18\/signals-einfacher-mit-qt-creator\/","title":{"rendered":"Signals einfacher mit QT-Creator"},"content":{"rendered":"<p>Heute mal seit langer Zeit wieder ein l\u00e4ngerer Beitrag mit einem kleineren Tutorial.<\/p>\n<p>Aktuell bin ich mal wieder dabei eine Qt-(Desktop)-Anwendung f\u00fcr einen Kunden zu erstellen, mal wieder ganz von Null auf, inkl. Analyse, Wireframe-Konzept, Klickdummy, Umsetzung, Dokumentation und Test.<\/p>\n<p>Bis auf Nutzung als C++-Editor habe ich im Qt-Creator lange Zeit nichts mehr mit Oberfl\u00e4chen-\/Formularen entwickelt, die anf\u00e4ngliche Idee, die neue Anwendung mit QML zu entwickeln habe ich nach einer Weile QML-Tutorials anschauen und kurzer \u00dcberlegung dann verworfen und entwickle das neue Tool nun wieder als Qt-Widget-Anwendung. Wie sagt man so sch\u00f6n:<\/p>\n<blockquote><p>Schuster bleib bei Deinen Leisten<\/p><\/blockquote>\n<p>In meiner bisher umfangreichsten Qt-Desktop-Anwendung &#8222;Laserfeed&#8220; ist vieles historisch gewachsen, manche Dinge m\u00fcsste ich eigentlich mal dringend umstellen, u.a. alle Tab-Inhalte als separate Widget-Klassen definieren. Aktuell ist da der Gro\u00dfteil noch im Haupt-Form untergebracht, was diese Klasse echt katastrophal zu pflegen macht.<\/p>\n<p>Mit Umsetzung der neuen Anwendung m\u00f6chte ich das diesmal gleich von Anfang an richtig machen. Daher habe ich jeden Screen erst mal als eigene Formular-Klasse definiert und das entsprechende Layouting vorgenommen. Anschlie\u00dfend habe ich in dem MainWindow ein StackWidget angelegt und dort die entsprechende Anzahl an Seiten eingef\u00fcgt. In jede Seite kommt ein Widget und wird \u00fcber ein Layout entsprechend auf die Gr\u00f6\u00dfe des StackWidgets gesetzt.<\/p>\n<p>Diese Widgets werden dann als &#8222;Delegate&#8220; eingerichtet, das macht man, indem man im Qt-Creator rechte Maustaste auf das Widget klickt und &#8222;Als Platzhalter f\u00fcr benutzerdefinierte Klasse festlegen&#8230;&#8220; ausw\u00e4hlt.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-medium wp-image-200\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Platzhalter_festlegen-293x300.png\" alt=\"\" width=\"293\" height=\"300\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Platzhalter_festlegen-293x300.png 293w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Platzhalter_festlegen.png 469w\" sizes=\"(max-width: 293px) 100vw, 293px\" \/><\/p>\n<p>Das \u00f6ffnet einen neuen Dialog, in dem man dann den entsprechenden Klassennamen hinterlegt.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-medium wp-image-199\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Platzhalter_Dialog-300x280.png\" alt=\"\" width=\"300\" height=\"280\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Platzhalter_Dialog-300x280.png 300w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Platzhalter_Dialog.png 508w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Tragt dort unter Klassenname den Namen Eurer Form-Klasse ein, passt ggf. die include-Datei an (ich habe z.B. alle forms im Unterverzeichnis forms angelegt) und vergesst nicht mit &#8222;Hinzuf\u00fcgen&#8220; diese Klasse einzutragen. W\u00e4hlt dann den neuen Eintrag in dem oberen Treeview aus und best\u00e4tigt die Auswahl mit &#8222;Anwenden&#8220;.<\/p>\n<p>Nun sind die Formulare zwar als separate Formular-Klasse hinterlegt werden aber trotzdem im MainWindow &#8222;verlinkt&#8220;.<\/p>\n<p>F\u00fcr meine Anwendung soll es eine Startseite geben, auf der eine entsprechende Aktion gew\u00e4hlt werden kann. Diese Aktion \u00f6ffnet dann ein entsprechendes Formular. Im Formular gibt es u.a. einen OK- und Abbrechen-Button.<br \/>\nWird auf OK bzw. Abbrechen geklickt, soll wieder zum Startbildschirm gewechselt werden. Wie bringt man aber die Delegates dazu, mit dem Haupt-Screen zu interagieren? Ja klar, \u00fcber Signal -&gt; Slots.<\/p>\n<p>Dazu definiere ich in den Formular-Klassen jeweils signals f\u00fcr ok und abbrechen, z.B:<\/p>\n<pre lang=\"cpp-qt\">    signals:\r\n     void okSelected();\r\n     void abbrechenSelected();\r\n<\/pre>\n<p>Im entsprechenden Formular werden dann die Button-Dr\u00fccke mit Aktionen hinterlegt. Das macht man im Designer, indem man auf den entsprechenden Button rechtsklickt und &#8222;Slot anzeigen&#8230;&#8220; w\u00e4hlt.<br \/>\n<img decoding=\"async\" class=\"alignnone size-medium wp-image-203\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Slot_anzeigen-191x300.png\" alt=\"\" width=\"191\" height=\"300\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_anzeigen-191x300.png 191w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_anzeigen.png 372w\" sizes=\"(max-width: 191px) 100vw, 191px\" \/><\/p>\n<p>Es \u00f6ffnet sich wieder ein Fenster, dort w\u00e4hlt man das entsprechende Signal aus, dass man implementieren m\u00f6chte, in unserem Fall einfach clicked() ohne Parameter (ist ja kein Togglebutton).<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-205\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Slot_clicked-300x125.png\" alt=\"\" width=\"300\" height=\"125\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_clicked-300x125.png 300w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_clicked.png 530w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Dr\u00fcckt man OK, legt Qt automatisch ein entsprechenden Slot an. Im Code schicken wir dann wieder ein Signal, je nach Button.<\/p>\n<p>OK-Button:<\/p>\n<pre lang=\"cpp-qt\">emit okSelected();<\/pre>\n<p>Abbrechen-Button:<\/p>\n<pre lang=\"cpp-qt\">emit abbrechenSelected();<\/pre>\n<p>Nun m\u00fcssen die Signale noch im Hautpwindow ausgewertet werden. Das kann man entweder auf h\u00e4ndische Weise machen, indem man h\u00e4ndisch die entsprechenden Slots im Header des Hauptfensters anlegt:<\/p>\n<pre lang=\"cpp-qt\">  private slots:\r\n      void widget1OkSelectedSlot();\r\n      void widget1AbbrechenSelectedSlot();\r\n<\/pre>\n<p>und im Konstruktor die Dinge miteinander verkn\u00fcpft (wenn unser Formular als widget1 &#8222;referenziert ist&#8220;):<\/p>\n<pre lang=\"cpp-qt\">   connect(ui-&gt;widget1, SIGNAL(okSelected()), this, SLOT(widget1OkSelectedSlot()));\r\n   connect(ui-&gt;widget1, SIGNAL(abbrechenSelected()), this, SLOT(widget1AbbrechenSlot()));\r\n<\/pre>\n<p>Alternativ bzw. einfacher geht das direkt im Designer. Irgendwie habe ich den Weg gar nicht mehr in Erinnerung gehabt, aber so geht es eigentlich viel besser.<\/p>\n<p>\u00d6ffnet dazu wiederum das HauptWindow im Designer und klickt mit rechter Maustaste auf das entsprechende Formular-Widget.<br \/>\nDort sollte es einen Eintrag: &#8222;Signale\/Slots \u00e4ndern&#8230;&#8220;.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-202\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Signale_Slots-300x283.png\" alt=\"\" width=\"300\" height=\"283\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Signale_Slots-300x283.png 300w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Signale_Slots.png 540w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Ist das nicht der Fall \u00fcberpr\u00fcft bitte noch einmal, ob dem Widget auch wirklich mit der Platzhalter-Methode weiter oben eine eigene Formular-Klasse zugewiesen wurde.<\/p>\n<p>Im nachfolgenden Dialog legt ihr um unteren Teil: Signale mit dem +-Symbol zwei Signale an und zwar okSelected() und abbrechenSelected().<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-201\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Signale_angelegt-300x272.png\" alt=\"\" width=\"300\" height=\"272\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Signale_angelegt-300x272.png 300w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Signale_angelegt.png 633w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Nun k\u00f6nnen wir analog zu den Button-Klick-Signale auch die beiden neuen Signale implementieren, indem wir wiederum auf dem Widget die rechte Maustaste klicken und wiederum Slot anzeigen&#8230; anklicken.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-medium wp-image-203\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Slot_anzeigen-191x300.png\" alt=\"\" width=\"191\" height=\"300\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_anzeigen-191x300.png 191w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_anzeigen.png 372w\" sizes=\"(max-width: 191px) 100vw, 191px\" \/><\/p>\n<p>Nun \u00f6ffnet sich wiederum der Dialog mit der Auswahl und siehe da, dort werden auch unsere beiden Signale angezeigt.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-204\" src=\"http:\/\/devblog.cssec.de\/wp-content\/uploads\/2019\/01\/Slot_anzeigen_formWidget-300x125.png\" alt=\"\" width=\"300\" height=\"125\" srcset=\"https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_anzeigen_formWidget-300x125.png 300w, https:\/\/www.cssec.de\/blog\/wp-content\/uploads\/2019\/01\/Slot_anzeigen_formWidget.png 530w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>W\u00e4hlt das entsprechende Signal aus (z.B. okSelected()), klickt auf OK und Qt-Creator erzeugt f\u00fcr Euch den entsprechenden Slot im Haupt-Window. Dort k\u00f6nnt ihr die entsprechende Logik hinterlegen, was passieren soll, wenn der OK-Button des entsprechenden Widgets gedr\u00fcckt wurde, ohne manuell Slots anzulegen und mit connect-Statements die Sachen h\u00e4ndisch zu verkn\u00fcpfen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Heute mal seit langer Zeit wieder ein l\u00e4ngerer Beitrag mit einem kleineren Tutorial. Aktuell bin ich mal wieder dabei eine Qt-(Desktop)-Anwendung f\u00fcr einen Kunden zu erstellen, mal wieder ganz von Null auf, inkl. Analyse, Wireframe-Konzept, Klickdummy, Umsetzung, Dokumentation und Test. Bis auf Nutzung als C++-Editor habe ich im Qt-Creator lange Zeit nichts mehr mit Oberfl\u00e4chen-\/Formularen [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":209,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,6],"tags":[],"_links":{"self":[{"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/posts\/198"}],"collection":[{"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/comments?post=198"}],"version-history":[{"count":6,"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/posts\/198\/revisions"}],"predecessor-version":[{"id":557,"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/posts\/198\/revisions\/557"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/media\/209"}],"wp:attachment":[{"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/media?parent=198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/categories?post=198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cssec.de\/blog\/wp-json\/wp\/v2\/tags?post=198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}