Как сделать меню в питоне
Для создания иерархического меню в tkinter применяется виджет Menu . Основные параметры Menu:
activebackground : цвет активного пункта меню
activeborderwidth : толщина границы активного пункта меню
activeforeground : цвет текста активного пункта меню
background / bg : фоновый цвет
bd : толщина границы
cursor : курсор указателя мыши при наведении на меню
disabledforeground : цвет, когда меню находится в состоянии DISABLED
font : шрифт текста
foreground / fg : цвет текста
tearoff : меню может быть отсоединено от графического окна. В частности, при создании подменю а скриншоте можно увидеть прерывающуюся линию в верху подменю, за которую его можно отсоединить. Однако при значении tearoff=0 подменю не сможет быть отсоединено.
Меню может содержать много элементов, причем эти элементы сами могут представлять меню и содержать другие элементы. В зависимости от того, какой тип элементов мы хотим добавить в меню, будет отличаться метод, используемый для их добавления. В частности, нам доступны следующие методы:
add_command(options) : добавляет элемент меню через параметр options
add_cascade(options) : добавляет элемент меню, который в свою очередь может представлять подменю
add_separator() : добавляет линию-разграничитель
add_radiobutton(options) : добавляет в меню переключатель
add_checkbutton(options) : добавляет в меню флажок
Создадим простейшее меню:
Для добавления пунктов меню у объекта Menu вызывается метод add_cascade() . В этот метод передаются параметры пункта меню, в данном случае они представлены текстовой меткой, устанавливаемой через параметр label .
Но просто создать меню — еще недостаточно. Его надо установить для текущего окна с помощью параметра menu в методе config() . В итоге графическое окно будет иметь следующее меню:
Теперь добавим подменю:
Здесь определяется подменю file_menu, которое добавляется в первый пункт основного меню благодаря установке опции menu=file_menu :

Но обратите внимание на пунктирную линию в подменю, которая совершенно не нужна и непонятно откуда появляется. Чтобы избавиться от этой линии, надо для нужного пункта меню установить параметр tearoff=0 :
Однако так как подпунктов меню может быть много, чтобы для кажлого не прописывать этот параметр, то проще отключить все это глобально с помощью следующей строки кода

Подобным образом можно создавать и более глубокие иерархии меню:

Взаимодействие с меню
Отличительной особенностью элементов меню является способность реагировать на нажатия пользователя. Для этого у каждого элемента меню можно задать параметр command , который устанавливает ссылку на функцию, выполняемую при нажатии.
Tkinter Menu
Summary: in this tutorial, you’ll learn how to create a Tkinter menu bar, add menus to the menu bar, and add menu items to each menu.
When an application contains a lot of functions, you need to use menus to organize them for easier navigation.
Typically, you use a menu to group closely related operations. For example, you can find the File menu in most text editors.
Tkinter natively supports menus. It displays menus with the look-and-feel of the target platform that the program runs e.g., Windows, macOS, and Linux.
Creating a simple menu
First, create a root window and set its title to ‘Menu Demo’ :
Second, create a menu bar and assign it to the menu option of the root window:
Note that each top-level window can only have only one menu bar.
Third, create a File menu whose container is the menubar :
Fourth, add a menu item to the file_menu :
In this example, the label of the menu item is Exit .
When you click the Exit menu item, Python will call the root.destroy() method automatically to close the root window.
Finally, add the File menu to the menubar:
The underline option allows you to create a keyboard shortcut. It specifies the character position that should be underlined.
Note that the position starts from zero. In this example, we specify it as the first character which is F . And you can select it by using the Alt+F keyboard shortcut.
Put it all together:

By default, Tkinter adds a dashed line before the first menu item. When you click the dashed line, the main window will detach the menu from it like this:

To remove the dashed line, you can set the tearoff property of the menu to False :

Creating a more complex menu
The following program illustrates how to create a menu bar, add the File and Help menus to the menu bar. Also, it adds multiple menu items to these menus:

The only new statement in this program is to use the add_separator() method to add a separator to the menu.
Adding a submenu
The following program adds the menu item Preferences to the File menu and create a submenu that links the new menu item:

