Inhaltsverzeichnis

Voraussetzung

Zur Verwendung der modernen und leistungsfähigen Qt-Bibliothek muss man das Paket PyQt6 installieren. Dazu ruft man über das Werkzeuge-Menü von GuiPy den Befehl Werkzeuge/Pakete mit PIP installieren auf und gibt als Paketname PyQt6 an. Über Werkzeuge/Command Prompt kann man sich eine Konsole öffnen und dann mit pip list die Liste der aktuell installierten Pakete anzeigen lassen.

Zusätzlich sollte man das Paket PySide6 installieren, um darauf basierenden Quellcode ausführen zu können.

Eine der wichtigsten Änderungen in PyQt6, ist die Notwendigkeit, vollständig qualifizierte Namen für Aufzählungen und Flags zu verwenden. In PyQt5 und PySide2 konnte man zum Beispiel einfach Qt.DecorationRole oder Qt.AlignLeft schreiben. In PyQt6 funktioniert diese verkürzte Form nicht mehr, man muss jetzt Qt.ItemDataRole.DisplayRole bzw. Qt.Alignment.AlignLeft schreiben. Diese Änderung wirkt sich auf alle Enums und Flag-Typen in Qt aus. In PySide6 werden sowohl lange als auch kurze Namen weiterhin unterstützt.

Möchten Sie lieber mit den verkürzten Formen arbeiten, so können Sie im Qt-Template PyQt6 durch PySide6 ersetzen. Das Qt-Template finden Sie in der Konfiguration unter Editor/Dateivorlagen.

In der Dokumentation bzw. Dokumentation Qt findet man Detailinformationen zu Qt.

Qt

Ein GUI-Formular wird mit Hilfe von Widgets aufgebaut. Das sind die grafischen Komponenten, die in den beiden Qt-Symbolleisten zur Verfügung stehen. Nachfolgend wird grundlegendes zur Verwendung von Widgets angegeben, was in vielen Fällen auch ausreicht. Detailliertere Angaben findet man z.B. in der Qt-Referenz.

Ein GUI-Programm legt man mit dem Symbol für neue Qt-Anwendung auf der Registerkarte Programm an. Widgets können per Drag&Drop oder durch Anklicken eines Widgets und anschließendes Klicken in das GUI-Formular platziert werden. Es wird nur absolutes Layout unterstützt. Das reicht für die meisten Zwecke vollkommen aus. Die Gestaltung einer GUI-Oberfläche mit Layoutmanagern ist deutlich schwieriger.

Attribute und Signale eines Widgets werden im Objektinspektor konfiguriert. Anfangs werden nur die allerwichtigsten Attribute und Signale angezeigt. Diese Filterung vereinfacht die Arbeit mit dem Objektinspektor. Man kann sich in zwei weiteren Stufen mehr beziehungsweise alle Attribute und Signale anzeigen lassen.

Der Pythoncode eines GUI-Programms wird unter der Dateierweiterung .pyw gespeichert, das dazugehörige Formular mit der Dateierweiterung .pfm. Beide werden zusammen geöffnet. Schließt man das Formular, so kann man es über das Symbol der Editorsymbolleiste wieder öffnen.

Qt Base

Label

Mit einem Label-Widget beschriftet man Widgets eines GUI-Formulars. Ein Label kann außer Text auch ein Bild oder Beides darstellen. Um ein Bild darzustellen wählt man im Objektinspektor beim Attribut Pixmap die gewünschte Bilddatei aus.

Beispiel:

Mit der Methode move(x, y) des Label-Widgets kann man ein Bild animieren. Im Auto-Beispiel wird gezeigt, wie das funktioniert.


LineEdit

Mit einem LineEdit-Widget kann man Text oder Zahlen ein- oder ausgeben. Den eingegebenen Text erhält man über die text()-Methode, zur Ausgabe verwendet man setText().

Beispiel:

EAN = self.leEAN.text()

Zur Eingabe einer Zahl wandelt man den eingegebenen Text mit int() in eine Integerzahl oder mit float() in eine Dezimalzahl um.

Beispiel:

Menge = float(self.leMenge.text())

Soll eine Zahl ausgegeben werden, so muss man sie mit der str()-Funktion in einen String umwandeln.

Beispiel:

self.leTankinhalt.setText(str(Tankinhalt))

PlainTextEdit

Ein PlainTextEdit-Widget stellt im Gegensatz zum LineEdit-Widget einen mehrzeiligen Text dar. Im Objektinspektor kann man über das Attribut PlainText den anzuzeigenden Text eingeben. Zur Laufzeit kann man die Methode appendPlainText() benutzen, um in ein PlainTextEdit-Widget mit dem Namen Ausgabe zeilenweise etwas auszugeben.

