{"id":4879,"date":"2022-09-16T09:15:46","date_gmt":"2022-09-16T09:15:46","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=4879"},"modified":"2022-10-29T07:35:35","modified_gmt":"2022-10-29T07:35:35","slug":"pyqt-signals-slots","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-signals-slots\/","title":{"rendered":"PyQt Signals &#038; Slots"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn about PyQt signals &amp; slots and how they work in PyQt applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-the-pyqt-signals-and-slots'>Introduction to the PyQT signals and slots <a href=\"#introduction-to-the-pyqt-signals-and-slots\" class=\"anchor\" id=\"introduction-to-the-pyqt-signals-and-slots\" title=\"Anchor for Introduction to the PyQT signals and slots\">#<\/a><\/h2>\n\n\n\n<p>Typically, a Python script runs from the top to the bottom as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Get inputs.<\/li><li>Process the inputs to produce outputs.<\/li><li>Write the outputs to the screen or a file.<\/li><\/ul>\n\n\n\n<p>This is called <em>procedure programming<\/em>. <\/p>\n\n\n\n<p>When you create a GUI program, you use <em>event-driven programming <\/em>instead. In the event-driven programming paradigm, a program has the following flow:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Create widgets like <a href=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qlabel\/\">labels<\/a>, <a href=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qlineedit\/\">line edits<\/a>, and <a href=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qpushbutton\/\">buttons<\/a>.<\/li><li>Start an event loop that waits for events.<\/li><li>Respond to events when they occur by executing <a href=\"https:\/\/www.pythontutorial.net\/python-built-in-functions\/python-callable\/\">callables<\/a>.<\/li><\/ul>\n\n\n\n<p class=\"note\">Note that a callable is a <a href=\"https:\/\/www.pythontutorial.net\/python-basics\/python-functions\/\">function<\/a>, a <a href=\"https:\/\/www.pythontutorial.net\/python-oop\/python-methods\/\">method<\/a>, or an object that implements the <code>__call__()<\/code> method.<\/p>\n\n\n\n<p>To connect events with callables of the program, PyQt uses the <em>signals and slots <\/em>mechanism.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id='signals'>Signals <a href=\"#signals\" class=\"anchor\" id=\"signals\" title=\"Anchor for Signals\">#<\/a><\/h3>\n\n\n\n<p>A signal is a special property of an object that is emitted when an event occurs. An event may be a user action, a timeout, or the completion of an asynchronous operation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id='slots'>Slots <a href=\"#slots\" class=\"anchor\" id=\"slots\" title=\"Anchor for Slots\">#<\/a><\/h3>\n\n\n\n<p>A slot is a <a href=\"https:\/\/www.pythontutorial.net\/python-built-in-functions\/python-callable\/\">callable<\/a> that can receive a signal and respond to it. <\/p>\n\n\n\n<p>To respond to events, you connect signals to slots. When you connect a signal to a slot, the slot will be executed when the signal is emitted. <\/p>\n\n\n\n<p>In PyQt, all subclasses of the <code>QObject<\/code> class can send and receive signals. Almost all classes in PyQt are subclasses of the <code>QObject<\/code> class.<\/p>\n\n\n\n<p>Let&#8217;s take an example to understand how the PyQt signals &amp; slots mechanism works.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='pyqt-signals-slots-example'>PyQt signals &amp; slots example <a href=\"#pyqt-signals-slots-example\" class=\"anchor\" id=\"pyqt-signals-slots-example\" title=\"Anchor for PyQt signals &amp; slots example\">#<\/a><\/h2>\n\n\n\n<p>The following program displays a window that has a button. When you click the button, the program shows the <code>clicked<\/code> message in the console:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> sys\n<span class=\"hljs-keyword\">from<\/span> PyQt6.QtWidgets <span class=\"hljs-keyword\">import<\/span> (\n    QApplication,\n    QWidget,\n    QLineEdit,\n    QPushButton,\n    QVBoxLayout\n)\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MainWindow<\/span><span class=\"hljs-params\">(QWidget)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, *args, **kwargs)<\/span>:<\/span>\n        super().__init__(*args, **kwargs)\n\n        <span class=\"hljs-comment\"># set the window title<\/span>\n        self.setWindowTitle(<span class=\"hljs-string\">'Qt Signals &amp; Slots'<\/span>)\n\n        <span class=\"hljs-comment\"># create a button widget and connect its clicked signal<\/span>\n        <span class=\"hljs-comment\"># to a method<\/span>\n        button = QPushButton(<span class=\"hljs-string\">'Click me'<\/span>)\n        button.clicked.connect(self.button_clicked)\n\n        <span class=\"hljs-comment\"># place the buton on window using a vertical box layout<\/span>\n        layout = QVBoxLayout()\n        self.setLayout(layout)\n\n        layout.addWidget(button)\n\n        <span class=\"hljs-comment\"># show the window<\/span>\n        self.show()\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">button_clicked<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n        print(<span class=\"hljs-string\">'clicked'<\/span>)\n\n\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">'__main__'<\/span>:\n    app = QApplication(sys.argv)\n\n    <span class=\"hljs-comment\"># create the main window and display it<\/span>\n    window = MainWindow()\n\n    <span class=\"hljs-comment\"># start the event loop<\/span>\n    sys.exit(app.exec())<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How it works. (We&#8217;ll focus on the signals &amp; slots only)<\/p>\n\n\n\n<p>First, create a push button using the <code><a href=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qpushbutton\/\">QPushButton<\/a><\/code> widget:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">button = QPushButton(<span class=\"hljs-string\">'Click me'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, connect the <code>clicked<\/code> signal to the <code>on_clicked<\/code> method (slot):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">button.clicked.connect(self.button_clicked)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In general, the syntax for connecting a signal to a slot is as follows:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">sender_object.signal_name.connect(receiver_object.slot_name)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Also, you can connect a signal to a slot when passing a slot to a signal as a keyword argument. For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">button = QPushButton(<span class=\"hljs-string\">'Click me'<\/span>, clicked=self.button_clicked)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, define a method <code>on_clicked<\/code> that prints the clicked message to the terminal:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">on_clicked<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n    print(<span class=\"hljs-string\">'clicked'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>When you click the button, the <code>QPushButton<\/code> emits the clicked signal that executes the connected slot <code>on_clicked<\/code>. <\/p>\n\n\n\n<p>Note that the following code places the button on the window using the <a href=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qvboxlayout\/\">vertical box layout<\/a>. And you&#8217;ll learn more about it in the upcoming tutorial.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">layout = QVBoxLayout()\nself.setLayout(layout)\nlayout.addWidget(button)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='using-signals-that-send-data'>Using signals that send data <a href=\"#using-signals-that-send-data\" class=\"anchor\" id=\"using-signals-that-send-data\" title=\"Anchor for Using signals that send data\">#<\/a><\/h2>\n\n\n\n<p>A signal may carry data that provides the state of the object when the event occurs. For example, the <code>textChanged<\/code> signal of the <code><a href=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qlineedit\/\">QLineEdit<\/a><\/code> has the text entered in the widget.<\/p>\n\n\n\n<p>If a signal carries data, the connected slot can receive it. <\/p>\n\n\n\n<p>The following program shows <code>QLineEdit<\/code> and <code>QLabel<\/code> widgets. When you type something on the <code>QLineEdit<\/code>, the <code>QLabel<\/code> will display it accordingly:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> sys\n<span class=\"hljs-keyword\">from<\/span> PyQt6.QtWidgets <span class=\"hljs-keyword\">import<\/span> (\n    QApplication,\n    QWidget,\n    QLabel,\n    QLineEdit,\n    QVBoxLayout\n)\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MainWindow<\/span><span class=\"hljs-params\">(QWidget)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, *args, **kwargs)<\/span>:<\/span>\n        super().__init__(*args, **kwargs)\n\n        self.setWindowTitle(<span class=\"hljs-string\">'Qt Signals &amp; Slots'<\/span>)\n\n        <span class=\"hljs-comment\"># create widgets<\/span>\n        label = QLabel()\n        line_edit = QLineEdit()\n        line_edit.textChanged.connect(label.setText)\n\n        <span class=\"hljs-comment\"># place the widgets<\/span>\n        layout = QVBoxLayout()\n        layout.addWidget(label)\n        layout.addWidget(line_edit)\n        self.setLayout(layout)\n\n        <span class=\"hljs-comment\"># show the window<\/span>\n        self.show()\n\n\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">'__main__'<\/span>:\n    app = QApplication(sys.argv)\n    window = MainWindow()\n    sys.exit(app.exec())<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, create a <code>QLabel<\/code> widget. The <code>QLabel<\/code> widget has the <code>setText()<\/code> method that sets its contents.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">label = QLabel()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, create a new <code>QLineEdit<\/code> widget:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">line_edit = QLineEdit()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, connect the <code>textChanged<\/code> signal to the <code>setText<\/code> method of the <code>QLabel<\/code> object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">line_edit.textChanged.connect(label.setText)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>When you type something on the <code>QLineEdit<\/code>: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The <code>textChanged<\/code> signal sends the text <\/li><li>The <code>QLabel<\/code> receives the text and passes it to the <code>setText()<\/code> method.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>A signal is a special property of an object that is emitted when an event occurs.<\/li><li>A slot is a callable that can receive a signal and respond to it accordingly.<\/li><li>PyQt uses signals and slots to wire up events with callables.<\/li><\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"4879\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-signals-slots\/\"\n\t\t\t\tdata-post-title=\"PyQt Signals &#038; Slots\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"4879\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-signals-slots\/\"\n\t\t\t\tdata-post-title=\"PyQt Signals &#038; Slots\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn about PyQt signals &#038; slots and how they work in PyQt applications.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":4862,"menu_order":1,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-4879","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/4879","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=4879"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/4879\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/4862"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=4879"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}