===== Precondition ===== To use the modern and powerful Qt library, you need to install the PyQt6 package. To do this, call up the command Install //tools/install packages with PIP// via the GuiPy tools menu and enter //PyQt6// as the package name. You can use the //pip list// command to display the list of currently installed packages. In addition, you should install the PySide6 package in order to be able to run source code based on it. One of the major changes in PyQt6 is the need to use fully qualified names for enums and flags. For example in PyQt5 and PySide2 you could just write Qt.DecorationRole or Qt.AlignLeft. This shortened form no longer works in PyQt6, you now have to write Qt.ItemDataRole.DisplayRole or Qt.Alignment.AlignLeft. This change affects all enums and flag types in Qt. Both long and short names are still supported in PySide6. If you prefer to work with the shortened forms, you can replace PyQt6 with PySide6 in the Qt template. The Qt template can be found in the configuration under Editor/File templates. Detailed information about Qt can be found in the [[https://doc.qt.io/qtforpython/PySide6/QtWidgets/index.html#module-PySide6.QtWidgets|documentation]] or [[https://doc.qt.io/qt-6/index.html|documentation Qt]]. ===== Qt===== A GUI form is built with the help of widgets. These are the graphical components available in both Qt toolbars. The basics for using widgets are given below, which is sufficient in many cases. More detailed information can be found e.g. in the [[https://doc.qt.io/qt-6/index.html| Qt Reference]]. A GUI program is created using the {{:qtapp.png}} icon for new Qt application on the //Program// tab. Widgets can be placed by drag and drop or by clicking on a widget and then clicking in the GUI form. Only absolute layout is supported. This is sufficient for school purposes. Designing a GUI surface with layout managers is much more difficult. Attributes and signals of a widget are configured in the object inspector. Initially, only the most important attributes and signals are displayed. This filtering simplifies working with the object inspector. You can display more or all attributes and signals in two further stages. The Python code of a GUI program is saved with the .pyw file extension, the associated form with the .pfm file extension. Both will open together. If you close the form, you can open it again using the {{:arrange.png}} icon in the editor toolbar. ===== Qt Base ===== ==== Label ==== {{:label.png}} A Label widget is used to label widgets of a GUI form. In addition to text, a label can also display an image or both. To display an image, select the desired image file in the object inspector for the //Pixmap// attribute.\\ Example: {{:en:carlabel.png}} An image can be animated using the move(x, y) method of the Label widget. The [[Examples#Car|car example]] shows how this works. \\ \\ ---- ==== LineEdit ==== {{:entry.png}} With a LineEdit widget you can input or output text or numbers. The entered text is obtained via the //text()// method, //setText()// is used for the output. Example: {{:en:eanentry.png}} EAN = self.leEAN.text() To enter a number, convert the entered text into an integer with //int()// or into a decimal with //float()//. Example: Amount = float(self.leAmount.text()) If a number is to be output, it must be converted into a string using the //str()// function. Example: self.leTankcontent.setText(str(Tankcontent)) ---- ==== PlainTextEdit ==== {{:text.png}} In contrast to the LineEdit widget, a PlainTextEdit widget displays a multi-line text. In the object inspector, you can enter the text to be displayed using the //PlainText// attribute. At runtime, you can use the //appendPlainText()// method to output line by line to a PlainTextEdit widget named Output. Beispiel: def output(self, line): self.Output.appendPlainText(line) \\ //clear()// clears all text. The [[https://doc.qt.io/qtforpython/PySide6/QtWidgets/QPlainTextEdit.html|documentation]] shows other methods. ---- ==== Button ==== {{:button.png}} Each Button widget automatically gets an event method that is called when the button is clicked. Example: def pushButton1_clicked(self, ckecked): # ToDo insert source code here pass In order to keep track of the source text even when there are many buttons in a form, the buttons and associated event methods are automatically named according to the label in the //Text// attribute of the object inspector. Double-clicking on a button in the design window positions the cursor on the associated event method. ---- ==== CheckBox ==== {{:checkbutton.png}} A CheckBox may or may not be selected. The boolean method //isChecked()// returns the current status, with //setChecked(bool)// a value is set. Example: {{:en:checkbutton.png}} if self.cbSelected.isChecked(): print('Selected!') ---- ==== ButtonGroup ==== {{:radiobuttongroup.png}}\\ A ButtonGroup offers several choices from which you can select an option. A newly created ButtonGroup automatically receives a group with the three options "America, Europe and Asia" and the label " Continent ". In the object inspector, you can find these values in the //Items// or //Title// attribute and can easily adjust them there. The radio buttons of a button group are numbered consecutively from 0. With //checkedId()// or //setId()// you can query the number of the selected radio button or select a radio button. In source code, these methods are called via the non-visual Buttongroup widget whose name ends with "BG". A GroupBox widget is responsible for the visual appearance with frame and label. Examples: print(self.buttonGroup1BG.checkedId()) self.buttonGroup1BG.setId(2) If you set the //Checkboxes// attribute to true in the object inspector, the radio buttons are converted into checkboxes. Many options can be displayed in multiple columns using the //Columns// attribute. ---- ==== ListWidget ==== {{:listbox.png}} A ListWidget displays a list of strings that can be entered in the object inspector via the //Items// attribute. The number of the selected row is obtained via //currentRow()//, the currently selected string with //currentItem().text()//. An entry can be changed using //item(Nr).setText()//. Examples: def pushButton1_clicked(self, checked): print(self.listWidget1.currentRow()) print(self.listWidget1.currentItem().text()) self.listWidget1.item(2).setText('Afrika') pass For more ListWidget methods, see [[https://doc.qt.io/qt-6/qlistwidget.html]] ---- ==== ComboBox ==== {{:combobox.png}} A ComboBox is a combination of an input line and a drop-down list box. At runtime, the user can enter text in the entry line or select a list item. In the object inspector, you can use the //ListItems// attribute to enter strings in the selection list. print(self.comboBox1.currentText()) print(self.comboBox1.currentIndex()) print(self.comboBox1.itemText(index)) self.comboBox1.setItemText(2, 'Australia') ---- ==== SpinBox ==== {{:spinbox.png}} With a SpinBox you can select numbers from a range step by step. In the object inspector you define the minimum, maximum, increment (single step) and current value (value). The current value can be queried in a program with //value()// and set with //setValue()//. Example: print(self.spinBox1.value()) self.spinBox1.setValue(12) The tab "Qt Controls" contains a DoubleSpinBox widget for decimal values. ---- ==== Scrollbar ==== {{:scrollbar.png}} A ScrollBar can be used to scroll, in which the visible section of a displayed text or graphic is moved. Some widgets such as B. PlainTextEdit, ListBox or TableWidget are automatically provided with scrollbars. ---- ==== Canvas ==== {{:canvas.png}} A Canvas is a drawing surface. The Painter for the canvas has many drawing possibilities. Example: def pushButton1_clicked(self, checked): self.canvas1Painter.drawEllipse(0, 0, 100, 100) # draw a circle self.canvas1Painter.drawLine(0, 100, 100, 0) # draw a line self.canvas1.setPixmap(self.canvas1Pixmap) # show the drawing A Canvas consists of a Label widget that hosts the canvas. Then we have a pixmap the size of the Label, which is the actual drawing surface. And third, we have the QPainter that draws on the pixmap. A shown in the example, you can easily draw on the canvas with the painter. When the drawing is finished, you have to show it with self.canvas1.setPixmap(self.canvas1Pixmap) ---- ==== Frame ==== {{:frame.png}} A Frame wigdet is a container for other widgets. Frames are a good way to structure graphic interfaces. To place a widget in a frame, click it in the toolbar and then click in the frame, or drag and drop a widget from the toolbar over the frame. If you move a frame, the widgets it contains are also moved. ---- ==== GroupBox ==== {{:labelframe.png}} Like a Frame widget, a GroupBox is a container for other widgets. A GroupBox also has a frame with an integrated label. GuiPy graphically displays a ButtonGroup for RadioButtons or CheckBoxes using a GroupBox. ---- ==== Slider==== {{:ttkscale.png}} The purpose of a Slider widget is to set a number value within a certain range. With //value()// you query the set value, with //setValue()// you set a value. print(self.slider1.value()) self.slider1.setValue(33) ---- ==== MenuBar ==== {{:menu.png}} A MenuBar widget is a menu bar with collapsible submenus. {{:menuexample.png}} The Menu is defined via the //MenuItems// attribute, in which the menu structure is generated by appropriate indentation. With a newly created menu, the structure looks like this: File New Python XML Load Save, Ctrl+S Edit Copy, Ctrl+C Paste, Ctrl+V - Delete Event methods are created for the menu items, which are called when the menu item is selected. def menuBar1FileNewMenuPythonCommand(self): # ToDo insert source code here pass ---- ==== Menu ==== {{:popupmenu.png}} A Menu widget is a context menu that is invoked with the right mouse button. As with the MenuBar widget, it is defined using the //MenuItems// attribute. You can assign a context menu to each widget. To do this, you specify the name of the menu in the //ContextMenu// attribute of the widget. ---- ==== TabWidget ==== {{:notebook.png}} A TabWidget provides a tab bar at the top that can be used to open pages below. If you click on a tab, the associated page opens. A page is a container for other widgets. Example self.tabWidget1Page1 = QLabel() self.tabWidget1Page1.setText('Add widgets to this page') self.tabWidget1.addTab(self.tabWidget1Page1, 'Tab 1') ---- ==== TreeWidget==== {{:treewidget.png}} A TreeWidget represents a hierarchical structure like a tree. Additional information for each tree node can be displayed in columns. The structure is defined via the //Items// attribute by appropriate indentation. This structure is initially specified: First, F2, F3 node A, A2, A3 node B Second node C node D, D2 ---- ==== TableWidget==== ---- ==== ProgressBar ==== {{:progressbar.png}} A ProgressBar represents a progress bar. The current value can be read with //value()// and written with //setValue()//. ==== StatusBar ==== {{:sizegrip.png}} A StatusBar widget represents a status bar at the bottom of the application window. A handle for resizing the application window is indicated by dots in the lower right corner. ---- ===== Qt Controls ===== ==== TextEdit ==== {{:textedit.png}} A TextEdit widget displays a multi-line text like the PlainTextEdit widget, but in HTML or Markdown format. The HTML text to be displayed can be entered in the object inspector via the //Html// attribute. In a program, the text can be read with //toHTML()// and written with //setHTML()// at runtime. Other methods are described in the [[https://doc.qt.io/qtforpython/PySide6/QtWidgets/QTextEdit.html|documentation]]. -------- ==== TextBrowser ==== {{:textbrowser.png}} The TextBrowser widget extends the TextEdit widget with some navigation functionality to allow users to follow links in hypertext documents. -------- ==== ToolButton==== {{:toolbutton.png}} A ToolButton is a special button that provides quick access to specific commands or options. Unlike a normal button, a ToolButton does not typically display a text label, but instead displays an icon. Usually ToolButtons are placed on ToolBars. -------- ==== CommandLinkButton==== {{:commandlinkbutton.png}} A CommandLinkButton can be used like a radio button to choose between a set of mutually exclusive options. -------- ==== FontComboBox ==== {{:fontcombobox.png}} The FontComboBox is a combo box for selecting a font. The currently selected font can be queried with //currentFont()//. -------- ==== DoubleSpinBox ==== {{:doublespinbox.png}} Unlike the SpinBox widget, the DoubleSpinBox widget can also select decimal values. The current value can be queried at runtime with //value()// and set with //setValue()//. ---- ==== LCDNumber ==== {{:lcdnumber.png}} The LCDNumber widget can display numbers in decimal, hexadecimal, octal, and binary representation. ---- ==== DateTimeEdit ==== {{:datetimeedit.png}} DateTimeEdit allows the user to edit dates using the keyboard or arrow keys to increase or decrease date and time values. The arrow keys can be used to move from section to section within the QDateTimeEdit field. ---- ==== DateEdit ==== {{:dateedit.png}} DateEdit is a special DateTimeEdit widget that only displays and edits date values. ---- ==== TimeEdit ==== {{:timeedit.png}} TimeEdit is a special DateTimeEdit widget that only displays and edits times. ---- ==== Dial==== {{:dial.png}} QDial behaves like a slider. In contrast to a slider, a rotary control can also be encircling (wrapping = true). ---- ==== Line ==== {{:line.png}} A line widget is a horizontal or vertical line that can be used to structure the GUI surface. ---- ==== ScrollArea ==== {{:scrollarea.png}} A ScrollArea is used to display the content of a child widget within a frame. If the widget exceeds the size of the frame, the view can provide scroll bars so that the entire area of the child widget can be displayed. The child widget must be specified with //setWidget()//. ---- ==== ToolBox==== {{:toolbox.png}} A toolbox is a widget that displays a column of tabs. The associated widget is displayed directly under the current tab. By default, three tabs are displayed, each containing a label. ---- ==== StackedWidget ==== {{:stackedwidget.png}} A StackedWidget can be used to create a user interface similar to TabWidget. It's a convenient layout widget built on top of the StackedLayout widget. ---- ==== ListView ==== {{:listview.png}} A ListView represents items stored in a model either as a simple non-hierarchical list or as a collection of icons. This widget is used to provide lists and icon views. ---- ==== ColumnView ==== {{:columnview.png}} ColumnView displays a model in multiple ListViews, one for each hierarchy in the tree. This is sometimes called a cascading list. ---- ==== TreeView ==== {{:treeview.png}} A TreeView widget implements a tree representation of elements from a model. This widget is used to provide standard hierarchical lists. ---- ==== TableView ==== {{:tableview.png}} A TableView widget implements a table view that displays items from a model. ---- ==== GraphicsView ==== {{:graphicsview.png}} GraphicsView visualizes the content of a QGraphicsScene in a scrollable viewport. ----