Beispiel:

    def ausgeben(self, Zeile):
        self.Ausgabe.appendPlainText(Zeile)


clear() löscht den gesamten Text. DieDokumentation zeigt weitere Methoden.


PushButton

Jedes PushButton-Widget erhält automatisch eine Ereignismethode, die beim Anklicken des Buttons aufgerufen wird.

Beispiel:

    def pushButton1_clicked(self, ckecked):
        # ToDo insert source code here
        pass

Um auch bei vielen Buttons in einem Formular die Übersicht im Quelltext zu behalten, werden die Buttons und zugehörigen Ereignismethoden automatisch nach der Beschriftung im Attribut Text des Objektinspektors benannt.

Ein Doppelklick auf einen Button im Designfenster positioniert den Cursor auf die zugehörige Ereignismethode.

CheckBox

Eine CheckBox kann ausgewählt sein oder nicht. Den aktuellen Zustand liefert die boolesche Methode isChecked(), mit setChecked(bool) wird ein Wert gesetzt.

Beispiel:

  if self.cbAusgewaehlt.isChecked(): 
      print('Ausgewählt!')  

ButtonGroup


Eine ButtonGroup bietet mehrere Auswahlmöglichkeiten an, aus denen man eine Option auswählen kann. Eine neu angelegte ButtonGroup erhält automatisch eine Gruppe mit den drei Auswahlmöglichkeiten „America, Europe und Asia“ und das Label „ Continent “. Im Objektinspektor findet man diese Werte im Attribut Items bzw. Title und kann sie dort leicht anpassen.

Die Radiobuttons einer Buttongroup werden von 0 an durchnummeriert. Mit checkedId() bzw. setId() kann man die Nummer des ausgewählten Radiobuttons abfragen, bzw. ein Radiobutton auswählen. Im Quelltext ruft man diese Methoden über das nicht visuelle Buttongroup Widget ab, dessen Name mit „BG“ endet. Für das optische Erscheinungsbild mit Rahmen und Beschriftung ist ein GroupBox-Widget zuständig.

Beispiele:

  print(self.buttonGroup1BG.checkedId())
  self.buttonGroup1BG.setId(2)

Setzt man im Objektinspector das Attribut checkboxes auf true, so werden werden die Radiobuttons in Checkboxen umgewandelt. Bei vielen Optionen kann man diese über das Attribut Columns mehrspaltig anzeigen lassen.


ListWidget

Ein ListWidget zeigt eine Liste von Strings an, die man im Objektinspektor über das Attribut Items eingeben kann. Die Nummer der ausgewählten Zeile erhält man über currentRow(), den aktuell ausgewählten String mit currentItem().text(). Einen Eintrag kann man über item(Nr).setText() ändern.

Beispiele:

    def pushButton1_clicked(self, checked):
        print(self.listWidget1.currentRow())
        print(self.listWidget1.currentItem().text())
        self.listWidget1.item(2).setText('Afrika')
        pass

Weitere ListWidget-Methoden findet man unter https://doc.qt.io/qt-6/qlistwidget.html


ComboBox

Eine ComboBox ist eine Kombination aus einer Eingabezeile und einer ausklappbaren Auswahlliste. Der Anwender kann zur Laufzeit in der Eingabezeile Text eingeben oder ein Listenelement auswählen. Im Objektinspektor kann man über das Attribut ListItems Strings in die Auswahlliste eingeben.

Beispiele:

    print(self.comboBox1.currentText())  
    print(self.comboBox1.currentIndex())       
    print(self.comboBox1.itemText(index))       
    self.comboBox1.setItemText(2, 'Australien')

SpinBox

Mit einer SpinBox kann man schrittweise Zahlen aus einem Bereich auswählen. Im Objektinspektor legt man Minimum, Maximum, Schrittweite (SingleStep) und aktueller Wert (Value) fest.

Den aktuellen wert kann man im Programm mit value() abfragen und mit setValue() setzen.

Beispiel:

  print(self.spinBox1.value())
  self.SpinBox1.setValue(12)

Der Tab „Qt Controls“ enthält ein DoubleSpinBox-Widget für Dezimalwerte.


ScrollBar

Mit einem ScrollBar kann man einen Bildlauf durchführen, bei dem der sichtbare Ausschnitt eines dargestellten Textes oder einer Grafik verschoben wird. Einige Widgets wie z. B. PlainTextEdit, ListBox oder TableWidget sind automatisch mit Scrollbars versehen.


Canvas

