{"id":5176,"date":"2022-10-10T08:35:22","date_gmt":"2022-10-10T08:35:22","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=5176"},"modified":"2022-10-11T00:45:26","modified_gmt":"2022-10-11T00:45:26","slug":"pyqt-qmenu","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qmenu\/","title":{"rendered":"PyQt QMenu"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to use the PyQt <code>QMenu<\/code> class to create a menu for the application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-pyqt-qmenu-class'>Introduction to PyQt QMenu class <a href=\"#introduction-to-pyqt-qmenu-class\" class=\"anchor\" id=\"introduction-to-pyqt-qmenu-class\" title=\"Anchor for Introduction to PyQt QMenu class\">#<\/a><\/h2>\n\n\n\n<p>The <code>QMenu<\/code> class allows you to create a menu widget in menu bars, context menus, and popup menus. This tutorial focuses on how to use the <code>QMenu<\/code> class to create menus in menu bars.<\/p>\n\n\n\n<p>To create a menu and add it to a menu bar, you follow these steps: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Get the menu bar of the main window by calling the <code>menuBar()<\/code> method of the <code>QMainWindow<\/code> object.<\/li><li>Add a menu to the menu bar using the <code><code>addMenu()<\/code><\/code> method. The <code><code>addMenu()<\/code><\/code> returns a new instance of the <code>QMenu<\/code> class.<\/li><\/ul>\n\n\n\n<p>The following shows how to add three menus to the menu bar of the main window including File, Edit, and Help:<\/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\">menu_bar = self.menuBar()\n\nfile_menu = menu_bar.addMenu(<span class=\"hljs-string\">'&amp;File'<\/span>)\nedit_menu = menu_bar.addMenu(<span class=\"hljs-string\">'&amp;Edit'<\/span>)\nhelp_menu = menu_bar.addMenu(<span class=\"hljs-string\">'&amp;Help'<\/span>)<\/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>Note that the ampersand (<code>&amp;<\/code>) defines a shortcut to jump to the menu when pressing the <code>Alt<\/code> key. For example, to jump to the File menu, you press the Alt-F keyboard shortcut.<\/p>\n\n\n\n<p>Once having a menu, you can add items to it. Typically, you create a <code>QAction<\/code> and use the <code>addAction()<\/code> method of the <code>QMenu<\/code> object to add actions to the menu.<\/p>\n\n\n\n<p>To add a separator between menu items, you use the <code>addSeparator()<\/code> method of the <code>QMenu<\/code> object. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='pyqt-qmenu-example'>PyQt QMenu example <a href=\"#pyqt-qmenu-example\" class=\"anchor\" id=\"pyqt-qmenu-example\" title=\"Anchor for PyQt QMenu example\">#<\/a><\/h2>\n\n\n\n<p>We&#8217;ll create a text editor application to demonstrate how to use the <code>QMenu<\/code> class:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"752\" height=\"496\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Example.png\" alt=\"PyQt QMenu Example\" class=\"wp-image-5177\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Example.png 752w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Example-300x198.png 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><\/figure>\n\n\n\n<p class=\"note\">Note that the icons used in this application are from <a href=\"https:\/\/icons8.com\/icon\/set\/open-file\/fluency\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">icon8.com website<\/a>. Also, you can download <a href=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/assets.zip\" target=\"_blank\" rel=\"noreferrer noopener\">them here<\/a>.<\/p>\n\n\n\n<p>Here&#8217;s the complete program:<\/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\"><span class=\"hljs-keyword\">import<\/span> sys\r\n<span class=\"hljs-keyword\">from<\/span> pathlib <span class=\"hljs-keyword\">import<\/span> Path\r\n<span class=\"hljs-keyword\">from<\/span> PyQt6.QtWidgets <span class=\"hljs-keyword\">import<\/span> QApplication, QMainWindow, QTextEdit, QFileDialog, QMessageBox, QWidget, QVBoxLayout\r\n<span class=\"hljs-keyword\">from<\/span> PyQt6.QtGui <span class=\"hljs-keyword\">import<\/span> QIcon, QAction\r\n\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MainWindow<\/span><span class=\"hljs-params\">(QMainWindow)<\/span>:<\/span>\r\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>\r\n        super().__init__(*args, **kwargs)\r\n\r\n        self.setWindowIcon(QIcon(<span class=\"hljs-string\">'.\/assets\/editor.png'<\/span>))\r\n        self.setGeometry(<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-number\">100<\/span>, <span class=\"hljs-number\">500<\/span>, <span class=\"hljs-number\">300<\/span>)\r\n        m = <span class=\"hljs-number\">30<\/span>\r\n\r\n        self.title = <span class=\"hljs-string\">'Editor'<\/span>\r\n        self.filters = <span class=\"hljs-string\">'Text Files (*.txt)'<\/span>\r\n\r\n        self.set_title()\r\n\r\n        self.path = <span class=\"hljs-literal\">None<\/span>\r\n\r\n        self.text_edit = QTextEdit(self)\r\n        <span class=\"hljs-comment\"># self.setCentralWidget(self.text_edit)<\/span>\r\n\r\n        container = QWidget(self)\r\n        container.setLayout(QVBoxLayout())\r\n        container.layout().addWidget(self.text_edit)\r\n        self.setCentralWidget(container)\r\n        <span class=\"hljs-comment\"># container.setContentsMargins(5, 5, 5, 5)<\/span>\r\n\r\n        menu_bar = self.menuBar()\r\n\r\n        file_menu = menu_bar.addMenu(<span class=\"hljs-string\">'&amp;File'<\/span>)\r\n        edit_menu = menu_bar.addMenu(<span class=\"hljs-string\">'&amp;Edit'<\/span>)\r\n        help_menu = menu_bar.addMenu(<span class=\"hljs-string\">'&amp;Help'<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># new menu item<\/span>\r\n        new_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/new.png'<\/span>), <span class=\"hljs-string\">'&amp;New'<\/span>, self)\r\n        new_action.setStatusTip(<span class=\"hljs-string\">'Create a new document'<\/span>)\r\n        new_action.setShortcut(<span class=\"hljs-string\">'Ctrl+N'<\/span>)\r\n        new_action.triggered.connect(self.new_document)\r\n        file_menu.addAction(new_action)\r\n\r\n        <span class=\"hljs-comment\"># open menu item<\/span>\r\n        open_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/open.png'<\/span>), <span class=\"hljs-string\">'&amp;Open...'<\/span>, self)\r\n        open_action.triggered.connect(self.open_document)\r\n        open_action.setStatusTip(<span class=\"hljs-string\">'Open a document'<\/span>)\r\n        open_action.setShortcut(<span class=\"hljs-string\">'Ctrl+O'<\/span>)\r\n        file_menu.addAction(open_action)\r\n\r\n        <span class=\"hljs-comment\"># save menu item<\/span>\r\n        save_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/save.png'<\/span>), <span class=\"hljs-string\">'&amp;Save'<\/span>, self)\r\n        save_action.setStatusTip(<span class=\"hljs-string\">'Save the document'<\/span>)\r\n        save_action.setShortcut(<span class=\"hljs-string\">'Ctrl+S'<\/span>)\r\n        save_action.triggered.connect(self.save_document)\r\n        file_menu.addAction(save_action)\r\n\r\n        file_menu.addSeparator()\r\n\r\n        <span class=\"hljs-comment\"># exit menu item<\/span>\r\n        exit_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/exit.png'<\/span>), <span class=\"hljs-string\">'&amp;Exit'<\/span>, self)\r\n        exit_action.setStatusTip(<span class=\"hljs-string\">'Exit'<\/span>)\r\n        exit_action.setShortcut(<span class=\"hljs-string\">'Alt+F4'<\/span>)\r\n        exit_action.triggered.connect(self.quit)\r\n        file_menu.addAction(exit_action)\r\n\r\n        <span class=\"hljs-comment\"># edit menu<\/span>\r\n        undo_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/undo.png'<\/span>), <span class=\"hljs-string\">'&amp;Undo'<\/span>, self)\r\n        undo_action.setStatusTip(<span class=\"hljs-string\">'Undo'<\/span>)\r\n        undo_action.setShortcut(<span class=\"hljs-string\">'Ctrl+Z'<\/span>)\r\n        undo_action.triggered.connect(self.text_edit.undo)\r\n        edit_menu.addAction(undo_action)\r\n\r\n        redo_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/redo.png'<\/span>), <span class=\"hljs-string\">'&amp;Redo'<\/span>, self)\r\n        redo_action.setStatusTip(<span class=\"hljs-string\">'Redo'<\/span>)\r\n        redo_action.setShortcut(<span class=\"hljs-string\">'Ctrl+Y'<\/span>)\r\n        redo_action.triggered.connect(self.text_edit.redo)\r\n        edit_menu.addAction(redo_action)\r\n\r\n        about_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/about.png'<\/span>), <span class=\"hljs-string\">'About'<\/span>, self)\r\n        help_menu.addAction(about_action)\r\n        about_action.setStatusTip(<span class=\"hljs-string\">'About'<\/span>)\r\n        about_action.setShortcut(<span class=\"hljs-string\">'F1'<\/span>)\r\n\r\n        <span class=\"hljs-comment\"># status bar<\/span>\r\n        self.status_bar = self.statusBar()\r\n        self.show()\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">set_title<\/span><span class=\"hljs-params\">(self, filename=None)<\/span>:<\/span>\r\n        title = <span class=\"hljs-string\">f\"<span class=\"hljs-subst\">{filename <span class=\"hljs-keyword\">if<\/span> filename <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-string\">'Untitled'<\/span>}<\/span> - <span class=\"hljs-subst\">{self.title}<\/span>\"<\/span>\r\n        self.setWindowTitle(title)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">confirm_save<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> self.text_edit.document().isModified():\r\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">True<\/span>\r\n\r\n        message = <span class=\"hljs-string\">f\"Do you want to save changes to <span class=\"hljs-subst\">{self.path <span class=\"hljs-keyword\">if<\/span> self.path <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-string\">'Untitled'<\/span>}<\/span>?\"<\/span>\r\n        MsgBoxBtn = QMessageBox.StandardButton\r\n        MsgBoxBtn = MsgBoxBtn.Save | MsgBoxBtn.Discard | MsgBoxBtn.Cancel\r\n\r\n        button = QMessageBox.question(\r\n            self, self.title, message, buttons=MsgBoxBtn\r\n        )\r\n\r\n        <span class=\"hljs-keyword\">if<\/span> button == MsgBoxBtn.Cancel:\r\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">False<\/span>\r\n\r\n        <span class=\"hljs-keyword\">if<\/span> button == MsgBoxBtn.Save:\r\n            self.save_document()\r\n\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">True<\/span>\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">new_document<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> self.confirm_save():\r\n            self.text_edit.clear()\r\n            self.set_title()\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">save_document<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-comment\"># save the currently openned file<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> (self.path):\r\n            <span class=\"hljs-keyword\">return<\/span> self.path.write_text(self.text_edit.toPlainText())\r\n\r\n        <span class=\"hljs-comment\"># save a new file<\/span>\r\n        filename, _ = QFileDialog.getSaveFileName(\r\n            self, <span class=\"hljs-string\">'Save File'<\/span>, filter=self.filters\r\n        )\r\n\r\n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> filename:\r\n            <span class=\"hljs-keyword\">return<\/span>\r\n\r\n        self.path = Path(filename)\r\n        self.path.write_text(self.text_edit.toPlainText())\r\n        self.set_title(filename)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">open_document<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        filename, _ = QFileDialog.getOpenFileName(self, filter=self.filters)\r\n        <span class=\"hljs-keyword\">if<\/span> filename:\r\n            self.path = Path(filename)\r\n            self.text_edit.setText(self.path.read_text())\r\n            self.set_title(filename)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">quit<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> self.confirm_save():\r\n            self.destroy()\r\n\r\n\r\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">'__main__'<\/span>:\r\n    <span class=\"hljs-keyword\">try<\/span>:\r\n        <span class=\"hljs-keyword\">import<\/span> ctypes\r\n        myappid = <span class=\"hljs-string\">'mycompany.myproduct.subproduct.version'<\/span>\r\n        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)\r\n    <span class=\"hljs-keyword\">finally<\/span>:\r\n        app = QApplication(sys.argv)\r\n        window = MainWindow()\r\n        sys.exit(app.exec())\r\n<\/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>How it works.<\/p>\n\n\n\n<p>First, create the main window using the <code>QMainWindow<\/code> class:<\/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\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MainWindow<\/span><span class=\"hljs-params\">(QMainWindow)<\/span>:<\/span><\/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>Second, set the window&#8217;s icon and geometry:<\/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\">self.setWindowIcon(QIcon(<span class=\"hljs-string\">'.\/assets\/editor.png'<\/span>))\nself.setGeometry(<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-number\">100<\/span>, <span class=\"hljs-number\">500<\/span>, <span class=\"hljs-number\">300<\/span>)<\/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>Third, initialize the text file filters, and window title, and call the <code>set_title()<\/code> method to set the title for the window:<\/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\">self.filters = <span class=\"hljs-string\">'Text Files (*.txt)'<\/span>\nself.title = <span class=\"hljs-string\">'Editor'<\/span>\nself.set_title()<\/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>The <code><code>set_title()<\/code><\/code> method accepts a filename. If the filename is omitted, the <code><code>set_title()<\/code><\/code> method sets the window&#8217;s title as <code>Untitled - Editor<\/code>. Otherwise, it sets the window title using the format <code>filename - Editor<\/code>:<\/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\">set_title<\/span><span class=\"hljs-params\">(self, filename=None)<\/span>:<\/span>\n    title = <span class=\"hljs-string\">f\"<span class=\"hljs-subst\">{filename <span class=\"hljs-keyword\">if<\/span> filename <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-string\">'Untitled'<\/span>}<\/span> - <span class=\"hljs-subst\">{self.title}<\/span>\"<\/span>\n    self.setWindowTitle(title)<\/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>For example, when you launch the program for the first time or create a new file, the window&#8217;s title will be:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"752\" height=\"47\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Default-Window-Title.png\" alt=\"PyQt QMenu - Default Window Title\" class=\"wp-image-5179\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Default-Window-Title.png 752w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Default-Window-Title-300x19.png 300w\" sizes=\"auto, (max-width: 752px) 100vw, 752px\" \/><\/figure>\n\n\n\n<p>If you open a file e.g., C:\/temp\/<code>test.txt<\/code>, the window&#8217;s title will change to:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"748\" height=\"52\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Window-Title-with-Filename.png\" alt=\"PyQt QMenu - Window Title with Filename\" class=\"wp-image-5180\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Window-Title-with-Filename.png 748w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Window-Title-with-Filename-300x21.png 300w\" sizes=\"auto, (max-width: 748px) 100vw, 748px\" \/><\/figure>\n\n\n\n<p>Fourth, initialize a variable that will hold the path of the file that is being opened for editing:<\/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\">self.path = <span class=\"hljs-literal\">None<\/span><\/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<p>Note that we&#8217;ll use the <code><a href=\"https:\/\/www.pythontutorial.net\/python-standard-library\/python-path\/\">Path<\/a><\/code> class from the <code>pathlib<\/code> module to manage the file path, reading from a text file, and writing to the text file.<\/p>\n\n\n\n<p>Fifth, create a <code>QTextEdit<\/code> widget and set it as the central widget of the main window:<\/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\">self.text_edit = QTextEdit(self)\nself.setCentralWidget(self.text_edit)<\/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>Sixth, create a <code>QMenuBar<\/code> object by calling the <code>menuBar()<\/code> method of the <code>QMainWindow<\/code> object:<\/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\">menu_bar = self.menuBar()<\/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>Seventh, create new, open, save, and exit actions and add them to the <code>file_menu<\/code> using the <code>addAction()<\/code> method.<\/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\"><span class=\"hljs-comment\"># new menu item<\/span>\nnew_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/new.png'<\/span>), <span class=\"hljs-string\">'&amp;New'<\/span>, self)\nnew_action.setStatusTip(<span class=\"hljs-string\">'Create a new document'<\/span>)\nnew_action.setShortcut(<span class=\"hljs-string\">'Ctrl+N'<\/span>)\nnew_action.triggered.connect(self.new_document)\nfile_menu.addAction(new_action)\n\n<span class=\"hljs-comment\"># open menu item<\/span>\nopen_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/open.png'<\/span>), <span class=\"hljs-string\">'&amp;Open...'<\/span>, self)\nopen_action.triggered.connect(self.open_document)\nopen_action.setStatusTip(<span class=\"hljs-string\">'Open a document'<\/span>)\nopen_action.setShortcut(<span class=\"hljs-string\">'Ctrl+O'<\/span>)\nfile_menu.addAction(open_action)\n\n<span class=\"hljs-comment\"># save menu item<\/span>\nsave_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/save.png'<\/span>), <span class=\"hljs-string\">'&amp;Save'<\/span>, self)\nsave_action.setStatusTip(<span class=\"hljs-string\">'Save the document'<\/span>)\nsave_action.setShortcut(<span class=\"hljs-string\">'Ctrl+S'<\/span>)\nsave_action.triggered.connect(self.save_document)\nfile_menu.addAction(save_action)\n\nfile_menu.addSeparator()\n\n<span class=\"hljs-comment\"># exit menu item<\/span>\nexit_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/exit.png'<\/span>), <span class=\"hljs-string\">'&amp;Exit'<\/span>, self)\nexit_action.setStatusTip(<span class=\"hljs-string\">'Exit'<\/span>)\nexit_action.setShortcut(<span class=\"hljs-string\">'Alt+F4'<\/span>)\nexit_action.triggered.connect(self.quit)\nfile_menu.addAction(exit_action)<\/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>It&#8217;ll result in the following menu:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"258\" height=\"247\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-File-Menu.png\" alt=\"\" class=\"wp-image-5181\"\/><\/figure>\n\n\n\n<p>Eighth, create undo and redo actions and add them to the edit menu:<\/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\"><span class=\"hljs-comment\"># edit menu<\/span>\nundo_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/undo.png'<\/span>), <span class=\"hljs-string\">'&amp;Undo'<\/span>, self)\nundo_action.setStatusTip(<span class=\"hljs-string\">'Undo'<\/span>)\nundo_action.setShortcut(<span class=\"hljs-string\">'Ctrl+Z'<\/span>)\nundo_action.triggered.connect(self.text_edit.undo)\nedit_menu.addAction(undo_action)\n\nredo_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/redo.png'<\/span>), <span class=\"hljs-string\">'&amp;Redo'<\/span>, self)\nredo_action.setStatusTip(<span class=\"hljs-string\">'Redo'<\/span>)\nredo_action.setShortcut(<span class=\"hljs-string\">'Ctrl+Y'<\/span>)\nredo_action.triggered.connect(self.text_edit.redo)\nedit_menu.addAction(redo_action)<\/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>It&#8217;ll result in the following Edit menu:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"302\" height=\"197\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Edit-Menu.png\" alt=\"\" class=\"wp-image-5182\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Edit-Menu.png 302w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Edit-Menu-300x196.png 300w\" sizes=\"auto, (max-width: 302px) 100vw, 302px\" \/><\/figure>\n\n\n\n<p>Ninth, create the about action and add it to the Help menu:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">about_action = QAction(QIcon(<span class=\"hljs-string\">'.\/assets\/about.png'<\/span>), <span class=\"hljs-string\">'About'<\/span>, self)\nhelp_menu.addAction(about_action)\nabout_action.setStatusTip(<span class=\"hljs-string\">'About'<\/span>)\nabout_action.setShortcut(<span class=\"hljs-string\">'F1'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><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>It&#8217;ll result in the following menu:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"323\" height=\"159\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-About-Menu.png\" alt=\"\" class=\"wp-image-5183\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-About-Menu.png 323w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-About-Menu-300x148.png 300w\" sizes=\"auto, (max-width: 323px) 100vw, 323px\" \/><\/figure>\n\n\n\n<p>Tenth, add the status bar to the main window using the <code>statusBar()<\/code> method of the <code>QMainWindow<\/code> object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">self.status_bar = self.statusBar()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><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>Note that you&#8217;ll learn more about the status bar widget in the <a href=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qstatusbar\/\"><code>QStatusBar<\/code> tutorial<\/a>.<\/p>\n\n\n\n<p>Eleventh, define the <code>confirm_save()<\/code> method that prompts the user whether to save the document or not. If the user clicks the Yes button, call the <code>save_document()<\/code> method to save the text of the <code>QTextEdit<\/code> widget into a file. <\/p>\n\n\n\n<p>The <code>confirm_save()<\/code> method returns <code>False<\/code> if the user clicks the Cancel button or <code>True<\/code> if the user clicks either <code>Yes<\/code> or <code>No<\/code> button:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"443\" height=\"186\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Confirm-Save-Dialog.png\" alt=\"\" class=\"wp-image-5203\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Confirm-Save-Dialog.png 443w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/10\/PyQt-QMenu-Confirm-Save-Dialog-300x126.png 300w\" sizes=\"auto, (max-width: 443px) 100vw, 443px\" \/><\/figure>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" 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\">confirm_save<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> self.text_edit.document().isModified():\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">True<\/span>\r\n\r\n    message = <span class=\"hljs-string\">f\"Do you want to save changes to <span class=\"hljs-subst\">{self.path <span class=\"hljs-keyword\">if<\/span> self.path <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-string\">'Untitled'<\/span>}<\/span>?\"<\/span>\r\n    MsgBoxBtn = QMessageBox.StandardButton\r\n    MsgBoxBtn = MsgBoxBtn.Save | MsgBoxBtn.Discard | MsgBoxBtn.Cancel\r\n\r\n    button = QMessageBox.question(\r\n        self, self.title, message, buttons=MsgBoxBtn\r\n    )\r\n\r\n    <span class=\"hljs-keyword\">if<\/span> button == MsgBoxBtn.Cancel:\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">False<\/span>\r\n\r\n    <span class=\"hljs-keyword\">if<\/span> button == MsgBoxBtn.Save:\r\n        self.save_document()\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">True<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><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>Twelfth, define the <code>new_document()<\/code> method that runs when the user selects the New menu item:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" 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\">new_document<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n    <span class=\"hljs-keyword\">if<\/span> self.confirm_save():\n        self.text_edit.setText(<span class=\"hljs-string\">''<\/span>)\n        self.set_title()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><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>The <code>new_document()<\/code> method calls the <code>confirm_save()<\/code> method to save the document and set the text of the <code>QTextEdit<\/code> to blank. Also, it resets the title of the main window.<\/p>\n\n\n\n<p>Thirteenth, define the <code>save_document()<\/code> method to save the text of the <code>QTextEdit<\/code> widget to a text file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" 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\">save_document<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n    <span class=\"hljs-comment\"># save the currently openned file<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (self.path):\n        <span class=\"hljs-keyword\">return<\/span> self.path.write_text(self.text_edit.toPlainText())\n\n    <span class=\"hljs-comment\"># save a new file<\/span>\n    filename, _ = QFileDialog.getSaveFileName(\n        self, <span class=\"hljs-string\">'Save File'<\/span>, filter=self.filters\n    )\n\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> filename:\n        <span class=\"hljs-keyword\">return<\/span>\n\n    self.path = Path(filename)\n    self.path.write_text(self.text_edit.toPlainText())\n    self.set_title(filename)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><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>If the user opens a file, then the <code>self.path<\/code> is not <code><a href=\"https:\/\/www.pythontutorial.net\/advanced-python\/python-none\/\">None<\/a><\/code>, it gets the text of the <code>QTextEdit<\/code> widget by calling the <code>toPlainText()<\/code> method and saves the text to the file specified by the Path object using the <code>write_text()<\/code> method.<\/p>\n\n\n\n<p>If the user has not opened a file, the method shows a Save File Dialog using the <code>QFileDialog<\/code> and writes the text to the file that is currently opened.<\/p>\n\n\n\n<p>Fourteenth, define the <code>open_document()<\/code> method that shows the Open File Dialog and loads the contents from a text file into the <code>QTextEdit<\/code> widget:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" 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\">open_document<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n    filename, _ = QFileDialog.getOpenFileName(self, filter=self.filters)\n    <span class=\"hljs-keyword\">if<\/span> filename:\n        self.path = Path(filename)\n        self.text_edit.setText(self.path.read_text())\n        self.set_title(filename)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><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>Since the filename changes, it calls the <code>set_title()<\/code> method to set the title of the <code>QMainWindow<\/code>.<\/p>\n\n\n\n<p>Fifteenth, define the <code>quit()<\/code> method that runs when the user selects the Exit menu item:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" 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\">quit<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n    <span class=\"hljs-keyword\">if<\/span> self.confirm_save():\n        self.destroy()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><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>Finally, if you run the program on Windows, the taskbar will not display the main window icon correctly. To fix it, you use the following code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> ctypes\nmyappid = <span class=\"hljs-string\">'mycompany.myproduct.subproduct.version'<\/span>\nctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If you execute the program in macOS or Linux, this code will raise an import error. Therefore, we wrap it into a <code>try<\/code>  block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">try<\/span>:\r\n    <span class=\"hljs-keyword\">import<\/span> ctypes\r\n    myappid = <span class=\"hljs-string\">'mycompany.myproduct.subproduct.version'<\/span>\r\n    ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)\r\n<span class=\"hljs-attr\">finally<\/span>:\r\n    app = QApplication(sys.argv)\r\n    <span class=\"hljs-built_in\">window<\/span> = MainWindow()\r\n    sys.exit(app.exec())<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\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>Qt uses the <code>QMenu<\/code> class to represent a menu widget.<\/li><li>Use the <code>menuBar()<\/code> method of the <code>QMainWindow<\/code> to create a menu bar and <code>addMenu()<\/code> method to add a new menu bar.<\/li><li>Use the <code>addAction()<\/code> method of the <code>QMenu<\/code> object to add an item to a menu.<\/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=\"5176\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qmenu\/\"\n\t\t\t\tdata-post-title=\"PyQt QMenu\"\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=\"5176\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/pyqt\/pyqt-qmenu\/\"\n\t\t\t\tdata-post-title=\"PyQt QMenu\"\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 how to use the PyQt QMenu class to create a menu for the application.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":4862,"menu_order":26,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-5176","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/5176","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=5176"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/5176\/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=5176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}