The following code adds a submenu to File menu and links the submenu to Preferences menu item:
Python and PyQt: Creating Menus, Toolbars, and Status Bars
When it comes to developing graphical user interface (GUI) applications with Python and PyQt, some of the most useful and versatile graphical elements that you’ll ever use are menus, toolbars, and status bars.
Menus and toolbars can make your applications look polished and professional, presenting users with an accessible set of options, while status bars allow you to display relevant information about the application’s status.
In this tutorial, you’ll learn:
- What menus, toolbars, and status bars are
- How to create menus, toolbars, and status bars programmatically
- How to populate Python menu and toolbar using PyQt actions
- How to use status bars to display status information
In addition, you’ll learn some programming best practices that you can apply when creating menus, toolbars, and status bars with Python and PyQt. If you’re new to GUI programming with PyQt, then you can check out Python and PyQt: Building a GUI Desktop Calculator.
You can download the code and resources for the sample application that you’ll build in this tutorial by clicking on the box below:
Download the sample code: Click here to get the code you’ll use to learn how to add menus, toolbars, and status bars to your GUI applications using Python and PyQt.
Building Python Menu Bars, Menus, and Toolbars in PyQt
A menu bar is a region of a GUI application’s main window that holds menus. Menus are pull-down lists of options that provide convenient access to your application’s options. For example, if you were creating a text editor, then you might have some of the following menus in your menu bar:
- A File menu that provides some of the following menu options:
- New for creating a new document
- Open for opening an existing document
- Open Recent for opening recent documents
- Save for saving a document
- Exit for exiting the application
- Copy for copying some text
- Paste for pasting some text
- Cut for cutting some text
- Help Content for launching to user’s manual and help content
- About for launching an About dialog
You can also add some of these options to a toolbar. A toolbar is a panel of buttons with meaningful icons that provide fast access to the most commonly used options in an application. In your text editor example, you could add options like New, Open, Save, Copy, and Paste to a toolbar.
Note: In this tutorial, you’ll develop a sample application that implements all the above menus and options. You can use this sample application as a starting point to create a text editor project.
In this section, you’ll learn the basics of how to add menu bars, menus, and toolbars to your GUI applications with Python and PyQt.
Before going any further, you’ll create a sample PyQt application that you’ll use throughout this tutorial. In each section, you’ll add new features and functionalities to this sample application. The application will be a main window–style application. This means that it’ll have a menu bar, a toolbar, a status bar, and a central widget.
Open your favorite code editor or IDE and create a Python file called sample_app.py . Then add the following code to it:
Now sample_app.py contains all the code that you need for creating your sample PyQt application. In this case, Window inherits from QMainWindow . So, you’re building a main window–style application.
Note: Unfortunately, PyQt5’s official documentation has some incomplete sections. To work around this, you can check out either the PyQt4 documentation or the original Qt documentation.
In the class initializer .__init__() , you first call the parent class’s initializer using super() . Then you set the title of the window using .setWindowTitle() and resize the window using .resize() .
Note: If you aren’t familiar with PyQt applications and how to create them, then you can check out Python and PyQt: Building a GUI Desktop Calculator.
The window’s central widget is a QLabel object that you’ll use to show messages in response to certain user actions. These messages will display at the center of the window. To do this, you call .setAlignment() on the QLabel object with a couple of alignment flags.
If you run the application from your command line, then you’ll see the following window on your screen:
That’s it! You’ve created a main window–style application with Python and PyQt. You’ll use this sample application for all the upcoming examples in this tutorial.
Creating Menu Bars
In a PyQt main window–style application, QMainWindow provides an empty QMenuBar object by default. To get access to this menu bar, you need to call .menuBar() on your QMainWindow object. This method will return an empty menu bar. The parent for this menu bar will be your main window object.
Now go back to your sample application and add the following method in the definition of Window :
This is the preferred way of creating a menu bar in PyQt. Here, the menuBar variable will hold an empty menu bar, which will be your main window’s menu bar.
Note: A common practice in PyQt programming is to use local variables for objects that you won’t use or need from outside their definition method. Python garbage-collects all objects that get out of scope, so you might think that menuBar in the above example will disappear once ._createMenuBar() returns.
The truth is that PyQt keeps a reference to local objects such as menuBar using their ownership, or parent-child relationship. In other words, since menuBar is owned by your main window object, Python won’t be able to garbage-collect it.
Another way of adding a menu bar to your PyQt applications is to create a QMenuBar object and then set it as the main window’s menu bar using .setMenuBar() . With this in mind, you can also write ._createMenuBar() in the following way:
In the above example, menuBar holds a QMenuBar object with the parent set to self , which is the application’s main window. Once you have the menu bar object, you can use .setMenuBar() to add it to your main window. Finally, note that for this example to work, you first need to import QMenuBar from PyQt5.QWidgets .
In a GUI application, the menu bar will be displayed in different positions depending on the underlying operating system:
- Windows: At the top of the application’s main window, under the title bar
- macOS: At the top of the screen
- Linux: Either at the top of the main window or at the top of the screen, depending on your desktop environment
The final step to create a menu bar for your application is to call ._createMenuBar() from the main window’s initializer .__init__() :
If you run your sample application with these new changes, then you won’t see the menu bar shown on the application’s main window. That’s because your menu bar is still empty. To see the menu bar on your application’s main window, you need to create some menus. That’s what you’ll learn next.
Adding Menus to a Menu Bar
Menus are pull-down lists of menu options that you can trigger by clicking them or by hitting a keyboard shortcut. There are at least three ways for adding menus to a menu bar object in PyQt:
QMenuBar.addMenu(menu) appends a QMenu object ( menu ) to a menu bar object. It returns the action associated with this menu.
QMenuBar.addMenu(title) creates and appends a new QMenu object with the string ( title ) as its title to a menu bar. The menu bar takes the ownership of the menu and the method returns the new QMenu object.
QMenuBar.addMenu(icon, title) creates and appends a new QMenu object with an icon and a title to a menu bar object. The menu bar takes the ownership of the menu and the method returns the new QMenu object.
If you use the first option, then you need to create your custom QMenu objects first. To do that, you can use one of the following constructors:
- QMenu(parent)
- QMenu(title, parent)
In both cases, parent is the QWidget that will hold the ownership of the QMenu object. You’ll typically set parent to the window in which you’ll use the menu. In the second constructor, title will hold a string with a text that describes the menu option.
Here’s how you can add File, Edit, and Help menus to the menu bar of your sample application:
First, you import QMenu from PyQt5.QtWidgets . Then in ._createMenuBar() , you add three menus to your menu bar using the first two variations of .addMenu() . The third variation requires an icon object, but you haven’t learned how to create and use icons yet. You’ll learn about how to use icons in the section Using Icons and Resources in PyQt.
If you run the sample application, then you’ll see that you now have a menu bar like this:
The application’s menu bar has the menus File, Edit, and Help. When you click these menus, they don’t show a pull-down list of menu options. That’s because you haven’t added menu options yet. You’ll learn how to add menu options to a menu in the section Populating Menus With Actions.
Finally, note that the ampersand character ( & ) that you include in the title of each menu creates underlined letters in the menu bar display. This is discussed in more detail in the section Defining Keyboard Shortcuts for Menu and Toolbar Options.
Creating Toolbars
A toolbar is a movable panel that holds buttons and other widgets to provide fast access to the most common options of a GUI application. Toolbar buttons can display icons, text, or both to represent the task that they perform. The base class for toolbars in PyQt is QToolBar . This class will allow you to create custom toolbars for your GUI applications.
When you add a toolbar to a main window–style application, the default position is at the top of the window. However, you can place a toolbar in any one of the following four toolbar areas:
Toolbar Area Position in Main Window Qt.LeftToolBarArea Left side Qt.RightToolBarArea Right side Qt.TopToolBarArea Top Qt.BottomToolBarArea Bottom Toolbar areas are defined as constants in PyQt. If you need to use them, then you have to import Qt from PyQt5.QtCore and then use fully qualified names just like in Qt.LeftToolBarArea .
There are three ways to add toolbars to your main window application in PyQt:
QMainWindow.addToolBar(title) creates a new and empty QToolBar object and sets its window title to title . This method inserts the toolbar into the top toolbar area and returns the newly created toolbar.
QMainWindow.addToolBar(toolbar) inserts a QToolBar object ( toolbar ) into the top toolbar area.
QMainWindow.addToolBar(area, toolbar) inserts a QToolBar object ( toolbar ) into the specified toolbar area ( area ). If the main window already has toolbars, then toolbar is placed after the last existing toolbar. If toolbar already exists in the main window, then it will only be moved to area .
If you use one of the last two options, then you need to create the toolbar by yourself. To do this, you can use one of the following constructors:
- QToolBar(parent)
- QToolBar(title, parent)
In both cases, parent represents the QWidget object that will hold the ownership of the toolbar. You’ll commonly set the toolbar ownership to the window in which you’re going to use the toolbar. In the second constructor, title will be a string with the toolbar’s window title. PyQt uses this window title to build a default context menu that allows you to hide and show your toolbars.
Now you can go back to your sample application and add the following method to Window :
First, you import QToolBar from PyQt5.QtWidgets . Then, in ._createToolBars() , you first create the File toolbar using .addToolBar() with a title. Next, you create a QToolBar object with the title «Edit» and add it to the toolbar using .addToolBar() without passing a toolbar area. In this case, the Edit toolbar is placed at the top toolbar area. Finally, you create the Help toolbar and place it in the left toolbar area using Qt.LeftToolBarArea .
The final step to make this work is to call ._createToolBars() from the initializer of Window :
The call to ._createToolBars() inside the initializer of Window will create three toolbars and add them to your main window. Here’s how your application looks now:
Now you have two toolbars right below the menu bar and one toolbar along the left side of the window. Each toolbar has a double dotted line. When you move the mouse over the dotted lines, the pointer changes to a hand. If you click and hold on the dotted line, then you can move the toolbar to any other position or toolbar area on the window.
If you right-click a toolbar, then PyQt will show a context menu that will allow you to hide and show existing toolbars according to your needs.
So far, you have three toolbars on your application’s window. These toolbars are still empty—you’ll need to add some toolbar buttons to make them functional. To do that, you can use PyQt actions, which are instances of QAction . You’ll learn how to create actions in PyQt in a later section. For now, you’ll learn how to use icons and other resources in your PyQt applications.
Using Icons and Resources in PyQt
The Qt library includes the Qt resource system, which is a convenient way of adding binary files such as icons, images, translation files, and other resources to your applications.
To use the resource system, you need to list your resources in a resource collection file, or a .qrc file. A .qrc file is an XML file that contains the location, or path, of each resource in your file system.
Suppose that your sample application has a resources directory containing the icons that you want to use in the application’s GUI. You have icons for options like New, Open, and so on. You can create a .qrc file containing the path to each icon:
Each <file> entry must contain the path to a resource in your file system. The specified paths are relative to the directory containing the .qrc file. In the above example, the resources directory needs to be in the same directory as the .qrc file.
alias is an optional attribute that defines a short alternative name that you can use in your code to get access to each resource.
Once you have the resources for your application, you can run the command-line tool pyrcc5 targeting your .qrc file. pyrcc5 is shipped with PyQt and must be fully functional on your Python environment once you have PyQt installed.
pyrcc5 reads a .qrc file and produces a Python module that contains the binary code for all your resources:
This command will read resources.qrc and generate qrc_resources.py containing the binary code for each resource. You’ll be able to use those resources in your Python code by importing qrc_resources .
Note: If something goes wrong when running pyrcc5 , then make sure that you’re using the right Python environment. If you install PyQt in a Python virtual environment, then you won’t be able to use pyrcc5 from outside that environment.
Here’s a fragment of the code in qrc_resources.py that corresponds to your resources.qrc :
With qrc_resources.py in place, you can import it into your application and refer to each resource by typing a colon (:) and then either its alias or its path. For example, to access file-new.svg with its alias, you would use the access string «:file-new.svg» . If you didn’t have an alias , you would access it by its path with the access string «:resources/file-new.svg» .
If you have aliases, but for some reason you want to access a given resource by its path instead, then you might have to remove the colon from the access string in order to make this work properly.
To use the icons in your actions, you first need to import your resources module:
Once you’ve imported the module that contains your resources, you can use the resources in your application’s GUI.
Note: Linters, editors, and IDEs may flag the above import statement as unused because your code won’t include any explicit use of it. Some IDEs may go even further and remove that line automatically.
In these situations, you must override the suggestions of your linter, editor, or IDE and keep that import in your code. Otherwise, your application won’t be able to display your resources.
To create an icon using the resources system, you need to instantiate QIcon , passing the alias or the path to the class constructor:
In this example, you create a QIcon object with the file file-new.svg , which is in your resources module. This provides a convenient way of using icons and resources throughout your GUI application.
Now go back to your sample application and update the last line of ._createMenuBar() :
For this code to work, you first need to import QIcon from PyQt5.QtGui . You also need to import qrc_resources . In the last highlighted line, you add an icon to helpMenu using help-content.svg from your resources module.
If you run your sample application with this update, then you’ll get the following output:
The application’s main window now shows an icon on its Help menu. When you click the icon, the menu shows the text Help . Using icons in a menu bar isn’t a common practice, but PyQt allows you to do it anyway.
Creating Actions for Python Menus and Toolbars in PyQt
PyQt actions are objects that represent a given command, operation, or action in an application. They’re useful when you need to provide the same functionality for different GUI components such as menu options, toolbar buttons, and keyboard shortcuts.
You can create actions by instantiating QAction . Once you’ve created an action, you need to add it to a widget to be able to use it in practice.
You also need to connect your actions to some functionality. In other words, you need to connect them to the function or method that you want to run when the action is triggered. This will allow your application to perform operations in response to user actions in the GUI.
Actions are quite versatile. They allow you to reuse and keep in sync the same functionality across menu options, toolbar buttons, and keyboard shortcuts. This provides a consistent behavior throughout the application.
For example, users might expect the application to perform the same action when they click the Open… menu option, click the Open toolbar button, or press Ctrl + O on their keyboard.
QAction provides an abstraction that allows you to track the following elements:
- The text on menu options
- The text on toolbar buttons
- The help tip on a toolbar option (tooltip)
- The What’s This help tip
- The help tip on a status bar (status tip)
- The keyboard shortcut associated with options
- The icon associated with menu and toolbar options
- The action’s enabled or disabled state
- The action’s on or off state
To create actions, you need to instantiate QAction . There are at least three general ways to do that:
- QAction(parent)
- QAction(text, parent)
- QAction(icon, text, parent)
In all three cases, parent represents the object that holds the ownership of the action. This argument can be any QObject . A best practice is to create actions as children of the window in which you’re going to use them.
In the second and third constructors, text holds the text that the action will display on a menu option or a toolbar button.
The text of an action displays differently on menu options and toolbar buttons. For example, the text &Open. displays as Open… in a menu option and as Open in a toolbar button.
In the third constructor, icon is a QIcon object that holds the action’s icon. This icon will be displayed on the left side of the text in a menu option. The position of the icon in a toolbar button depends on the toolbar’s .toolButtonStyle property, which can take one of the following values:
Style Button Display Qt.ToolButtonIconOnly Only the icon Qt.ToolButtonTextOnly Only the text Qt.ToolButtonTextBesideIcon Text beside the icon Qt.ToolButtonTextUnderIcon Text under the icon Qt.ToolButtonFollowStyle Follows the general style of the underlying platform You can also set the action’s text and icon using their respective setter methods, .setText() and .setIcon() .
Note: For a complete list of QAction properties, you can check out the documentation.
Here’s how you can create some actions for your sample application using the different constructors of QAction :
In ._createActions() , you create a few actions for your sample application. These actions will allow you to add options to the application’s menus and toolbars.
Note that you’re creating actions as instance attributes, so you can access them from outside ._createActions() using self . This way, you’ll be able to use these actions on both your menus and your toolbars.
Note: In ._createActions() , you don’t use the third constructor of QAction because it doesn’t make sense to use icons if you can’t see the actions yet. You’ll learn how to add icons to actions in the section Populating Toolbars With Actions.
The next step is to call ._createActions() form the initializer of Window :
If you run the application now, then you won’t see any change on the GUI. That’s because actions don’t get displayed until they’re added to a menu or toolbar. Note that you call ._createActions() before you call ._createMenuBar() and ._createToolBars() because you’ll be using these actions on your menus and toolbars.
If you add an action to a menu, then the action becomes a menu option. If you add an action to a toolbar, then the action becomes a toolbar button. That’s the topic for the next few sections.
Adding Options to Python Menus in PyQt
If you want to add a list of options to a given menu in PyQt, then you need to use actions. So far, you’ve learned how to create actions using the different constructors of QAction . Actions are a key component when it comes to creating menus in PyQt.
In this section, you’ll learn how to use actions to populate menus with menu options.
Populating Menus With Actions
To populate menus with menu options, you’ll use actions. In a menu, an action is represented as a horizontal option that has at least a descriptive text like New, Open, Save, and so on. Menu options can also show an icon on its left side and shortcut key sequence such as Ctrl + S on its right side.
You can add actions to a QMenu object using .addAction() . This method has several variations. Most of them are thought to create actions on the fly. In this tutorial, however, you’re going to use a variation of .addAction() that QMenu inherits from QWidget . Here’s the signature of this variation:
The argument action represents the QAction object that you want to add to a given QWidget object. With this variation of .addAction() , you can create your actions beforehand and then add them to your menus as needed.
Note: QWidget also provides .addActions() . This method takes a list of actions and appends them to the current widget object.
With this tool, you can start adding actions to the menus of your sample application. To do this, you need to update ._createMenuBar() :
With this update to ._createMenuBar() , you add a lot of options to the three menus of your sample application.
Now the File menu has four options:
- New for creating a new file
- Open… for opening an existing file
- Save for saving the changes done to a file
- Exit for closing the application
The Edit menu has three options:
- Copy for coping content to the system clipboard
- Paste for pasting content from the system clipboard
- Cut for cutting content to the system clipboard
The Help menu has two options:
- Help Content for launching the application’s help manual
- About for showing an about dialog
The order in which options are displayed in a menu from top to bottom corresponds to the order in which you add the options in your code.
If you run the application, then you’ll see the following window on your screen:
If you click on a menu, then the application shows a pull-down list with the options you saw before.
Creating Python Submenus
Sometimes you need to use submenus in your GUI applications. A submenu is a nested menu that shows up while you move the cursor over a given menu option. To add a submenu to an application, you need to call .addMenu() on a container menu object.
Say you need to add a submenu in your sample application’s Edit menu. Your submenu will contain options for finding and replacing content, so you’ll call it Find and Replace. This submenu will have two options:
- Find… for finding some content
- Replace… for finding and replacing old content with new content
Here’s how you can add this submenu to your sample application:
In the first highlighted line, you add a QMenu object with the text «Find and Replace» to the Edit menu using .addMenu() on editMenu . The next step is to populate the submenu with actions just like you’ve done so far. If you run your sample application again, then you’ll see a new menu option under the Edit menu:
The Edit menu now has a new entry called Find and Replace. When you hover your mouse over this new menu option, a submenu appears, presenting you with two new options, Find… and Replace…. That’s it! You’ve created a submenu.
Adding Options to a Toolbars in PyQt
Toolbars are a quite useful component when it comes to building GUI applications with Python and PyQt. You can use a toolbar to present your users with a quick way to get access to the most commonly used options in your application. You can also add widgets like spin boxes and combo boxes to a toolbar for allowing the user to directly modify some properties and variables from the application’s GUI.
In the following few sections, you’ll learn how to add options or buttons to your toolbars using actions and also how to add widgets to a toolbar with .addWidget() .
Populating Toolbars With Actions
To add options or buttons to a toolbar, you need to call .addAction() . In this section, you’ll rely on the variation of .addAction() that QToolBar inherits from QWidget . So, you’ll call .addAction() with an action as an argument. This will allow you to share your actions between menus and toolbars.
When you’re creating toolbars, you’ll commonly face the problem of deciding what options to add to them. Typically, you’ll want to add only the most frequently used actions to your toolbars.
If you return to your sample application, then you’ll remember that you added three toolbars:
- File
- Edit
- Help
In the File toolbar, you can add options like the following:
- New
- Open
- Save
In the Edit toolbar, you can add the following options:
- Copy
- Paste
- Cut
Normally, when you want to add buttons to a toolbar, you first select the icons that you want to use on each button. This isn’t mandatory, but it’s a best practice. Once you’ve selected the icons, you need to add them to their corresponding actions.
Here’s how you can add icons to the actions of your sample application:
To add icons to your actions, you update the highlighted lines. In the case of newAction , you use .setIcon() . In the rest of the actions, you use the constructor with an icon , a title , and a parent object as arguments.
Once your selected actions have icons, you can add these actions to their corresponding toolbar by calling .addAction() on the toolbar object:
With this update to ._createToolBars() , you add buttons for the New, Open, and Save options to the File toolbar. You also add buttons for the Copy, Paste, and Cut options to the Edit toolbar.
Note: The order in which buttons are displayed on a toolbar from left to right corresponds to the order in which you add the buttons in your code.
If you run your sample application now, then you’ll get the following window on your screen:
The sample application now shows two toolbars with a few buttons each. Your users can click these buttons to get quick access to the application’s most commonly used options.
Note: When you first wrote ._createToolBars() back in the section Creating Toolbars, you created a Help toolbar. This toolbar was intended to show how to add a toolbar using a different variation of .addToolBar() .
In the above update of ._createToolBars() , you get rid of the Help toolbar just to keep the example short and clear.
Note that, since you share the same actions between your menus and toolbars, the menu options will also display the icons on their left side, which is a big win in terms of productivity and resource use. This is one of the advantages of using PyQt actions to create menus and toolbars with Python.
Adding Widgets to a Toolbar
In some situations, you’ll find it useful to add specific widgets like spin boxes, combo boxes, or others to a toolbar. A common example of this is the combo boxes that most word processors use to allow the user to change the font of a document or the size of a selected text.
To add widgets to a toolbar, you first need to create the widget, setup its properties and then call .addWidget() on the toolbar object passing the widget as an argument.
Suppose you want to add a QSpinBox object to the Edit toolbar of your sample application to allow the user to change the size of something, which could be the font size. You need to update ._createToolBars() :
Here, you first import the spin box class. Then you create a QSpinBox object, set its focusPolicy to Qt.NoFocus , and finally add it to your Edit toolbar.
Note: In the above code, you set the focusPolicy property of the spin box to Qt.NoFocus because if this widget gets the focus, then the application’s keyboard shortcuts won’t work properly.
Now, if you run the application, then you’ll get the following output:
Here, the Edit toolbar shows a QSpinBox object that your users can use to set the size of the font or any other numeric property on your application.
Customizing Toolbars
PyQt toolbars are quite flexible and customizable. You can set a bunch of properties on a toolbar object. Some of the most useful properties are shown in the following table:
Property Feature Controlled Default Setting allowedAreas The toolbar areas in which you can place a given toolbar Qt.AllToolBarAreas floatable Whether you can drag and drop the toolbar as an independent window True floating Whether the toolbar is an independent window True iconSize The size of the icons displayed on the toolbar buttons Determined by the application’s style movable Whether you can move the toolbar within the toolbar area or between toolbar areas True orientation The orientation of the toolbar Qt.Horizontal All these properties have an associated setter method. For example, you can use .setAllowedAreas() to set allowedAreas , .setFloatable() to set floatable , and so on.
Now, suppose you don’t want your users to move the File toolbar around the window. In this case, you can set movable to False using .setMovable() :
The highlighted line makes the magic here. Now your users can’t move the toolbar around the application’s window:
The File toolbar doesn’t show the double dotted line anymore, so your users won’t be able to move it. Note that the Edit toolbar is still movable. You can change other properties on your toolbars using this same approach and customize them according to your needs.
Organizing Menu and Toolbar Options
To add clarity and improve the user experience in your GUI applications, you can organize menu options and toolbar buttons using separators. A separator renders as a horizontal line that delimits, or separates, menu options or as a vertical line that separates toolbar buttons.
To insert or add a separator to a menu, submenu, or toolbar object, you can call .addSeparator() on any of these objects.
For example, you can use a separator to separate the Exit option on your File menu from the rest of the options just to make clear that Exit isn’t logically related to the rest of the options on the menu. You can also use a separator to separate the Find and Replace option on your Edit menu from the rest of the options following the same rule.
Go to your sample application and update ._createMenuBar() like in the following code:
In the first highlighted line, you add a separator between the Save and the Exit options in the File menu. In the second highlighted line, you add a separator that separates the Find and Replace option from the rest of the options in the Edit menu. Here’s how these additions work:
Your File menu now shows a horizontal line that separates the Edit option from the rest of the options in the menu. The Edit menu also shows a separator at the end of the pull-down list of options. The coherent use of separator can subtly improve the clarity of your menus and toolbars, making your GUI applications more user-friendly.
As an exercise, you can go to the definition of ._createToolBars() and add a separator that separates the QSpinBox object from the rest of the options on the toolbar.
Building Context or Pop-Up Menus in PyQt
Context menus, also known as pop-up menus, are a special type of menu that appears in response to certain user actions, like a right-click on a given widget or window. These menus offer a small list of options that are available in a given context of the operating system or application that you’re using.
For example, if you right-click the desktop of a Windows machine, then you’ll get a menu with options that corresponds to that specific context or space of the operating system. If you right-click the workspace of a text editor, then you’ll get a totally different context menu that will depend on the editor you’re using.
In PyQt, you have several options for creating context menus. In this tutorial, you’ll learn about two of those options:
Setting the contextMenuPolicy property on specific widgets to Qt.ActionsContextMenu
Handling the context menu event on the application’s window through contextMenuEvent()
The first option is the most common and user-friendly of the two, so you’ll learn about it first.
The second option is a little bit more complex and relies on handling user events. In GUI programming, an event is any user action on the application, like clicking a button or a menu, selecting an item from a combo box, entering or updating the text in a text field, pressing a key on the keyboard, and so on.
Creating Context Menus Through Context Menu Policy
All PyQt graphical components or widgets that derive from QWidget inherit a property called contextMenuPolicy . This property controls how the widget displays a context menu. One of the most commonly used values for this property is Qt.ActionsContextMenu . This makes the widget display its internal list of actions as a context menu.
To make a widget display a context menu based on its internal actions, you need to run two steps:
Add some actions to the widget using QWidget.addAction() .
Set contextMenuPolicy to Qt.ActionsContextMenu on the widget using .setContextMenuPolicy() .
Setting contextMenuPolicy to Qt.ActionsContextMenu causes widgets that have actions to show them in a context menu. This is a really quick way to create a context menu with Python and PyQt.
With this technique, you can add a context menu to the central widget of your sample application and provide your users with a way to quickly access to some of the application’s options. To do that, you can add the following method to Window :
In ._createContextMenu() , you first set contextMenuPolicy to Qt.ActionsContextMenu using the setter method .setContextMenuPolicy() . Then you add actions to the widget using .addAction() as usual. The final step is to call ._createContextMenu() from the initializer of Window :
If you run your sample application after these additions, then you’ll see that the application’s central widget shows a context menu when you right-click on it:
Now your sample application has a context menu that pops up whenever you right-click the application’s central widget. The central widget stretches to occupy all the available space in the window, so you’re not limited to right-clicking on the label text to see the context menu.
Finally, since you use the same actions throughout this application, the options on the context menu show the same set of icons.
Creating Context Menus Through Event Handling
An alternative way of creating context menus in PyQt is to handle the context menu event of the application’s main window. To do this, you need to run the following steps:
Override the event handler method, .contextMenuEvent() , on the QMainWindow object.
Create a QMenu object passing a widget (context widget) as its parent.
Populate the menu object with actions.
Launch the menu object using QMenu.exec() with the event’s .globalPos() as an argument.
This way of managing context menus is a bit more complex. However, it gives you fine control over what happens when the context menu is invoked. For example, you can enable or disable menus options according to the application’s state and so on.
Note: Before you go any further in this section, you need to disable the code you wrote in the previous section. To do that, just go to the initializer of Window and comment out the line that calls self._createContextMenu() .
Here’s how you can reimplement the context menu of your sample application, overriding the event handler method on the main window object:
In contextMenuEvent() , you first create a QMenu object ( menu ) with centralWidget as its parent widget. Next you populate the menu with actions using .addAction . Finally, you call .exec() on the QMenu object to show it on the screen.
The second argument of .contextMenuEvent() represents the event that the method catches. In this case, event will be a right-click on the application’s central widget.
In the call to .exec() , you use event.globalPos() as an argument. This method returns the global position of the mouse pointer when the user clicks a PyQt window or a widget. The mouse position will tell .exec() where on the window to show the context menu.
If you run your sample application with these new changes, then you’ll get the same result that you got in the previous section.
Organizing Context Menus Options
Unlike in menus and toolbars, in context menus, you can’t use .addSeparator() to add a separator and visually separate your menu options according to the relationship between them. When it comes to organizing context menus, you need to create a separator action:
The call to .setSeparator(True) on an action object will turn that action into a separator. Once you have the separator action, you need to insert it in the right place in the context menu using QMenu.addAction() .
If you look back to your sample application, then you might want to visually separate the options that come from the File menu from the options that come from the Edit menu. To do that, you can update .contextMenuEvent() :
In the first two highlighted lines, you create the separator action. In the third highlighted line, you add the separator action to the menu using .addAction() .
This will add a horizontal line between the File options and the Edit options. Here’s how your context menu looks with this addition:
Now your context menu includes a horizontal line that visually separates the options that come from File from the options that come from Edit. With this, you’ve improved the visual quality of the menu and provided a better user experience.
Connecting Signals and Slots in Menus and Toolbars
In PyQt, you use signals and slots to provide functionality to your GUI applications. PyQt widgets emit signals every time an event such as a mouse click, a keypress, or a window resizing, occurs on them.
A slot is a Python callable that you can connect to a widget’s signal to perform some actions in response to user events. If a signal and a slot are connected, then the slot will be called automatically every time the signal is emitted. If a given signal isn’t connected to a slot, then nothing will happen when the signal is emitted.
To make your menu options and toolbar buttons launch some operations when the user clicks on them, you need to connect the signals of the underlying actions with some custom or built-in slots.
QAction objects can emit a variety of signals. However, the most commonly used signal in menus and toolbars is .triggered() . This signal is emitted every time the user clicks a menu option or a toolbar button. To connect .triggered() with a slot, you can use the following syntax:
In this example, slot is a Python callable. In other words, slot can be a function, a method, a class, or an instance of a class that implements .__call__() .
You already have a set of actions in your sample application. Now you need to code the slots that you’ll call every time the user clicks a menu option or a toolbar button. Go to the definition of Window and add the following methods:
These methods will play the role of the slots of your sample application. They’ll be called every time the user clicks the corresponding menu option or toolbar button.
Once you have the slots that provide the functionality, you need to connect them with the action’s .triggered() signal. This way, the application will perform actions in response to the user events. To make these connections, go to the sample application and add the following method to Window :
This method will connect all your actions’ .triggered() signals with their respective slots or callbacks. With this update, your sample application will display a message on the QLabel object that you set as a central widget telling you what menu option or toolbar button was clicked.
In the case of exitAction , you connect its triggered() signal with the built-in slot QMainWindow.close() . This way, if you select File → Exit, then your application will close.
Finally, go to the initializer of Window and add a call to ._connectActions() :
With this final update, you can run the application again. Here’s how all these changes work:
If you click a menu option, a toolbar button, or a context menu option, then the label at the center of the application’s window shows a message indicating the action that was executed. This functionality isn’t very useful outside of a learning context, but it gives you an idea of how to make your applications perform real-world actions when the user interacts with the GUI.
Finally, when you select File → Exit, the application closes because the .triggered() signal of exitAction is connected to the built-in slot QMainWindow.close() .
As an exercise, you can try to create custom slots for the Find… and Replace… options in the Find and Replace submenu and then connect their .triggered() signals to those slots to make them live. You can also experiment with the slots that you coded in this section and try to do new things with them.
Populating Python Menus Dynamically
When creating menus for an application, you’ll sometimes need to populate those menus with options that are unknown at the time you create the application’s GUI. For example, the Open Recent menu in a text editor shows a list of recently opened documents. You can’t populate this menu at the time of creating the application’s GUI because every user will open different documents and there’s no way to know this information in advance.
In this case, you need to populate the menus dynamically in response to user actions or the application’s state. QMenu has a signal called .aboutToShow() that you can connect to a custom slot to dynamically populate the menu object before it’s shown on the screen.
To continue developing your sample application, suppose you need to create an Open Recent submenu under File and dynamically populate it with recently opened files or documents. To do this, you need to run the following steps:
- Create the Open Recent submenu under File.
- Code a custom slot that dynamically generates the actions to populate the menu.
- Connect the .aboutToShow() signal of the menu with the custom slot.
Here’s the code for creating the submenu:
In the highlighted line, you add a submenu under the File menu with the title «Open Recent» . This submenu doesn’t have menu options yet. You need to create the actions dynamically to populate it.
You can do this by coding a method to create the actions dynamically and add them to the submenu. Here’s an example that shows the general logic that you can use:
In .populateOpenRecent() , you first remove the old options, if any, from the menu using .clear() . Then you add the logic for dynamically creating and connecting the actions. Finally, you add the actions to the menu using .addActions() .
In the for loop, you use functools.partial() to connect the .triggered() signal with .openRecentFile() because you want to pass filename as an argument to .openRecentFile() . This is a quite useful technique when it comes to connecting a signal with a slot that takes extra arguments. For it to work, you need to import partial() from functools .
Note: The logic in the second step of this example doesn’t really load a list of recently opened files. It just creates a list of five hypothetical files with the only purpose of showing a way to implement this technique.
The next step is to connect the .aboutToShow() signal of .openRecentMenu to .populateOpenRecent() . To do that, add the following line at the end of ._connectActions() :
In the highlighted line, you connect the .aboutToShow signal with .populateOpenRecent() . This ensures that your menu gets populated right before it’s shown.
Now you need to code .openRecentFile() . This is the method that your application will call when your users click any of the dynamically created actions:
This method will update the text of the QLabel object that you use as the central widget of your sample application.
Here’s how your dynamically created submenu works in practice:
When your mouse pointer hovers over the Open Recent menu, the menu emits the .aboutToShow() signal. This results in a call to .populateOpenRecent() , which creates and connects the actions. If you click a file name, then you’ll see that the central label changes accordingly to show a message.
Defining Keyboard Shortcuts for Menu and Toolbar Options
Keyboard shortcuts are an important feature in a GUI application. A keyboard shortcut is a key combination that you can press in your keyboard to quickly access some of the most common options in an application.
Here are some examples of keyboard shortcuts:
- Ctrl + C copies something to the clipboard.
- Ctrl + V pastes something from the clipboard.
- Ctrl + Z undoes the last operation.
- Ctrl + O opens files.
- Ctrl + S saves files.
In the section below, you’ll learn how to add keyboard shortcuts to your application to improve your user’s productivity and experience.
Using Key Sequences
So far, you’ve learned that QAction is a versatile class for populating menus and toolbars. QAction also provides a user-friendly way of defining keyboard shortcuts for your menu options and toolbar buttons.
QAction implements .setShortcut() . This method takes a QKeySequence object as an argument and returns a keyboard shortcut.
QKeySequence provides several constructors. In this tutorial, you’ll learn about two of them:
QKeySequence(ks, format) takes a string-based key sequence ( ks ) and a format ( format ) as arguments and creates a QKeySequence object.
QKeySequence(key) takes a StandardKey constant as an argument and creates a QKeySequence object that matches that key sequences on the underlying platform.
The first constructor recognizes the following strings:
- «Ctrl»
- «Shift»
- «Alt»
- «Meta»
You can create string-based key sequences by combining these strings with letters, punctuation marks, digits, named keys ( Up , Down , Home ), and function keys ( «Ctrl+S» , «Ctrl+5» , «Alt+Home» , «Alt+F4» ). You can pass up to four of these string-based key sequences in a comma-separated list.
Note: For a complete reference on standard shortcuts on different platforms, see the Standard Shortcuts section of the QKeySequence documentation.
The second constructor is handy if you’re developing a multi-platform application and want to stick to the standard keyboard shortcuts for each platform. For example, QKeySequence.Copy will return the platform’s standard keyboard shortcut for copying objects to the clipboard.
Note: For a complete references on the standard keys that PyQt provides, see the QKeySequence.StandardKey documentation.
With this general background on how to define keyboard shortcuts for actions in PyQt, you can get back to your sample application and add some shortcuts. To do this, you need to update ._createActions() :
You first need to import QKeySequence . Inside ._createActions() , the first three highlighted lines create keyboard shortcuts using a string-based key sequence. This is a quick way of adding keyboard shortcuts to your action. In the second three highlighted lines, you use QKeySequence to supply standard keyboard shortcuts.
If you run the sample application with these additions, then your menus will look like this:
Your menu options now show a keyboard shortcut on their right side. If you press any of these key combinations, then you’ll execute the corresponding action.
Using Keyboard Accelerators
There’s another alternative that you can use to add keyboard shortcuts, or keyboard accelerators, to the menu options of your applications.
You might have noticed that when you set the text for a menu or a menu option, you commonly insert an ampersand symbol ( & ) in the text. You do this so the letter immediately after the ampersand will be underlined when displayed in the text of the menu or menu option. For example, if you place an ampersand before the letter F in the title of a File menu ( «&File» ), then the F will be underlined when the menu title is displayed.
Note: If you ever need to display an ampersand symbol on a menu’s text, then you need to use a double ampersand ( && ) to escape the default functionality of this symbol.
In the case of a menu bar, using the ampersand allows you to invoke any menu by pressing Alt in combination with the underlined letter in the menu title.
Once you’ve launched a menu, you can access any menu option by pressing the underlined letter in the text of the option. For example, in File you can access the Exit option by pressing the letter E.
Note: When you use ampersands to provide keyboard accelerators, bear in mind that you can’t have two options under the same menu that share the same access letter.
If you set C as the access letter for the Copy option, then you can’t set C as the access letter for the Cut option. In other words, under a given menu, the access letters must be unique.
This feature will allow you to provide quick keyboard accelerators for users who prefer to use their keyboard to work with your applications. This technique is especially useful for options that don’t provide an explicit keyboard shortcut.
Creating Menus and Toolbars: Best Practices and Tips
When you’re creating menus and toolbars with Python and PyQt, you should follow some standards that are generally considered best practices in GUI programming. Here’s a quick list:
Arrange your menus in the generally accepted order. For example, if you have a File menu, then it should be the first menu from left to right. If you have an Edit menu, then it should be the second. Help should be the rightmost menu, and so on.
Populate your menus with common options for the type of application you’re developing. For example, in a text editor, File menus commonly include options like New, Open, Save, and Exit. Edit menus often include options like Copy, Paste, Cut, Undo, and so on.
Use standard keyboard shortcuts for common options. For example, use Ctrl + C for Copy, Ctrl + V for Paste, Ctrl + X for Cut, and so on.
Use separators to separate unrelated options. These visual cues will make your application easier to navigate.
Add ellipses ( . ) to the title of options that launch additional dialogs. For example, use Save As… instead of Save As, About… instead of About, and so on.
Use ampersands ( & ) in your menu options to provide convenient keyboard accelerators. For example, «&Open instead of «Open» , «&Exit» instead of «Exit» .
If you follow these guidelines, then your GUI applications will provide a familiar and inviting experience for your users.
Building Python Status Bars in PyQt
A status bar is a horizontal panel that is usually placed at the bottom of the main window in a GUI application. Its primary purpose is to display information about the current status of the application. The status bar can also be divided into sections to show different information on each section.
According to the Qt documentation, there are three types of status indicators:
Temporary indicators take up almost the entire status bar for a short time to display tooltip texts, menu entries, and other time-sensitive information.
Normal indicators take up a part of the status bar and display information that users may want to reference periodically, such as word counts in a word processor. These may be briefly hidden by temporary indicators.
Permanent indicators are always displayed in the status bar, even when a temporary indicator is activated. They’re used to show important information about the current mode of the application, such as when the Caps Lock key has been pressed.
You can add a status bar to your main window–style application using one of the following options:
Call .statusBar() on your QMainWindow object. .statusBar() creates and returns an empty status bar for the main window.
Create a QStatusBar object, then call .setStatusBar() on your main window with the status bar object as an argument. That way, .setStatusBar() will set your status bar object as the main window’s status bar.
Here you have two alternative implementations for adding a status bar to your sample application:
Both implementations produce the same result. However, most of the time you’ll use the first implementation for creating your status bars. Note that for the second implementation to work, you need to import QStatusBar from PyQt5.QtWidgets .
Add one of the above implementations to your application’s Window and then call ._createStatusBar() in the class initializer. With these additions, when you run your application again, you’ll see a window like this:
Your application now has a status bar at the bottom of its main window. The status bar is almost invisible, but if you look closely, then you’ll notice a small dotted triangle on the bottom-right corner of the window.
Showing Temporary Status Messages
The main purpose of a status bar is to present status information to the users of your application. To show temporary status messages in a status bar, you need to use QStatusBar.showMessage() . This method takes the following two arguments:
- message holds a status indicator message as a string.
- timeout holds the number of milliseconds that the message will be shown on the status bar.
If timeout is 0 , which is its default value, then the message remains on the status bar until you call .clearMessage() or .showMessage() on the status bar.
If there’s an active message on your status bar and you call .showMessage() with a new message, then the new message will obscure or replace the old one.
Go to your sample application and add the following line to ._createStatusBar() :
The final line in ._createStatusBar() will make your application show a Ready message on the application’s status bar for 3000 milliseconds:
When you run the application, the status bar shows the message Ready . After 3000 milliseconds, the message disappears and the status bar gets cleared and ready to show a new status message.
Showing Permanent Messages in Status Bars
You can also show permanent messages on your application’s status bar. A permanent message keeps the user informed about some general state of the application. For example, in a text editor, you might want to show a permanent message with information about the text encoding of the currently opened file.
To add permanent messages to your status bars, you use a QLabel object to hold the message. Then you add the label to the status bar by calling .addPermanentWidget() . This method permanently adds the given widget to the current status bar. The widget’s parent is set to the status bar.
.addPermanentWidget() takes the following two arguments:
- widget holds the widget object that you want to add to the status bar. Some commonly used widgets on this role are QLabel , QToolButton , and QProgressBar .
- stretch is used to compute a suitable size for the widget as the status bar grows and shrinks. It defaults to 0 , which means that the widget is going to take the minimum amount of space.
Keep in mind that a permanent widget won’t be obscured or replaced by temporary messages. .addPermanentWidget() locates widgets at the right side of the status bar.
Note: You can use .addPermanentWidget() not only to show permanent messages on your status bars but also to present the user with a progress bar to monitor the duration of a given operation. You can also provide buttons on the status bar to allow the user to change properties like the file encoding on a text editor.
When you use these kinds of widgets on a status bar, try to stick to the most commonly used widget for the type of application that you’re developing. This way, your users will feel right at home.
Say you want to turn your sample application into a text editor, and you want to add a message to the status bar that shows information about the word count of the current file. To do that, you can create a method called .getWordCount() and then add a permanent message using .addPermanentWidget() and a QLabel object:
This method adds the logic for computing the word count in the currently opened document. Now, you can show this information as a permanent message:
In the last two lines, you first create a QLabel object ( wcLabel ) to hold the message about the word count. To create the message, you use an f-string, in which you insert a call to .getWordCount() to get the word count information. Then you add the label to the status bar using .addPermanentWidget() .
In this case, you create the QLabel object as an instance attribute because the word count needs to be updated according to the changes that the user makes to the current file.
If you run the application with this update, then you’ll see the word count message on the right side of the status bar:
The status bar shows a message that informs the user about the word count in a hypothetical current file. The ability to present the user with permanent information or other options in the status bar is quite useful and can help you to greatly improve the user experience for your applications.
Adding Help Tips to Actions
When it comes to creating GUI applications, it’s important to offer help tips to your users about specific functionalities on the application’s interface. Help tips are short messages that provide a quick guide to the user about some of the options that the application offers.
PyQt actions allow you to define the following kinds of help tips:
Status tips are help tips that the application shows on the status bar when the user hovers the mouse pointer over a menu option or a toolbar button. By default, a status tip contains an empty string.
Tooltips are help tips that the application shows as floating messages when the user hovers their mouse pointer over a toolbar button or widget. By default, a tooltip contains text that identifies the action at hand.
Note: PyQt also offers the What’s This help tip that you can use in widgets and actions to show a richer description of the functionality that the widget or action provides. However, this topic is beyond the scope of this tutorial.
To learn how help tips work, you can add some status tips and tooltips to your sample application. Go to ._createActions() and add the following lines of code:
The three highlighted lines set the message «Create a new file» as the status and tooltip for the New option. If you run the application now, then you’ll see that the New option shows a short but descriptive help tip to the user:
When you click the File menu and hold your mouse pointer on New, you can see the help tip message shown on the left side of the status bar. On the other hand, if you move the mouse pointer over the New toolbar button, then you can see the message on the status bar and also as a small floating box next to the mouse pointer.
In general, adding help tips to your Python menus and toolbars is considered a best practice. It will make your GUI applications easier for users to navigate and learn. As a final exercise, you can continue adding help tips to the rest of the actions of your sample application and see how it looks after you’re done.
Conclusion
Menus, toolbars, and status bars are common and important graphical components of most GUI applications. You can use them to provide your user with a quick way to access the application’s options and functionalities. They also make your applications look polished and professional and provide a great experience to your users.
In this tutorial, you’ve learned how to:
- Programmatically create menus, toolbars, and status bars
- Use PyQt actions to populate your menus and toolbars
- Provide status information by using a status bar
Along the way, you’ve learned some best programming practices that are worth considering when it comes to adding and using menus, toolbars, and status bars in your GUI applications.
You’ve also coded a sample application in which you applied all your knowledge on menus and toolbars. You can get the full source code and other resources for that application by clicking on the box below:
Download the sample code: Click here to get the code you’ll use to learn how to add menus, toolbars, and status bars to your GUI applications using Python and PyQt.
Python и PyQt: создание меню, панелей инструментов и строк состояния
Когда дело доходит до разработки приложений с графическим пользовательским интерфейсом (GUI) с помощью Python и PyQt, одними из самых полезных и универсальных графических элементов, которые вы когда-либо будете использовать, являются меню, панели инструментов и строки состояния.
Меню и панели инструментов могут придать вашим приложениям безупречный и профессиональный вид, предоставляя пользователям доступный набор опций, а строки состояния позволяют отображать соответствующую информацию о состоянии приложения.
В этом руководстве вы узнаете:
- Что такое меню, панели инструментов и строка состояния
- Как создать меню, панели инструментов и строку состояния программно
- Как заполнить меню и панель инструментов Python с помощью действий в PyQt
- Как использовать строки состояния для отображения информации о состоянии
Кроме того, вы изучите некоторые передовые методы программирования, которые можно применять при создании меню, панелей инструментов и строк состояния с помощью Python и PyQt.
Создание меню и панелей инструментов в PyQt
Строка меню представляет собой область главного окна графического интерфейса пользователя приложения, которая содержит меню. Меню — это раскрывающиеся списки параметров, обеспечивающие удобный доступ к параметрам вашего приложения. Например, если вы создавали текстовый редактор, в строке меню могли бы быть некоторые из следующих элементов:
- File — меню которое предоставляет некоторые из следующих опций:New — для создания нового документаOpen — для открытия существующего документаOpen Recent — для открытия недавних документовSave — для сохранения документаExit — для выхода из приложения
- Edit — меню, которое предоставляет некоторые из следующих опций:Copy — для копирования текстаPaste — для вставки текстаCut — для вырезания текста
- Help — меню, которое предоставляет дополнительные опции:
Вы также можете добавить некоторые из этих параметров на панель инструментов. Панель инструментов — это панель кнопок с значками, которые обеспечивают быстрый доступ к наиболее часто используемым параметрам в приложении. В примере с текстовым редактором вы можете добавить на панель инструментов такие параметры, как New, Open, Save, Copy и Paste.
Прежде чем идти дальше, вы создадите образец приложения PyQt, которое вы будете использовать в этом руководстве. В каждом разделе вы будете добавлять новые функции и возможности в этот образец приложения. Это означает, что у него будет строка меню, панель инструментов, строка состояния и центральный виджет.
Создание меню и панелей инструментов в PyQt
Строка меню представляет собой область главного окна графического интерфейса пользователя приложения, которая содержит меню. Меню — это раскрывающиеся списки параметров, обеспечивающие удобный доступ к параметрам вашего приложения. Например, если вы создавали текстовый редактор, в строке меню могли бы быть некоторые из следующих элементов:
- File — меню которое предоставляет некоторые из следующих опций:New — для создания нового документаOpen — для открытия существующего документаOpen Recent — для открытия недавних документовSave — для сохранения документаExit — для выхода из приложения
- Edit — меню, которое предоставляет некоторые из следующих опций:Copy — для копирования текстаPaste — для вставки текстаCut — для вырезания текста
- Help — меню, которое предоставляет дополнительные опции:
Вы также можете добавить некоторые из этих параметров на панель инструментов. Панель инструментов — это панель кнопок с значками, которые обеспечивают быстрый доступ к наиболее часто используемым параметрам в приложении. В примере с текстовым редактором вы можете добавить на панель инструментов такие параметры, как New, Open, Save, Copy и Paste.
Прежде чем идти дальше, вы создадите образец приложения PyQt, которое вы будете использовать в этом руководстве. В каждом разделе вы будете добавлять новые функции и возможности в этот образец приложения. Это означает, что у него будет строка меню, панель инструментов, строка состояния и центральный виджет.
Откройте ваш любимый редактор кода или IDE и создайте файл Python с именем sample_app.py . Затем добавьте к нему следующий код:
Теперь sample_app.py содержит весь код, необходимый для создания образца приложения PyQt. В этом случае Window наследуется от QMainWindow . Итак, вы создаете приложение в стиле главного окна.
В инициализаторе класса .__init__() вы сначала вызываете инициализатор родительского класса, используя super() . Затем вы устанавливаете заголовок окна с помощью .setWindowTitle() и изменяете размер окна с помощью .resize() .
Центральный виджет окна — это объект QLabel , который вы будете использовать для отображения сообщений в ответ на определенные действия пользователя. Эти сообщения будут отображаться в центре окна. Чтобы сделать это, вы вызываете .setAlignment() у объекта QLabel с параметром выравнивания.
Если вы запустите приложение из командной строки, вы увидите на экране следующее окно:
Вы создали приложение в стиле главного окна с помощью Python и PyQt. Вы будете использовать этот образец приложения для всех следующих примеров в этом руководстве.
Создание панелей меню
В приложении в стиле главного окна PyQt по умолчанию QMainWindow предоставляет пустой объект QMenuBar . Чтобы получить доступ к этой строке меню, вам нужно вызвать .menuBar() у объекта QMainWindow . Этот метод вернет пустую строку меню. Родителем для этой строки меню будет объект вашего главного окна.
Теперь вернитесь к вашему образцу приложения и добавьте следующий метод в определение Window :
Это предпочтительный способ создания строки меню в PyQt. Здесь переменная menuBar будет содержать пустую строку меню, которая будет строкой меню вашего главного окна.
Другой способ добавить строку меню в ваши приложения PyQt — создать объект QMenuBar , а затем установить его в качестве строки меню главного окна с помощью .setMenuBar() . Имея это в виду, вы также можете написать ._createMenuBar() так:
В приведенном выше примере menuBar содержит объект QMenuBar с установленным родительским элементом self , который является главным окном приложения. Если у вас есть объект строки меню, вы можете использовать его .setMenuBar() для добавления в главное окно. Наконец, обратите внимание, что для того, чтобы этот пример работал, вам сначала нужно выполнить импорт QMenuBar из PyQt5.QWidgets .
В приложении с графическим интерфейсом строка меню будет отображаться в разных положениях в зависимости от базовой операционной системы:
- Windows: вверху главного окна приложения под строкой заголовка.
- macOS: вверху экрана.
- Linux: либо вверху главного окна, либо вверху экрана, в зависимости от среды рабочего стола.
Последний шаг по созданию строки меню для вашего приложения — это вызов ._createMenuBar() из инициализатора главного окна .__init__() :
Если вы запустите образец приложения с этими новыми изменениями, вы не увидите строку меню, отображаемую в главном окне приложения. Это потому, что ваша строка меню все еще пуста. Чтобы увидеть строку меню в главном окне вашего приложения, вам нужно создать несколько меню. Вот что вы узнаете дальше.
Добавление меню в строку меню
Меню — это раскрывающиеся списки пунктов меню, которые можно вызвать, щелкнув их или нажав сочетание клавиш. Есть как минимум три способа добавить меню к объекту строке меню в PyQt:
- QMenuBar.addMenu(menu) добавляет объект QMenu ( menu ) к объекту строки меню. Он возвращает действие, связанное с этим меню.
- QMenuBar.addMenu(title) создает и добавляет новый объект QMenu со строкой ( title ) в качестве заголовка к строке меню. Строка меню становится владельцем меню, а метод возвращает новый объект QMenu .
- QMenuBar.addMenu(icon, title) создает и добавляет новый объект QMenu с помощью icon и title к объекту строки меню. Строка меню становится владельцем меню, а метод возвращает новый объект QMenu .
Если вы используете первый вариант, вам нужно сначала создать свои собственные объекты QMenu . Для этого вы можете использовать один из следующих конструкторов:
- QMenu(parent)
- QMenu(title, parent)
В обоих случаях parent это тот QWidget , который будет владеть объектом QMenu . Обычно вы устанавливаете parent окно, в котором будете использовать меню. Во втором конструкторе title будет содержаться строка с текстом, описывающим параметр меню.
Вот как вы можете добавить меню File, Edit и Help в строку меню вашего примера приложения:
Сначала вы импортируете QMenu из PyQt5.QtWidgets . Затем ._createMenuBar() вы добавляете три меню в строку меню, используя первые два варианта .addMenu() . Для третьего варианта требуется объект иконки, но вы еще не научились создавать и использовать иконки. Об этом мы расскажем ниже в статье.
Если вы запустите пример приложения, то увидите, что теперь у вас есть строка меню, подобная этой:
В строке меню приложения есть меню File, Edit и Help. Когда вы щелкаете по этим меню, они не показывают раскрывающийся список опций меню. Это потому, что вы еще не добавили пункты меню.
Наконец, обратите внимание, на символ амперсанда ( & ), который вы включаете в заголовок каждого меню, создает подчеркнутые буквы на отображении строки меню.
Создание панелей инструментов
Панель представляет собой выпадающее меню, которое содержит кнопки и другие виджеты для быстрого доступа к наиболее распространенным вариантам приложения с графическим интерфейсом. Кнопки панели инструментов могут отображать значки, текст или и то, и другое, чтобы представлять задачу, которую они выполняют. Базовый класс для панелей инструментов в PyQt — это QToolBar . Этот класс позволит вам создавать настраиваемые панели инструментов для ваших приложений с графическим интерфейсом.
Когда вы добавляете панель инструментов в приложение в главное окно, позиция по умолчанию находится в верхней части окна. Однако вы можете разместить панель инструментов в любой из следующих четырех областей панели инструментов:
Область панели инструментов<br> Положение в главном окне<br> Qt.LeftToolBarArea<br> Левая сторона<br> Qt.RightToolBarArea<br> Правая сторона<br> Qt.TopToolBarArea<br> Верх Qt.BottomToolBarArea<br> Низ Области панели инструментов определены в PyQt как константы. Если вам нужно их использовать, вам нужно импортировать Qt из PyQt5.QtCore а затем использовать полностью определенные имена, как в Qt.LeftToolBarArea .
Есть три способа добавить панели инструментов в ваше главное окно приложения в PyQt:
- QMainWindow.addToolBar(title) создает новый пустой объект QToolBar и устанавливает для его заголовка окна значение title . Этот метод вставляет панель инструментов в область верхней панели инструментов и возвращает только что созданную панель инструментов.
- QMainWindow.addToolBar(toolbar) вставляет объект QToolBar ( toolbar ) в область верхней панели инструментов.
- QMainWindow.addToolBar(area, toolbar) вставляет объект QToolBar ( toolbar ) в указанную область панели инструментов ( area ). Если в главном окне уже есть панели инструментов toolbar , оно помещается после последней существующей панели инструментов. Если toolbar уже существует в главном окне, он будет перемещен только в area .
Если вы используете один из двух последних вариантов, вам необходимо создать панель инструментов самостоятельно. Для этого можно использовать один из следующих конструкторов:
- QToolBar(parent)
- QToolBar(title, parent)
В обоих случаях parent представляет объект QWidget , который будет владеть панелью инструментов. Обычно вы устанавливаете владельцем панели инструментов окно, в котором вы собираетесь использовать панель инструментов. Во втором конструкторе title будет строка с заголовком окна панели инструментов. PyQt использует этот заголовок окна для создания контекстного меню по умолчанию, которое позволяет скрывать и отображать панели инструментов.
Теперь вы можете вернуться к вашему образцу приложения и добавить следующий метод в Window :
Сначала вы импортируете QToolBar из PyQt5.QtWidgets . Затем, в ._createToolBars() , вы сначала создаете панель инструментов File, используя .addToolBar() с заголовком. Затем вы создаете объект QToolBar с заголовком «Edit» и добавляете его на панель инструментов .addToolBar() , не передавая область панели инструментов. В этом случае панель инструментов Edit размещается в верхней области панели инструментов. Наконец, вы создаете панель инструментов Help и размещаете ее в левой области панели инструментов с помощью Qt.LeftToolBarArea .
Последним шагом для выполнения этой работы является вызов ._createToolBars() из инициализатора Window :
Вызов ._createToolBars() внутри инициализатора Window создаст три панели инструментов и добавит их в ваше главное окно. Вот как теперь выглядит ваше приложение:
Теперь у вас есть две панели инструментов прямо под строкой меню и одна панель инструментов вдоль левой стороны окна. Каждая панель инструментов имеет двойную пунктирную линию. Когда вы наводите указатель мыши на пунктирные линии, указатель принимает вид руки. Если вы нажмете и удерживаете пунктирную линию, вы можете переместить панель инструментов в любое другое положение или область панели инструментов в окне.
Если вы щелкните правой кнопкой мыши панель инструментов, PyQt покажет контекстное меню, которое позволит вам скрывать и отображать существующие панели инструментов в соответствии с вашими потребностями.
На данный момент у вас есть три панели инструментов в окне вашего приложения. Эти панели инструментов по-прежнему пусты — вам нужно добавить несколько кнопок на панели инструментов, чтобы они работали. Для этого вы можете использовать действия PyQt, которые являются экземплярами QAction . Вы узнаете, как создавать действия в PyQt в следующем разделе. А пока вы узнаете, как использовать иконки и другие ресурсы в своих приложениях PyQt.
Использование иконок и ресурсов в PyQt
Библиотека Qt включает систему ресурсов Qt, которая представляет собой удобный способ добавления двоичных файлов, таких как иконки, изображения, файлы перевода и другие ресурсы, в ваши приложения.
Чтобы использовать систему ресурсов, вам необходимо указать свои ресурсы в файле коллекции ресурсов или файле .qrc . Файл .qrc представляет собой XML файл, который содержит местоположение или путь, каждый ресурс в файловой системе.
Предположим, что в вашем примере приложения есть каталог resources , содержащий иконки, которые вы хотите использовать в графическом интерфейсе приложения. У вас есть иконки для таких опций, как Create, Open и т.д. Вы можете создать файл .qrc , содержащий путь к каждой иконке:
Каждая запись <file> должна содержать путь к ресурсу в вашей файловой системе. Указанные пути указаны относительно каталога, в котором находится файл .qrc . В приведенном выше примере каталог resources должен находиться в том же каталоге, что и файл .qrc .
alias — необязательный атрибут, определяющий короткое альтернативное имя, которое вы можете использовать в своем коде для доступа к каждому ресурсу.
Когда у вас появятся ресурсы для вашего приложения, вы можете запустить инструмент командной строки pyrcc5 для своего файла .qrc . pyrcc5 поставляется с PyQt и должен быть полностью функциональным в вашей среде Python после установки PyQt.
pyrcc5 читает .qrc файл и создает модуль Python, содержащий двоичный код для всех ваших ресурсов:
Эта команда будет читать resources.qrc и генерировать qrc_resources.py двоичный код для каждого ресурса. Вы сможете использовать эти ресурсы в своем коде Python, импортировав qrc_resources .
Вот фрагмент кода qrc_resources.py , который соответствует вашему resources.qrc :
После этого вы можете импортировать qrc_resources.py в свое приложение и ссылаться на каждый ресурс, набрав двоеточие (:), а затем либо alias , либо его путь. Например, чтобы получить доступ file-new.svg с его псевдонимом, вы должны использовать строку доступа «:file-new.svg» . Если бы у вас не было alias , вы могли бы получить к нему доступ по его пути со строкой доступа «:resources/file-new.svg» .
Если у вас есть псевдонимы, но по какой-то причине вы хотите вместо этого получить доступ к данному ресурсу по его пути, вам, возможно, придется удалить двоеточие из строки доступа, чтобы это работало правильно.
Чтобы использовать иконки в своих действиях, вам сначала нужно импортировать модуль ресурсов:
После того, как вы импортировали модуль, содержащий ваши ресурсы, вы можете использовать ресурсы в графическом интерфейсе вашего приложения.
Чтобы создать иконку с использованием системы ресурсов, вам необходимо создать экземпляр QIcon , передав псевдоним или путь к конструктору класса:
В этом примере вы создаете объект QIcon с файлом file-new.svg , который находится в вашем модуле ресурсов. Это обеспечивает удобный способ использования иконок и ресурсов в вашем приложении с графическим интерфейсом.
Теперь вернитесь к вашему образцу приложения и обновите последнюю строку ._createMenuBar() :
Чтобы этот код работал, вам сначала нужно выполнить импорт QIcon из PyQt5.QtGui . Вам также необходимо импортировать qrc_resources . В последней строке вы добавляете иконку help-content.svg для использования helpMenu из модуля ресурсов.
Если вы запустите образец приложения с этим обновлением, вы получите следующий результат:
В главном окне приложения теперь отображается значок в меню Help. Когда вы щелкаете иконку, в меню отображается текст Help . Использование иконок в строке меню — не обычная практика, но PyQt все равно позволяет это делать.
Создание действий для меню и панелей инструментов Python в PyQt
Действия PyQt — это объекты, которые представляют заданную команду, операцию или действие в приложении. Они полезны, когда вам нужно предоставить одинаковые функциональные возможности для различных компонентов графического интерфейса, таких как параметры меню, кнопки панели инструментов и сочетания клавиш.
Вы можете создавать действия, создавая экземпляры QAction . После того, как вы создали действие, вам необходимо добавить его в виджет, чтобы иметь возможность использовать его на практике.
Также необходимо связать свои действия с каким-то функционалом. Другими словами, вам необходимо подключить их к функции или методу, которые вы хотите запустить при запуске действия. Это позволит вашему приложению выполнять операции в ответ на действия пользователя в графическом интерфейсе.
Действия довольно разносторонние. Они позволяют повторно использовать и синхронизировать одни и те же функции в параметрах меню, кнопках панели инструментов и сочетаниях клавиш. Это обеспечивает единообразное поведение во всем приложении.
Например, пользователи могут ожидать, что приложение выполнит то же действие, когда они щелкнут пункт меню Open…, нажатие кнопки Open на панели инструментов или нажмите Ctrl+O на своей клавиатуре.
QAction предоставляет абстракцию, которая позволяет отслеживать следующие элементы:
- Текст в параметрах меню
- Текст на кнопках панели инструментов
- Подсказка по параметрам панели инструментов (всплывающая подсказка)
- Справочный совет «Что это за»
- Подсказка в строке состояния (подсказка состояния)
- Сочетание клавиш, связанное с параметрами
- Иконка, связанный с параметрами меню и панели инструментов
- enabled или disabled состояние
- on или off состояние
Чтобы создать действия, вам нужно создать экземпляр QAction . Есть как минимум три основных способа сделать это:
- QAction(parent)
- QAction(text, parent)
- QAction(icon, text, parent)
Во всех трех случаях parent представляет объект, которому принадлежит действие. Этот аргумент может быть любым QObject . Лучше всего создавать действия как дочерние по отношению к окну, в котором вы собираетесь их использовать.
Во втором и третьем конструкторах text содержит текст, который будет отображать в пункте меню или на кнопке панели инструментов.
Текст действия по-разному отображается в параметрах меню и на кнопках панели инструментов. Например, текст &Open. отображается как Open… в пункте меню и как Open на кнопке панели инструментов.
В третьем конструкторе находится объект QIcon , содержащий иконку действия. Эта иконка будет отображаться слева от текста в пункте меню. Положение иконки на кнопке панели инструментов зависит от свойства .toolButtonStyle панели инструментов, которое может принимать одно из следующих значений:
Стиль Дисплей кнопок Qt.ToolButtonIconOnly<br> Только значок<br> Qt.ToolButtonTextOnly<br> Только текст<br> Qt.ToolButtonTextBesideIcon<br> Текст рядом со значком<br> Qt.ToolButtonTextUnderIcon<br> Текст под значком<br> Qt.ToolButtonFollowStyle<br> Соответствует общему стилю базовой платформы<br> Вы также можете установить текст и иконку действия, используя соответствующие методы установки .setText() и .setIcon() .
Вот как вы можете создать некоторые действия для вашего примера приложения, используя различные конструкторы QAction :
В ._createActions() , вы создаете несколько действий для вашего примера приложения. Эти действия позволят вам добавлять параметры в меню и панели инструментов приложения.
Обратите внимание, что вы создаете действия как атрибуты экземпляра, поэтому вы можете получить к ним доступ извне ._createActions() , используя self . Таким образом, вы сможете использовать эти действия как в меню, так и на панелях инструментов.
Следующим шагом будет вызов ._createActions() из инициализатора Window :
Если вы запустите приложение сейчас, вы не увидите никаких изменений в графическом интерфейсе. Это потому, что действия не отображаются, пока они не добавлены в меню или на панель инструментов. Обратите внимание, что вы вызываете ._createActions() перед вызовом ._createMenuBar() и ._createToolBars() потому что вы будете использовать эти действия в своих меню и панелях инструментов.
Если вы добавляете действие в меню, оно становится опцией меню. Если вы добавляете действие на панель инструментов, то действие становится кнопкой панели инструментов. Это тема для следующих нескольких разделов.
Добавление параметров в меню Python в PyQt
Если вы хотите добавить список опций к данному меню в PyQt, вам необходимо использовать действия. Итак, вы узнали, как создавать действия с помощью различных конструкторов QAction . Действия — ключевой компонент при создании меню в PyQt.
В этом разделе вы узнаете, как использовать действия для заполнения меню параметрами меню.
Заполнение меню действиями
Чтобы заполнить меню параметрами меню, вы будете использовать действия. В меню действие представлено как горизонтальный параметр, который имеет как минимум описательный текст, например New, Open, Save и т.д. Параметры меню также могут отображать иконку с левой стороны и последовательность сочетаний клавиш, например Ctrl+S с правой стороны.
Вы можете добавлять действия к объекту QMenu , используя .addAction() . У этого метода есть несколько вариаций. Считается, что большинство из них создают действия на лету. Однако в этом руководстве вы собираетесь использовать вариант .addAction() , QMenu унаследованный от QWidget . Вот пример этого варианта:
Аргумент action представляет объект QAction , который вы хотите добавить к данному объекту QWidget . С помощью этого варианта вы можете заранее создавать свои действия, а затем добавлять их в свои меню по мере необходимости.
С помощью этого инструмента вы можете начать добавлять действия в меню вашего образца приложения. Для этого вам необходимо обновить ._createMenuBar() :
С этим обновлением ._createMenuBar() вы добавляете множество параметров в три меню вашего образца приложения.
Порядок, в котором параметры отображаются в меню сверху вниз, соответствует порядку, в котором вы добавляете параметры в свой код.
Если вы запустите приложение, то вы увидите на экране следующее окно:
Если щелкнуть меню, приложение покажет раскрывающийся список с параметрами, которые вы видели ранее.
Создание подменю Python
Иногда вам нужно использовать подменю в ваших графических приложениях. Подменю — это вложенное меню, которое появляется, когда вы наводите курсор на заданный пункт меню. Чтобы добавить подменю в приложение, вам нужно вызвать .addMenu() у объекта контейнера.
Скажем, вам нужно добавить подменю в меню Edit вашего примера приложения. Ваше подменю будет содержать параметры для поиска и замены содержимого, поэтому вы назовете его Find and Replace. В этом подменю есть два варианта:
- Find… для поиска содержания
- Replace… для поиска и замены старого содержания новым содержанием.
Вот как вы можете добавить это подменю в свой образец приложения:
В первой выделенной строке вы добавляете объект QMenu с текстом «Find and Replace» в меню Edit с помощью .addMenu() у editMenu . Следующий шаг — заполнить подменю действиями, как вы это делали до ранее. Если вы снова запустите образец приложения, вы увидите новый параметр в меню Edit:
Добавление параметров на панели инструментов в PyQt
Панели инструментов — довольно полезный компонент, когда дело доходит до создания приложений с графическим интерфейсом пользователя с помощью Python и PyQt. Вы можете использовать панель инструментов, чтобы предоставить пользователям быстрый доступ к наиболее часто используемым параметрам в вашем приложении. Вы также можете добавить на панель инструментов виджеты, такие как счетчики и поля со списком, чтобы пользователь мог напрямую изменять некоторые свойства и переменные из графического интерфейса приложения.
В следующих нескольких разделах вы узнаете, как добавлять параметры или кнопки на панели инструментов с помощью действий, а также как добавлять виджеты на панель инструментов с помощью .addWidget() .
Заполнение панелей инструментов действиями
Чтобы добавить параметры или кнопки на панель инструментов, вам нужно вызвать .addAction() . В этом разделе вы будете полагаться на вариацию .addAction() , QToolBar унаследованную от QWidget . Итак, вы вызовете .addAction() и действие в качестве аргумента. Это позволит вам делиться своими действиями между меню и панелями инструментов.
Когда вы создаете панели инструментов, вы обычно сталкиваетесь с проблемой решения, какие параметры добавить к ним. Как правило, вы хотите добавить на свои панели инструментов только наиболее часто используемые действия.
Если вы вернетесь к своему образцу приложения, то вспомните, что добавили три панели инструментов:
- File
- Edit
- Help
На панели инструментов File вы можете добавить следующие параметры:
- New
- Open
- Save
На панели инструментов Edit вы можете добавить следующие параметры:
- Copy
- Paste
- Cut
Обычно, когда вы хотите добавить кнопки на панель инструментов, вы сначала выбираете иконки, которые хотите использовать на каждой кнопке. Это не обязательно, но это лучшая практика. После того, как вы выбрали иконки, вам нужно добавить их к соответствующим действиям.
Вот как вы можете добавить иконки к действиям вашего примера приложения:
В случае newAction используется .setIcon() . В остальных действиях вы используете конструктор с объектом icon , а title и parent в качестве аргументов.
После того как выбранные вами действия имеют иконки, вы можете добавить эти действия на соответствующую панель инструментов, вызвав .addAction() у объекта панели инструментов:
В этом обновлении ._createToolBars() вы добавляете кнопки для параметров Create, Open и Save на панель инструментов File. Вы также добавляете кнопки для параметров Copy, Paste и Cut на панель инструментов Edit.
Если вы сейчас запустите образец приложения, на экране появится следующее окно:
В примере приложения теперь отображаются две панели инструментов с несколькими кнопками на каждой. Ваши пользователи могут нажимать эти кнопки, чтобы получить быстрый доступ к наиболее часто используемым параметрам приложения.
Обратите внимание, что, поскольку вы используете одни и те же действия в своих меню и панелях инструментов, параметры меню также будут отображать значки с левой стороны, что является большим преимуществом с точки зрения производительности и использования ресурсов. Это одно из преимуществ использования действий PyQt для создания меню и панелей инструментов с помощью Python.
Добавление виджетов на панель инструментов
В некоторых ситуациях вам будет полезно добавить на панель инструментов определенные виджеты, такие как счетчики, поля со списком или другие. Типичным примером этого являются поля со списком, которые большинство текстовых процессоров используют, чтобы позволить пользователю изменять шрифт документа или размер выделенного текста.
Чтобы добавить виджеты на панель инструментов, вам сначала нужно создать виджет, настроить его свойства, а затем вызвать объект панели инструментов, передав .addWidget() виджет в качестве аргумента.
Предположим, вы хотите добавить объект QSpinBox на панель инструментов Edit в вашем примере приложения, чтобы пользователь мог изменять размер чего-либо, например, размера шрифта. Вам необходимо обновить ._createToolBars() :
Здесь вы сначала импортируете класс счетчика. Затем вы создаете объект QSpinBox , устанавливаете focusPolicy значение Qt.NoFocus и наконец, добавляете его на панель инструментов редактирования.
Теперь, если вы запустите приложение, вы получите следующий результат:
Здесь на панели инструментов Edit отображается объект QSpinBox , который пользователи могут использовать для установки размера шрифта или любого другого числового свойства в приложении.
Настройка панелей инструментов
Панели инструментов PyQt довольно гибкие и настраиваемые. Вы можете установить набор свойств для объекта панели инструментов. Некоторые из наиболее полезных свойств показаны в следующей таблице:
Свойство<br> Функция под контролем<br> Настройки по умолчанию<br> allowedAreas<br> Области панели инструментов, в которых вы можете разместить данную панель инструментов<br> Qt.AllToolBarAreas<br> floatable Можно ли перетащить панель инструментов как отдельное окно<br> True floating Является ли панель инструментов независимым окном<br> True iconSize<br> Размер иконок, отображаемых на кнопках панели инструментов<br> Определяется стилем приложения<br> movable Можно ли перемещать панель инструментов внутри области панели инструментов или между областями панели инструментов<br> True orientation<br> Ориентация панели инструментов<br> Qt.Horizontal<br> Все эти свойства имеют связанный метод установки. Например, вы можете использовать .setAllowedAreas() для установки allowedAreas , .setFloatable() для установки floatable и так далее.
Теперь предположим, что вы не хотите, чтобы ваши пользователи перемещали панель инструментов File по окну. В этом случае, вы можете установить movable в False используя .setMovable() :
Выделенная линия создает здесь волшебство. Теперь ваши пользователи не могут перемещать панель инструментов по окну приложения:
На панели инструментов File больше не отображается двойная пунктирная линия, поэтому ваши пользователи не смогут ее перемещать. Обратите внимание, что панель инструментов Edit по-прежнему подвижна. Вы можете изменить другие свойства на своих панелях инструментов, используя тот же подход, и настроить их в соответствии с вашими потребностями.
Организация параметров меню и панели инструментов
Чтобы добавить ясности и улучшить взаимодействие с пользователем в ваших приложениях с графическим интерфейсом, вы можете организовать параметры меню и кнопки панели инструментов с помощью разделителей. Разделитель отображается как горизонтальная линия, разделяющая пункты меню, или как вертикальная линия, разделяющая кнопки панели инструментов.
Чтобы вставить или добавить разделитель к объекту меню, подменю или панели инструментов, вы можете вызвать .addSeparator() для любого из этих объектов.
Например, вы можете использовать разделитель, чтобы отделить параметр Exit в меню File от остальных параметров, просто чтобы прояснить, что Exit логически не связан с остальными параметрами в меню. Вы также можете использовать разделитель, чтобы отделить опцию Find and Replace в меню Edit от остальных опций, соответствующих тому же правилу.
Перейдите в образец приложения и обновите ._createMenuBar() , как показано в следующем коде:
В первой выделенной строке вы добавляете разделитель между параметрами Save и Exit в меню File. Во второй выделенной строке вы добавляете разделитель, который отделяет опцию Find and Replace от остальных опций в меню Edit. Вот как работают эти дополнения:
В меню File теперь отображается горизонтальная линия, отделяющая параметр Edit от остальных параметров меню. В меню Edit также отображается разделитель в конце раскрывающегося списка параметров. Последовательное использование разделителя может немного улучшить ясность ваших меню и панелей инструментов, делая ваши приложения с графическим интерфейсом пользователя более удобными.
Создание контекстных или всплывающих меню в PyQt
Контекстные меню, также известные как всплывающие меню, представляют собой особый тип меню, которое появляется в ответ на определенные действия пользователя, такие как клик правой кнопкой мыши по заданному виджету или окну. Эти меню предлагают небольшой список параметров, доступных в конкретном контексте используемой вами операционной системы или приложения.
Например, если вы щелкните правой кнопкой мыши рабочий стол компьютера с Windows, вы получите меню с параметрами, которые соответствуют этому конкретному контексту или пространству операционной системы. Если вы щелкните правой кнопкой мыши рабочую область текстового редактора, вы получите совершенно другое контекстное меню, которое будет зависеть от редактора, который вы используете.
В PyQt у вас есть несколько вариантов создания контекстных меню. В этом руководстве вы узнаете о двух из этих вариантов:
- Установка свойства contextMenuPolicy на определенных виджетах на Qt.ActionsContextMenu
- Обработка события контекстного меню в окне приложения через contextMenuEvent()
Первый вариант является наиболее распространенным и удобным из двух, поэтому вы сначала узнаете о нем.
Второй вариант немного сложнее и основан на обработке пользовательских событий. В программировании с графическим интерфейсом событие — это любое действие пользователя в приложении, такое как нажатие кнопки или меню, выбор элемента из поля со списком, ввод или обновление текста в текстовом поле, нажатие клавиши на клавиатуре и т.д.
Создание контекстных меню с помощью политики контекстного меню
Все графические компоненты или виджеты PyQt, являющиеся производными QWidget , наследуют свойство с именем contextMenuPolicy . Это свойство определяет, как виджет отображает контекстное меню. Одно из наиболее часто используемых значений этого свойства — Qt.ActionsContextMenu . Это заставляет виджет отображать свой внутренний список действий в виде контекстного меню.
Чтобы виджет отображал контекстное меню на основе его внутренних действий, вам необходимо выполнить два шага:
- Добавьте действия к виджету, используя QWidget.addAction() .
- Набор contextMenuPolicy для Qt.ActionsContextMenu виджета с помощью .setContextMenuPolicy() .
При выборе значения contextMenuPolicy для Qt.ActionsContextMenu виджетов с действиями они отображаются в контекстном меню. Это действительно быстрый способ создать контекстное меню с помощью Python и PyQt.
С помощью этого метода вы можете добавить контекстное меню к центральному виджету вашего образца приложения и предоставить пользователям способ быстрого доступа к некоторым параметрам приложения. Для этого вы можете добавить следующий метод в Window :
В ._createContextMenu() , вы перввой строчкой добавляете contextMenuPolicy со значением Qt.ActionsContextMenu с помощью метода .setContextMenuPolicy() . Затем вы добавляете действия к виджету с помощью .addAction() , как обычно. Последний шаг — вызов ._createContextMenu() инициализатора Window :
Если вы запустите образец приложения после этих добавлений, вы увидите, что центральный виджет приложения показывает контекстное меню, когда вы щелкаете по нему правой кнопкой мыши:
Теперь в вашем примере приложения есть контекстное меню, которое всплывает всякий раз, когда вы щелкаете правой кнопкой мыши в центральном виджете приложения. Центральный виджет растягивается, чтобы занять все доступное пространство в окне, поэтому вы не ограничены щелчком правой кнопкой мыши по тексту метки, чтобы увидеть контекстное меню.
Наконец, поскольку вы используете одни и те же действия во всем приложении, параметры в контекстном меню показывают одинаковый набор значков.
Создание контекстных меню посредством обработки событий
Альтернативный способ создания контекстных меню в PyQt — обработка события контекстного меню главного окна приложения. Для этого вам необходимо выполнить следующие действия:
- Переопределите метод обработчика событий .contextMenuEvent() на объекте QMainWindow .
- Создайте объект QMenu , передающий виджет (виджет контекста) в качестве своего родителя.
- Заполните объект меню действиями.
- Запустите объект меню QMenu.exec() , используя событие .globalPos() в качестве аргумента.
Этот способ управления контекстными меню немного сложнее. Однако он дает вам точный контроль над тем, что происходит при вызове контекстного меню. Например, вы можете включать или отключать опции меню в зависимости от состояния приложения и так далее.
Вот как вы можете повторно реализовать контекстное меню вашего примера приложения, переопределив метод обработчика событий в объекте главного окна:
В contextMenuEvent() , вы сначала создаете объект QMenu ( menu ) с родительским виджетом centralWidget . Затем вы заполняете меню действиями, используя .addAction . Наконец, вы вызываете .exec() на объект QMenu , чтобы показать его на экране.
Второй аргумент .contextMenuEvent() представляет событие, которое перехватывает метод. В этом случае event это будет щелчок правой кнопкой мыши по центральному виджету приложения.
В вызове .exec() вы используете event.globalPos() в качестве аргумента. Этот метод возвращает глобальную позицию указателя мыши, когда пользователь щелкает окно PyQt или виджет. Положение мыши подскажет .exec() , где в окне показывать контекстное меню.
Если вы запустите образец приложения с этими новыми изменениями, вы получите тот же результат, что и в предыдущем разделе.
Организация параметров контекстного меню
В отличие от меню и панелей инструментов, в контекстных меню нельзя добавить разделитель и визуально разделить параметры меню в соответствии с их взаимосвязью. Когда дело доходит до организации контекстных меню, вам нужно создать действие-разделитель:
Вызов .setSeparator(True) у объекта действия превратит это действие в разделитель. Когда у вас есть действие разделителя, вам нужно вставить его в нужное место в контекстном меню, используя QMenu.addAction() .
Если вы вернетесь к своему образцу приложения, то, возможно, вы захотите визуально отделить параметры, поступающие из меню File, от параметров, поступающих из меню Edit. Для этого вы можете обновить .contextMenuEvent() :
В первых двух выделенных строках вы создаете действие-разделитель. В третьей выделенной строке вы добавляете действие-разделитель в меню, используя .addAction() .
Это добавит горизонтальную линию между параметрами файла и параметрами редактирования. Вот как выглядит ваше контекстное меню с этим дополнением:
Подключение сигналов и слотов в меню и панелях инструментов
В PyQt вы используете сигналы и слоты для обеспечения функциональности ваших приложений с графическим интерфейсом. Виджеты PyQt излучают сигналы каждый раз, когда на них происходит такое событие, как щелчок мыши, нажатие клавиши или изменение размера окна.
Слот является обратной функцией, которую можно подключить к сигналу виджета, чтобы выполнить какие — либо действия в ответ на пользовательские события. Если сигнал и слот связаны, то слот будет вызываться автоматически каждый раз, когда сигнал запускается. Если данный сигнал не подключен к слоту, то при его передаче ничего не произойдет.
Чтобы параметры меню и кнопки панели инструментов запускали некоторые операции, когда пользователь нажимает на них, вам необходимо связать сигналы основных действий с некоторыми настраиваемыми или встроенными слотами.
QAction объекты могут излучать самые разные сигналы. Однако наиболее часто используемый сигнал в меню и панелях инструментов — это .triggered() . Этот сигнал излучается каждый раз, когда пользователь щелкает пункт меню или кнопку панели инструментов. Чтобы подключить .triggered() к слоту, вы можете использовать следующий синтаксис:
В этом примере slot это функция. Другими словами, slot может быть функцией, методом, классом или экземпляром класса, который реализует .__call__() .
В вашем примере приложения уже есть набор действий. Теперь вам нужно закодировать слоты, которые вы будете вызывать каждый раз, когда пользователь щелкает пункт меню или кнопку панели инструментов. Перейдите к определению Window и добавьте следующие методы:
Эти методы будут играть роль слотов вашего примера приложения. Они будут вызываться каждый раз, когда пользователь щелкает соответствующий пункт меню или кнопку панели инструментов.
Когда у вас есть слоты, которые обеспечивают функциональность, вам нужно связать их с сигналом действия .triggered() . Таким образом, приложение будет выполнять действия в ответ на пользовательские события. Чтобы выполнить эти подключения, перейдите к образцу приложения и добавьте следующий метод в Window :
Этот метод свяжет все .triggered() сигналы ваших действий с соответствующими слотами или обратными вызовами. С этим обновлением ваше примерное приложение будет отображать сообщение в объекте QLabel , который вы установили в качестве центрального виджета, с указанием того, какой пункт меню или кнопка панели инструментов была нажата.
В случае exitAction , вы подключаете его triggered() сигнал со встроенным слотом QMainWindow.close() . Таким образом, если вы выберете File → Exit, ваше приложение закроется.
Наконец, перейдите к инициализатору Window и добавьте вызов ._connectActions() :
С этим последним обновлением вы можете снова запустить приложение. Вот как работают все эти изменения:
Динамическое заполнение меню Python
При создании меню для приложения вам иногда необходимо заполнить эти меню параметрами, которые неизвестны на момент создания графического интерфейса приложения. Например, меню Open Recent в текстовом редакторе показывает список недавно открытых документов. Вы не можете заполнить это меню во время создания графического интерфейса приложения, потому что каждый пользователь будет открывать разные документы, и нет никакого способа узнать эту информацию заранее.
В этом случае вам необходимо динамически заполнять меню в ответ на действия пользователя или состояние приложения. QMenu имеет сигнал .aboutToShow() говорящий о том, что вы можете подключиться к настраиваемому слоту для динамического заполнения объекта меню до его отображения на экране.
Чтобы продолжить разработку примера приложения, предположим, что вам нужно создать подменю Open Recent в разделе File и динамически заполнить его недавно открытыми файлами или документами. Для этого вам необходимо выполнить следующие действия:
- Создайте подменю Open Recent в разделе File.
- Закодируйте пользовательский слот, который динамически генерирует действия для заполнения меню.
- Подключите сигнал меню к пользовательскому слоту с помощью .aboutToShow() .
Вот код для создания подменю:
В выделенной строке вы добавляете подменю в меню File с заголовком «Open Recent» . В этом подменю пока нет параметров меню. Вам необходимо динамически создавать действия, чтобы заполнить его.
Вы можете сделать это, написав метод динамического создания действий и добавив их в подменю. Вот пример, показывающий общую логику, которую вы можете использовать:
В .populateOpenRecent() сначала удалите старые параметры, если они есть, из меню с помощью .clear() . Затем вы добавляете логику для динамического создания и подключения действий. Наконец, вы добавляете действия в меню, используя .addActions() .
В цикле for вы используете functools.partial() для добавления .triggered() сигнала, потом вы хотите передаете filename в качестве аргумента .openRecentFile() . Это довольно полезный метод, когда речь идет о соединении сигнала со слотом, который принимает дополнительные аргументы. Чтобы он работал, вам нужно импортировать метод partial() из functools .
Следующим шагом будет подключение сигнала .openRecentMenu к .populateOpenRecent() . Для этого добавьте следующую строку в конец ._connectActions() :
Теперь вам нужно написать код .openRecentFile() . Это метод, который ваше приложение будет вызывать, когда пользователи щелкают любое из динамически созданных действий:
Этот метод обновит текст объекта QLabel , который вы используете в качестве центрального виджета в вашем примере приложения.
Вот как ваше динамически создаваемое подменю работает на практике:
Когда указатель мыши находится над меню Open Recent, меню издает сигнал. Это приводит к вызову .populateOpenRecent() , который создает и связывает действия. Если вы щелкните имя файла, вы увидите, что центральная метка изменится соответствующим образом, чтобы отобразить сообщение.
Определение сочетаний клавиш для параметров меню и панели инструментов
Сочетания клавиш — важная функция в приложении с графическим интерфейсом. Сочетание клавиш — это комбинация клавиш, которую вы можете нажать на клавиатуре для быстрого доступа к некоторым из наиболее распространенных опций в приложении.
Вот несколько примеров сочетаний клавиш:
- Ctrl+C копирует что-то в буфер обмена.
- Ctrl+V вставляет что-то из буфера обмена.
- Ctrl+Z отменяет последнюю операцию.
- Ctrl+O открывает файлы.
- Ctrl+S сохраняет файлы.
В следующем разделе вы узнаете, как добавить в приложение сочетания клавиш, чтобы повысить производительность и удобство работы пользователей.
Использование ключевых последовательностей
До сих пор вы узнали, что QAction это универсальный класс для заполнения меню и панелей инструментов. QAction также предоставляет удобный способ определения сочетаний клавиш для пунктов меню и кнопок панели инструментов.
QAction имеет метод .setShortcut() . Этот метод принимает объект QKeySequence в качестве аргумента и возвращает shortcut.
QKeySequence предоставляет несколько конструкторов. В этом руководстве вы узнаете о двух из них:
- QKeySequence(ks, format) принимает в качестве аргументов последовательность клавиш на основе строки ( ks ) и формат ( format ) и создает объект QKeySequence .
- QKeySequence(key) принимает константу StandardKey в качестве аргумента и создает объект QKeySequence , который соответствует этим последовательностям ключей на базовой платформе.
Первый конструктор распознает следующие строки:
- «Ctrl»
- «Shift»
- «Alt»
- «Meta»
Вы можете создавать строки на основе последовательности клавиш, комбинируя эти строки с буквами, знаки препинания, цифры, именные ключи ( Up , Down , Home ), и функциональные клавиши ( «Ctrl+S» , «Ctrl+5» , «Alt+Home» , «Alt+F4» ). Вы можете передать до четырех из этих последовательностей строковых ключей в списке, разделенном запятыми.
Второй конструктор удобен, если вы разрабатываете многоплатформенное приложение и хотите использовать стандартные сочетания клавиш для каждой платформы. Например, QKeySequence.Copy вернет стандартное сочетание клавиш платформы для копирования объектов в буфер обмена.
Имея это общее представление о том, как определять сочетания клавиш для действий в PyQt, вы можете вернуться к своему образцу приложения и добавить несколько сочетаний клавиш. Для этого вам необходимо обновить ._createActions() :
Сначала вам нужно импортировать QKeySequence . Внутри ._createActions() первые три строки создают сочетания клавиш с использованием последовательности клавиш на основе строки. Это быстрый способ добавить к вашему действию сочетания клавиш. Во вторых трех строках вы используете QKeySequence со стандартным сочетанием клавиш.
Если вы запустите пример приложения с этими дополнениями, ваши меню будут выглядеть следующим образом:
Теперь в пунктах вашего меню справа отображается сочетание клавиш. Если вы нажмете любую из этих комбинаций клавиш, вы выполните соответствующее действие.
Использование быстрого доступа с клавиатуры
Есть еще одна альтернатива, которую вы можете использовать для добавления сочетаний клавиш или быстрого доступа в пункты меню ваших приложений.
Вы могли заметить, что при установке текста для меню или параметра меню вы обычно вставляете в текст символ амперсанда ( & ). Вы делаете это так, чтобы буква сразу после амперсанда была подчеркнута при отображении в тексте меню или пункта меню. Например, если вы поместите амперсанд перед буквой F в заголовке меню File ( «&File» ), то при отображении заголовка меню буква F будет подчеркнута.
В случае строки меню использование амперсанда позволяет вызывать любое меню, нажимая Alt вместе с подчеркнутой буквой в заголовке меню.
После того, как вы запустили меню, вы можете получить доступ к любой опции меню, нажав подчеркнутую букву в тексте опции. Например, в файле вы можете получить доступ к опции Exit , нажав букву E.
Эта функция позволит вам предоставить быстрые доступ к опциям с помощью клавиатуры для пользователей, которые предпочитают использовать клавиатуру для работы с вашими приложениями. Этот метод особенно полезен для параметров, которые не предоставляют явного сочетания клавиш.
Создание меню и панелей инструментов: передовой опыт и советы
Когда вы создаете меню и панели инструментов с помощью Python и PyQt, вы должны следовать некоторым стандартам, которые обычно считаются лучшими практиками в программировании графического интерфейса. Вот краткий список:
- Расставьте меню в общепринятом порядке. Например, если у вас есть меню File, оно должно быть первым слева направо. Если у вас есть меню Edit, то оно должно быть вторым. Help должна быть в самом конце меню и тд.
- Заполните свои меню общими опциями для типа разрабатываемого приложения. Например, в текстовом редакторе меню File обычно включают такие параметры, как Create, Open, Save и Exit. Меню редактирования часто включают такие параметры, как Copy, Paste, Cut, Undo и т.д.
- Для общих параметров используйте стандартные сочетания клавиш. Например, используйте Ctrl+C для копирования, Ctrl+V для вставки, Ctrl+X для вырезания и так далее.
- Используйте разделители для разделения несвязанных опций. Эти визуальные подсказки упростят навигацию по вашему приложению.
- Добавьте многоточие ( . ) к заголовку параметров, запускающих дополнительные диалоги. Например, используйте Save As… вместо Save As, About… вместо About и т.д.
- Используйте амперсанды ( & ) в параметрах меню, чтобы обеспечить удобного и быстрого доступа с клавиатуры. Например, «&Open» вместо «Open» , «&Exit» вместо «Exit» .
Если вы будете следовать этим рекомендациям, ваши приложения с графическим пользовательским интерфейсом будут знакомыми и привлекательными для ваших пользователей.
Создание строк состояния Python в PyQt
Строка состояния представляет собой горизонтальную панель, которая обычно находится в нижней части главного окна в приложении GUI. Его основная цель — отображать информацию о текущем статусе приложения. Строку состояния также можно разделить на разделы, чтобы отображать различную информацию по каждому разделу.
Согласно документации Qt, существует три типа индикаторов состояния:
- Временные индикаторы на короткое время занимают почти всю строку состояния для отображения текстов всплывающих подсказок, пунктов меню и другой информации, зависящей от времени.
- Обычные индикаторы занимают часть строки состояния и отображают информацию, к которой пользователи могут периодически обращаться, например, количество слов в текстовом процессоре. Они могут быть ненадолго скрыты временными индикаторами.
- Постоянные индикаторы всегда отображаются в строке состояния, даже если временный индикатор активирован. Они используются для отображения важной информации о текущем режиме приложения, например, когда была нажата клавиша Caps Lock.
Вы можете добавить строку состояния к своему приложению в стиле главного окна, используя один из следующих вариантов:
- Вызвать .statusBar() у объект QMainWindow . .statusBar() создает и возвращает пустую строку состояния для главного окна.
- Создайте объект QStatusBar , затем вызовите .setStatusBar() у главного окна с объектом строки состояния в качестве аргумента. Таким образом, ваш объект строки состояния будет установлен в качестве строки состояния главного окна.
Здесь у вас есть две альтернативные реализации для добавления строки состояния в образец приложения:
Обе реализации дают одинаковый результат. Однако в большинстве случаев вы будете использовать первую реализацию для создания строк состояния. Обратите внимание, что для работы второй реализации вам необходимо выполнить импорт QStatusBar из PyQt5.QtWidgets .
Добавьте одну из вышеперечисленных реализаций в свое приложение в Window , а затем вызовите ._createStatusBar() в инициализаторе класса. С этими дополнениями, когда вы снова запустите приложение, вы увидите такое окно:
Теперь ваше приложение имеет строку состояния в нижней части главного окна. Строка состояния почти не видна, но если вы присмотритесь, то заметите небольшой пунктирный треугольник в правом нижнем углу окна.
Отображение временных сообщений о состоянии
Основная цель строки состояния — представить информацию о состоянии пользователям вашего приложения. Чтобы отображать временные сообщения о состоянии в строке состояния, вам необходимо использовать QStatusBar.showMessage() . Этот метод принимает следующие два аргумента:
- message содержит сообщение индикатора состояния в виде строки.
- timeout содержит количество миллисекунд, в течение которых сообщение будет отображаться в строке состояния.
Если timeout равен 0 , что является его значением по умолчанию, то сообщение остается в строке состояния до вызова .clearMessage() или .showMessage() в строке состояния.
Если в строке состояния есть активное сообщение и вы вызовете .showMessage() с новым сообщением, новое сообщение будет скрывать или заменять старое.
Перейдите в свой образец приложения и добавьте следующую строку в ._createStatusBar() :
Последняя строка ._createStatusBar() заставит ваше приложение отображать сообщение Ready в строке состояния приложения в течение миллисекунд 3000 :
Когда вы запускаете приложение, в строке состояния отображается сообщение Ready . Через 3000 миллисекунды сообщение исчезает, а строка состояния очищается и готова к отображению нового сообщения о состоянии.
Отображение постоянных сообщений в строке состояния
Вы также можете отображать постоянные сообщения в строке состояния вашего приложения. Постоянное сообщение информирует пользователя об общем состоянии приложения. Например, в текстовом редакторе вы можете отобразить постоянное сообщение с информацией о кодировке текста в текущем открытом файле.
Чтобы добавить постоянные сообщения в строки состояния, вы используете объект QLabel для хранения сообщения. Затем вы добавляете QLabel в строку состояния, вызвав .addPermanentWidget() . Этот метод добавляет данный виджет в текущую строку состояния. Родитель виджета установлен в строку состояния.
.addPermanentWidget() принимает следующие два аргумента:
- widget содержит объект виджета, который вы хотите добавить в строку состояния. Некоторые часто используемые виджеты: QLabel , QToolButton и QProgressBar .
- stretch используется для вычисления подходящего размера для виджета по мере увеличения и уменьшения строки состояния. По умолчанию 0 это означает, что виджет будет занимать минимальное количество места.
Имейте в виду, что постоянный виджет не будет скрыт или заменен временными сообщениями. .addPermanentWidget() находит виджеты в правой части строки состояния.
Допустим, вы хотите превратить образец приложения в текстовый редактор и добавить в строку состояния сообщение, в котором отображается информация о количестве слов в текущем файле. Для этого вы можете создать вызываемый метод .getWordCount() , а затем добавить постоянное сообщение, используя .addPermanentWidget() и объект QLabel :
Этот метод добавляет логику для вычисления количества слов в текущем открытом документе. Теперь вы можете отображать эту информацию как постоянное сообщение:
В последних двух строках вы сначала создаете объект QLabel ( wcLabel ) для хранения сообщения о количестве слов. Чтобы создать сообщение, вы используете f-строку, в которую вы вставляете вызов .getWordCount() , чтобы получить информацию о количестве слов. Затем вы добавляете метку в строку состояния с помощью .addPermanentWidget() .
В этом случае вы создаете объект QLabel как атрибут экземпляра, потому что количество слов необходимо обновлять в соответствии с изменениями, которые пользователь вносит в текущий файл.
Если вы запустите приложение с этим обновлением, вы увидите сообщение о подсчете слов в правой части строки состояния:
В строке состояния отображается сообщение, информирующее пользователя о количестве слов в гипотетическом текущем файле. Возможность предоставить пользователю постоянную информацию или другие параметры в строке состояния весьма полезна и может помочь вам значительно улучшить взаимодействие с пользователем для ваших приложений.
Добавление подсказок к действиям
Когда дело доходит до создания приложений с графическим пользовательским интерфейсом, важно предлагать вашим пользователям полезные советы о конкретных функциях интерфейса приложения. Подсказки — это короткие сообщения, которые предоставляют пользователю краткое руководство по некоторым параметрам, которые предлагает приложение.
Действия PyQt позволяют определять следующие типы подсказок:
- Подсказки по состоянию — это подсказки, которые приложение показывает в строке состояния, когда пользователь наводит указатель мыши на пункт меню или кнопку панели инструментов. По умолчанию всплывающая подсказка содержит пустую строку.
- Всплывающие подсказки — это подсказки, которые приложение показывает как плавающие сообщения, когда пользователь наводит указатель мыши на кнопку или виджет панели инструментов. По умолчанию всплывающая подсказка содержит текст, определяющий текущее действие.
Чтобы узнать, как работают подсказки, вы можете добавить несколько подсказок по состоянию и всплывающих подсказок в образец приложения. Перейдите к ._createActions() и добавьте следующие строки кода:
Три выделенные строки устанавливают сообщение «Create a new file» как статус и всплывающую подсказку для параметра New. Если вы запустите приложение сейчас, то увидите, что параметр New показывает пользователю краткую, но информативную подсказку:
Если щелкнуть меню File и удерживать указатель мыши на New, вы увидите сообщение с подсказкой, отображаемое в левой части строки состояния. С другой стороны, если вы наведете указатель мыши на кнопку New на панели инструментов, вы увидите сообщение в строке состояния, а также в виде небольшого плавающего прямоугольника рядом с указателем мыши.
В общем, добавление справочных подсказок в меню и панели инструментов Python считается передовой практикой. Это упростит пользователям навигацию и изучение ваших приложений с графическим интерфейсом.