Ein Canvas ist eine Zeichenfläche. Der Painter für die Zeichenfläche hat viele Zeichenmöglichkeiten.

Beispiel:

  def pushButton1_clicked(self, checked):
      self.canvas1Painter.drawEllipse(0, 0, 100, 100)  # zeichne einen Kreis
      self.canvas1Painter.drawLine(0, 100, 100, 0)     # zeichne eine Strecke
      self.canvas1.setPixmap(self.canvas1Pixmap)       # zeige die Zeichnung

Ein Canvas besteht aus einem Label-Widget, das den Canvas aufnimmt. Dann haben wir ein QPixmap in der Größe des Labels, das die eigentliche Zeichenfläche ist. Und drittens haben wir den QPainter, der auf die QPixmap zeichnet.

Wie im Beispiel gezeigt, kann man mit dem Painter ganz einfach zeichnen. Wenn die Zeichnung fertig ist, muss man sie wie folgt anzeigen:

self.canvas1.setPixmap(self.canvas1Pixmap)

Frame

Ein Frame ist ein Container für andere Widgets. Mit Frames kann man gut grafische Oberflächen strukturieren. Zum Platzieren eines Widgets in einem Frame klickt man es in der Symbolleiste an und klickt dann in das Frame, oder man zieht ein Widegt von der Symboleiste über den Frame und lässt es dann fallen (Drag&Drop). Verschiebt man ein Frame, so werden die darin enthaltenen Widgets mitverschoben.


GroupBox

Eine GroupBox ist wie ein Frame ein Container für andere Widgets. Eine GroupBox hat aber zusätzlich einen Rahmen mit integriertem Label.

GuiPy stellt eine ButtonGroup für RadioButtons bzw. CheckBoxen mit Hilfe einer GroupBox grafisch dar.


Slider

Der Zweck eines Slider-Widgets besteht darin, einen Zahlenwert innerhalb eines bestimmten Bereichs festzulegen. Über value() fragt man den eingestellten Wert ab, über setValue() stellt man einen Wert ein.

    print(self.slider1.value())
    self.slider1.setValue(33)

Ein MenuBar-Widget ist eine Menüleiste mit aufklappbaren Untermenüs.

Das Menü wird über das Attribut MenuItems definiert, bei dem durch entsprechende Einrückung die Menüstruktur erzeugt wird. Bei einem neu erzeugtem Menu sieht diese Struktur so aus:

File
  New
    Python
    XML
  Load
  Save, Ctrl+S
Edit
  Copy, Ctrl+C
  Paste, Ctrl+V
  -
  Delete

Für die Menüeinträge werden Ereignismethoden angelegt, die bei der Auswahl des Menüeintrags aufgerufen werden.

    def menuBar1FileNewMenuPythonCommand(self):
        # ToDo insert source code here
        pass

Ein Menu-Widget ist ein Kontextmenü, das mit der rechten Maustaste aufgerufen wird. Es wird wie beim MenuBar-Widget über das Attribut MenuItems definiert.

Man kann jedem Widget ein Kontextmenü zuweisen. Dazu gibt man beim Attribut ContextMenu den Namen des Menüs an.


TabWidget

Ein TabWidget stellt oben eine Liste mit Registerkarten bereit, mit denen unten befindliche Seiten aufgeschlagen werden können. Klickt man auf eine Registerkarte, wird die zugehörige Seite aufgeschlagen. Eine Seite ist ein Container für weitere Widgets.

BeispieL

    self.tabWidget1Page1 = QLabel()
    self.tabWidget1Page1.setText('Add widgets to this page')
    self.tabWidget1.addTab(self.tabWidget1Page1, 'Tab 1')

TreeWidget

Ein TreeWidget stellt eine hierarchische Struktur baumartig dar. Zu jedem Baumknoten können in weiteren Spalten zusätzliche Informationen angezeigt werden.

Durch entsprechende Einrückung wird die Struktur über das Attribut Items festgelegt. Diese Struktur ist anfangs vorgegeben:

First, F2, F3
  node A, A2, A3
  node B
Second
  node C
    node D, D2
 

TableWidget


ProgressBar

Ein ProgressBar stellt einen Fortschrittsbalken dar. Der aktuelle Wert kann mit value() gelesen und mit setValue() geschrieben werden.


StatusBar

Ein StatusBar-Widget stellt eine Stauszeile am unteren Rand des Anwednungsfensters dar. In der rechten unteren Ecke wird durch Punkte ein Griff zum Ändern der Größe des Anwendungsfensters angezeigt.


Qt Controls

TextEdit

