diff options
author | Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> | 2018-10-24 15:39:56 +0200 |
---|---|---|
committer | Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> | 2018-11-05 10:15:57 +0000 |
commit | 7f8abfc78d6ed861bcc5f41bef224e5c732d2ba9 (patch) | |
tree | 33782468759e840b1b68b0daaa55f0f53aad1273 /sources/pyside2 | |
parent | 1c962cbff7e961a768d7bfaa2c9f63dd4905cc6b (diff) |
Add tutorials to the documentation
Included basic tutorials related to Widgets, QML and UI files.
Task-number: PYSIDE-841
Change-Id: Ia338f8cf1a64e4f09617fb3ac5a898d28e527dbd
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside2')
6 files changed, 497 insertions, 0 deletions
diff --git a/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst new file mode 100644 index 000000000..afec6d84f --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst @@ -0,0 +1,84 @@ +A Simple Button Tutorial +************************ + +In this tutorial, we'll show you how to handle **signals and slots** +using Qt for Python. **Signals and slots** is a Qt feature that lets +your graphical widgets communicate with other graphical widgets or +your python code. Our application creates a button that logs the +`Button clicked, Hello!` message to the python console each time you +click it. + +Let's start by importing the necessary PySide2 classes and python +`sys` module: +:: + import sys + from PySide2.QtWidgets import QApplication, QPushButton + from PySide2.QtCore import Slot + +Let's also create a python function that logs the message to the +console: +:: + + # Greetings + @Slot() + def say_hello(): + print("Button clicked, Hello!") + +.. note:: The `@Slot()` is a decorator that identifies a function as + a slot. It is not important to understand why for now, + but use it always to avoid unexpected behavior. + +Now, as mentioned in previous examples you must create the +`QApplication` to run your PySide2 code: +:: + # Create the Qt Application + app = QApplication(sys.argv) + +Let's create the clickable button, which is a `QPushButton` instance. +To label the button, we pass a python string to the constructor: +:: + # Create a button + button = QPushButton("Click me") + +Before we show the button, we must connect it to the `say_hello()` +function that we defined earlier. There are two ways of doing this; +using the old style or the new style, which is more pythonic. Let's +use the new style in this case. You can find more information about +both these styles in the +`Signals and Slots in PySide2 <https://wiki.qt.io/Qt_for_Python_Signals_and_Slots>`_ +wiki page. + +The `QPushButton` has a predefined signal called **clicked**, which +is triggered every time the button is clicked. We'll connect this +signal to the `say_hello()` function: +:: + # Connect the button to the function + button.clicked.connect(say_hello) + +Finally, we show the button and start the Qt main loop: +:: + # Show the button + button.show() + # Run the main Qt loop + app.exec_() + +Here is the complete code for this example: +:: + #!/usr/bin/python + + import sys + from PySide2.QtWidgets import QApplication, QPushButton + from PySide2.QtCore import Slot + + @Slot() + def say_hello(): + print("Button clicked, Hello!") + + # Create the Qt Application + app = QApplication(sys.argv) + # Create a button, connect it and show it + button = QPushButton("Click me") + button.clicked.connect(say_hello) + button.show() + # Run the main Qt loop + app.exec_() diff --git a/sources/pyside2/doc/tutorials/basictutorial/dialog.rst b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst new file mode 100644 index 000000000..1daa6b89d --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst @@ -0,0 +1,139 @@ +Creating a Simple PySide2 Dialog Application +********************************************* + +This tutorial shows how to build a simple dialog with some +basic widgets. The idea is to let users provide their name +in a `QLineEdit`, and the dialog greets them on click of a +`QPushButton`. + +Let us just start with a simple stub that creates and shows +a dialog. This stub is updated during the course of this +tutorial, but you can use this stub as is if you need to: +:: + import sys + from PySide2.QtWidgets import QApplication, QDialog, QLineEdit, QPushButton + + class Form(QDialog): + + def __init__(self, parent=None): + super(Form, self).__init__(parent) + self.setWindowTitle("My Form") + + + if __name__ == '__main__': + # Create the Qt Application + app = QApplication(sys.argv) + # Create and show the form + form = Form() + form.show() + # Run the main Qt loop + sys.exit(app.exec_()) + +The imports aren't new to you, the same for the creation of the +`QApplication` and the execution of the Qt main loop. +The only novelty here is the **class definition**. + +You can create any class that subclasses PySide2 widgets. +In this case, we are subclassing `QDialog` to define a custom +dialog, which we name as **Form**. We have also implemented the +`init()` method that calls the `QDialog`'s init method with the +parent widget, if any. Also, the new `setWindowTitle()` method +just sets the title of the dialog window. In `main()`, you can see +that we are creating a *Form object* and showing it to the world. + +Create the Widgets +=================== + +We are going to create two widgets: a `QLineEdit` where users can +enter their name, and a `QPushButton` that prints the contents of +the `QLineEdit`. +So, let's add the following code to the `init()` method of our Form: +:: + # Create widgets + self.edit = QLineEdit("Write my name here..") + self.button = QPushButton("Show Greetings") + +It's obvious from the code that both widgets will show the corresponding +texts. + +Create a layout to organize the Widgets +======================================== + +Qt comes with layout-support that helps you organize the widgets +in your application. In this case, let's use `QVBoxLayout` to lay out +the widgets vertically. Add the following code to the `init()` method, +after creating the widgets: +:: + # Create layout and add widgets + layout = QVBoxLayout() + layout.addWidget(self.edit) + layout.addWidget(self.button) + # Set dialog layout + self.setLayout(layout) + +So, we create the layout, add the widgets with `addWidget()`, +and finally we say that our **Form** will have our `QVBoxLayout` +as its layout. + +Create the function to greet and connect the Button +==================================================== + +Finally, we just have to add a function to our custom **Form** +and *connect* our button to it. Our function will be a part of +the Form, so you have to add it after the `init()` function: +:: + # Greets the user + def greetings(self): + print ("Hello {}".format(self.edit.text())) + +Our function just prints the contents of the `QLineEdit` to the +python console. We have access to the text by means of the +`QLineEdit.text()` method. + +Now that we have everything, we just need to *connect* the +`QPushButton` to the `Form.greetings()` method. To do so, add the +following line to the `init()` method: +:: + # Add button signal to greetings slot + self.button.clicked.connect(self.greetings) + +Once executed, you can enter your name in the `QLineEdit` and watch +the console for greetings. + +Complete code +============= + +Here is the complete code for this tutorial: +:: + import sys + from PySide2.QtWidgets import (QLineEdit, QPushButton, QApplication, + QVBoxLayout, QDialog) + + class Form(QDialog): + + def __init__(self, parent=None): + super(Form, self).__init__(parent) + # Create widgets + self.edit = QLineEdit("Write my name here") + self.button = QPushButton("Show Greetings") + # Create layout and add widgets + layout = QVBoxLayout() + layout.addWidget(self.edit) + layout.addWidget(self.button) + # Set dialog layout + self.setLayout(layout) + # Add button signal to greetings slot + self.button.clicked.connect(self.greetings) + + # Greets the user + def greetings(self): + print ("Hello %s" % self.edit.text()) + + if __name__ == '__main__': + # Create the Qt Application + app = QApplication(sys.argv) + # Create and show the form + form = Form() + form.show() + # Run the main Qt loop + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/basictutorial/qml.rst b/sources/pyside2/doc/tutorials/basictutorial/qml.rst new file mode 100644 index 000000000..0b26b3b83 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/qml.rst @@ -0,0 +1,63 @@ +Your First Application Using PySide2 and QtQuick/QML +***************************************************** + +QML is a declarative language that lets you develop applications +faster than with traditional languages. It is ideal for designing the +UI of your applicataion because of its declarative nature. In QML, a +user interface is specified as a tree of objects with properties. In +this tutorial, we will show how to make a simple "Hello World" +application with PySide2 and QML. + +A PySide2/QML application consists, at least, of two different files - +a file with the QML description of the user interface, and a python file +that loads the QML file. To make things easier, let's save both files in +the same directory. + +Here is a simple QML file called `view.qml`: +:: + import QtQuick 2.0 + + Rectangle { + width: 200 + height: 200 + color: "green" + + Text { + text: "Hello World" + anchors.centerIn: parent + } + } + +We start by importing `QtQuick 2.0`, which is a QML module. + +The rest of the QML code is pretty straightforward for those who +have previously used HTML or XML files. Basically, we are creating +a green rectangle with the size `200*200`, and adding a Text element +that reads "Hello World". The code `anchors.centerIn: parent` makes +the text appear centered in relation to its immediate parent, which +is the Rectangle in this case. + +Now, let's see how the code looks on the PySide2. +Let's call it `main.py`: +:: + from PySide2.QtWidgets import QApplication + from PySide2.QtQuick import QQuickView + from PySide2.QtCore import QUrl + + app = QApplication([]) + view = QQuickView() + url = QUrl("view.qml") + + view.setSource(url) + view.show() + app.exec_() + +If you are already familiar with PySide2 and have followed our +tutorials, you have already seen much of this code. +The only novelties are that you must `import QtQuick` and set the +source of the `QQuickView` object to the URL of your QML file. +Then, as any Qt widget, you call `QQuickView.show()`. + +.. note:: If you are programming for desktop, you should consider + adding `view.setResizeMode(QQuickView.SizeRootObjectToView)` + before showing the view. diff --git a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst new file mode 100644 index 000000000..00731abc3 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst @@ -0,0 +1,166 @@ +Using UI Files +*************** + +This page describes the use of Qt Creator to create graphical +interfaces for your Qt for Python project. +You will need **Qt Creator** to design and modify your interface (UI file). + +If you don't know how to use Qt Creator, refer to the +`Using Qt Designer <http://doc.qt.io/qtcreator/creator-using-qt-designer.html>`_ +documentation page. + +At Qt Creator, create a new Qt Design Form, choose "Main Window" for template. +And save as `mainwindow.ui`. +Add a `QPushButton` to the center of the centralwidget. + +Your file (mainwindow.ui) should look something like this: +:: + <?xml version="1.0" encoding="UTF-8"?> + <ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralWidget"> + <widget class="QPushButton" name="pushButton"> + <property name="geometry"> + <rect> + <x>110</x> + <y>80</y> + <width>201</width> + <height>81</height> + </rect> + </property> + <property name="text"> + <string>PushButton</string> + </property> + </widget> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>20</height> + </rect> + </property> + </widget> + <widget class="QToolBar" name="mainToolBar"> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + </widget> + <widget class="QStatusBar" name="statusBar"/> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> + </ui> + +Now we are ready to decide how to use the **UI file** from Python. + +Generating a Python class +========================= + +Another option to interact with a **UI file** is to generate a Python +class from it. This is possible thanks to the `pyside2-uic` tool. +To use this tool, you need to run the following command on a console: +:: + pyside2-uic mainwindow.ui > ui_mainwindow.py + +We redirect all the output of the command to a file called `ui_mainwindow.py`, +which will be imported directly: +:: + from ui_mainwindow import Ui_MainWindow + +Now to use it, we should create a personalized class for our widget +to **setup** this generated design. + +To understand the idea, let's take a look at the whole code: +:: + import sys + from PySide2.QtWidgets import QApplication, QMainWindow + from PySide2.QtCore import QFile + from ui_mainwindow import Ui_MainWindow + + class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + + if __name__ == "__main__": + app = QApplication(sys.argv) + + window = MainWindow() + window.show() + + sys.exit(app.exec_()) + +What is inside the *if* statement is already known from the previous +examples, and our new basic class contains only two new lines +that are in charge of loading the generated python class from the UI +file: +:: + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + +.. note:: You must run `pyside2-uic` again every time you make changes +to the **UI file**. + +Loading it directly +==================== + +To load the UI file directly, we will need a class from the **QtUiTools** +module: +:: + from PySide2.QtUiTools import QUiLoader + +The `QUiLoader` lets us load the **ui file** dynamically +and use it right away: +:: + ui_file = QFile("mainwindow.ui") + ui_file.open(QFile.ReadOnly) + + loader = QUiLoader() + window = loader.load(ui_file) + window.show() + +The complete code of this example looks like this: +:: + # File: main.py + import sys + from PySide2.QtUiTools import QUiLoader + from PySide2.QtWidgets import QApplication + from PySide2.QtCore import QFile + + if __name__ == "__main__": + app = QApplication(sys.argv) + + ui_file = QFile("mainwindow.ui") + ui_file.open(QFile.ReadOnly) + + loader = QUiLoader() + window = loader.load(ui_file) + ui_file.close() + window.show() + + sys.exit(app.exec_()) + +Then to execute it we just need to run the following on a +command prompt: +:: + python main.py diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgets.rst b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst new file mode 100644 index 000000000..80c137cac --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst @@ -0,0 +1,40 @@ +Your First QtWidgets Application +********************************* + +As with any other programming framework, +you start with the traditional "Hello World" program. + +Here is a simple example of a Hello World application in PySide2: +:: + import sys + from PySide2.QtWidgets import QApplication, QLabel + + app = QApplication(sys.argv) + label = QLabel("Hello World!") + label.show() + app.exec_() + + +For a widget application using PySide2, you must always start by +importing the appropriate class from the `PySide2.QtWidgets` module. + +After the imports, you create a `QApplication` instance. As Qt can +receive arguments from command line, you may pass any argument to +the QApplication object. Usually, you don't need to pass any +arguments so you can leave it as is, or use the following approach: +:: + app = QApplication([]) + +After the creation of the application object, we have created a +`QLabel` object. A `QLabel` is a widget that can present text +(simple or rich, like html), and images: +:: + # This HTML approach will be valid too! + label = QLabel("<font color=red size=40>Hello World!</font>") + +.. note:: After the creation of the label, we are calling the +method `show()` to show the label. + +Finally, we call `app.exec_()` to enter the Qt main loop and start +to execute the Qt code. In reality, it is only here where the label +is shown, but this can be ignored for now. diff --git a/sources/pyside2/doc/tutorials/index.rst b/sources/pyside2/doc/tutorials/index.rst index c09b48ab5..5b1eb9fe3 100644 --- a/sources/pyside2/doc/tutorials/index.rst +++ b/sources/pyside2/doc/tutorials/index.rst @@ -21,5 +21,10 @@ Tutorials .. toctree:: :maxdepth: 2 + basictutorial/widgets.rst + basictutorial/qml.rst + basictutorial/clickablebutton.rst + basictutorial/dialog.rst + basictutorial/uifiles.rst qmltutorial/index.rst qmladvancedtutorial/index.rst |