Ein TextEdit-Widget stellt wie das PlainTextEdit-Widget einen mehrzeiligen Text dar, allerdings im HTML- oder Markdown-Format. Im Objektinspektor kann man über das Attribut Html den anzuzeigenden HTML-Text eingeben. In einem Programm kann man zur Laufzeit den Text mit toHTML() lesen und mit setHTML() schreiben. Weitere Methoden werden in der Dokumentation beschrieben.


TextBrowser

Das TextBrowser-Widget erweitert das TextEdit-Widget um einige Navigationsfunktionen, damit Benutzer Links in Hypertext-Dokumenten folgen können.


ToolButton

Eine ToolButton ist eine spezieller Button, der schnellen Zugriff auf bestimmte Befehle oder Optionen bietet. Im Gegensatz zu einem normalen Button zeigt ein ToolButton normalerweise keine Textbeschriftung, sondern stattdessen ein Symbol an. Üblicherweise werden ToolButtons auf ToolBars platziert.


CommandLinkButton

Ein CommandLinkButton kann ähnlich einem Radiobutton verwendet werden, um zwischen einer Reihe sich gegenseitig ausschließender Optionen zu wählen.


FontComboBox

Die FontComboBox ist eine ComboBox für die Auswahl eines Fonts. Der aktuell ausgewählte Font kann mit currentFont() abgefragt werden.


DoubleSpinBox

Im Gegensatz zum SpinBox-Widget können mit dem DoubleSpinBox-Widget auch Dezimalwerte ausgewählt werden. Den aktuellen Wert kann man zur Laufzeit mit value() abfragen und mit setValue() setzen.


LCDNumber

Das LCDNumber-Widget kann Zahlen in Dezimal-, Hexadezimal-, Oktal- und Binär-Darstellung anzeigen.


DateTimeEdit

DateTimeEdit ermöglicht es dem Benutzer, Datumsangaben mit der Tastatur oder den Pfeiltasten zu bearbeiten, um Datums- und Zeitwerte zu erhöhen oder zu verringern. Die Pfeiltasten können verwendet werden, um sich innerhalb des QDateTimeEdit-Felds von Abschnitt zu Abschnitt zu bewegen.


DateEdit

DateEdit ist ein spezielles DateTimeEdit-Widget, das nur Datumswerte anzeigt und bearbeiten lässt.


TimeEdit

TimeEdit ist ein spezielles DateTimeEdit-Widget, das nur Uhrzeiten anzeigt und bearbeiten lässt.


Dial

QDial verhält sich wie ein Slider. Im Unterschied zu einem Schieberegler kann ein Drehregler auch umlaufend sein (Wrapping = true).


Line

Ein Line-Widget ist eine horizontale oder vertikale Strecke, mit der die GUI-Oberfläche strukturiert werden kann.


ScrollArea

Ein ScrollArea wird verwendet, um den Inhalt eines Kind-Widgets innerhalb eines Rahmens anzuzeigen. Wenn das Widget die Größe des Rahmens überschreitet, kann die Ansicht Bildlaufleisten bereitstellen, sodass der gesamte Bereich des untergeordneten Widgets angezeigt werden kann. Das untergeordnete Widget muss mit setWidget() angegeben werden.


ToolBox

Eine Toolbox ist ein Widget, das eine Spalte mit Registerkarten anzeigt. Direkt unter der aktuellen Registerkarte wird das zugehörige Widget angezeigt. Standardmäßig werden drei Registerkarten amgezeigt, die jeweils ein Label enthalten.


StackedWidget

StackedWidget kann verwendet werden, um eine Benutzeroberfläche ähnlich der von TabWidget zu erstellen. Es ist ein komfortables Layout-Widget, das auf dem Widget StackedLayout aufbaut.


ListView

Eine ListView stellt in einem Modell gespeicherte Elemente entweder als einfache nicht hierarchische Liste oder als Sammlung von Symbolen dar. Diese Widget wird verwendet, um Listen und Symbolansichten bereitzustellen.


ColumnView

ColumnView zeigt ein Modell in mehreren ListViews an, eines für jede Hierarchie im Baum. Dies wird manchmal als kaskadierende Liste bezeichnet.


TreeView

Ein TreeView-Widget implementiert eine Baumdarstellung von Elementen aus einem Modell. Dieses Widget wird verwendet, um standardmäßige hierarchische Listen bereitzustellen.


TableView

Ein TableView-Widget implementiert eine Tabellenansicht, die Elemente aus einem Modell anzeigt.


GraphicsView

GraphicsView visualisiert den Inhalt einer QGraphicsScene in einem scrollbaren Viewport.