Qmainwindow pyqt6 как сделать сетку
Перейти к содержимому

Qmainwindow pyqt6 как сделать сетку

  • автор:

 

Python-сообщество

При попытке создать меню (а так же тулбар и статусбар) при наследовании класса QtGui.QWidget — возникает ошибка, мол нету такого метода, естественно, т.к. в туториале меню создается из QMainWindow.

При использовании QMainWindow вроде бы все хорошо, и меню можно создать и виджеты которые необходимы, но есть одно но, сетка QtGui.QGridLayout() не работает, что есть плохо, т.к. это очень удобная штука и передвигать каждый виджет через object.move() не айс.

Собственно суть вопроса — можно ли как нибудь создать меню (тулбар и статус бар) в QWidget или же создать сетку grid в QMainWindow, или может быть как нибудь можно объединить эти 2 класса в 1 графическое приложение? C PyQT только начал знакомиться, поэтому возник такой вопрос.

PyQt6 Layouts
Use layouts to effortlessly position widgets within the window

So far we’ve successfully created a window, and we’ve added a widget to it. However we normally want to add more than one widget to a window, and have some control over where it ends up. To do this in Qt we use layouts. There are 4 basic layouts available in Qt, which are listed in the following table.

Layout Behavior
QHBoxLayout Linear horizontal layout
QVBoxLayout Linear vertical layout
QGridLayout In indexable grid XxY
QStackedLayout Stacked (z) in front of one another

You can also design and lay out your interface graphically using the Qt designer. Here we’re using code, so you can understand the underlying system.

As you can see, there are three positional layouts available in Qt. The VBoxLayout , QHBoxLayout and QGridLayout . In addition there is also QStackedLayout which allows you to place widgets one on top of the other within the same space, yet showing only one layout at a time.

Before we start we need a simple application outline. Save the following code in a file named app.py — we’ll modify this application to experiment with different layouts.

To make it easier to visualize the layouts, we’ll first create a simple custom widget that displays a solid color of our choosing. This will help to distinguish widgets that we add to the layout. Add the following code to your file as a new class at the top level —

In this code we subclass QWidget to create our own custom widget Color . We accept a single parameter when creating the widget — color (a str ). We first set .setAutoFillBackground to True to tell the widget to automatically fill its background with the window cooler. Next we get the current palette (which is the global desktop palette by default) and change the current QPalette.Window color to a new QColor described by the value color we passed in. Finally we apply this palette back to the widget. The end result is a widget that is filled with a solid color, that we specified when we created it.

If you find the above confusing, don’t worry too much. We’ll cover custom widgets in more detail later. For now it’s sufficient that you understand that calling you can create a solid-filled red widget by doing the following:

First let’s test our new Color widget by using it to fill the entire window in a single color. Once it’s complete we can add it to the QMainWindow using .setCentralWidget and we get a solid red window.

Run it! The window will appear, filled completely with the color red. Notice how the widget expands to fill all the available space.

Next we’ll look at each of the available Qt layouts in turn. Note that to add our layouts to the window we will need a dummy QWidget to hold the layout.

QVBoxLayout vertically arranged widgets

With QVBoxLayout you arrange widgets one above the other linearly. Adding a widget adds it to the bottom of the column.

A QVBoxLayout, filled from top to bottom.A QVBoxLayout, filled from top to bottom.

Let’s add our widget to a layout. Note that in order to add a layout to the QMainWindow we need to apply it to a dummy QWidget . This allows us to then use .setCentralWidget to apply the widget (and the layout) to the window. Our colored widgets will arrange themselves in the layout, contained within the QWidget in the window. First we just add the red widget as before.

Run it! Notice the border now visible around the red widget. This is the layout spacing — we’ll see how to adjust that later.

If you add a few more colored widgets to the layout you’ll notice that they line themselves up vertical in the order they are added.

QHBoxLayout horizontally arranged widgets

QHBoxLayout is the same, except moving horizontally. Adding a widget adds it to the right hand side.

A QHBoxLayout, filled from left to right.A QHBoxLayout, filled from left to right.

To use it we can simply change the QVBoxLayout to a QHBoxLayout . The boxes now flow left to right.

Nesting layouts

For more complex layouts you can nest layouts inside one another using .addLayout on a layout. Below we add a QVBoxLayout into the main QHBoxLayout . If we add some widgets to the QVBoxLayout , they’ll be arranged vertically in the first slot of the parent layout.

Run it! The widgets should arrange themselves in 3 columns horizontally, with the first column also containing 3 widgets stacked vertically. Experiment!

You can set the spacing around the layout using .setContentMargins or set the spacing between elements using .setSpacing .

The following code shows the combination of nested widgets and layout margins and spacing. Experiment with the numbers til you get a feel for them.

QGridLayout widgets arranged in a grid

As useful as they are, if you try and using QVBoxLayout and QHBoxLayout for laying out multiple elements, e.g. for a form, you’ll find it very difficult to ensure differently sized widgets line up. The solution to this is QGridLayout .

A QGridLayout showing the grid positions for each location.A QGridLayout showing the grid positions for each location.

QGridLayout allows you to position items specifically in a grid. You specify row and column positions for each widget. You can skip elements, and they will be left empty.

Usefully, for QGridLayout you don’t need to fill all the positions in the grid.

A QGridLayout with unfilled slots.A QGridLayout with unfilled slots.

QStackedLayout multiple widgets in the same space

The final layout we’ll cover is the QStackedLayout . As described, this layout allows you to position elements directly in front of one another. You can then select which widget you want to show. You could use this for drawing layers in a graphics application, or for imitating a tab-like interface. Note there is also QStackedWidget which is a container widget that works in exactly the same way. This is useful if you want to add a stack directly to a QMainWindow with .setCentralWidget .

QStackedLayout — in use only the uppermost widget is visible, which is by default the first widget added to the layout.QStackedLayout — in use only the uppermost widget is visible, which is by default the first widget added to the layout.

QStackedLayout, with the 2nd (1) widget selected and brought to the front.QStackedLayout, with the 2nd (1) widget selected and brought to the front.

QStackedWidget is exactly how tabbed views in applications work. Only one view (‘tab’) is visible at any one time. You can control which widget to show at any time by using .setCurrentIndex() or .setCurrentWidget() to set the item by either the index (in order the widgets were added) or by the widget itself.

Below is a short demo using QStackedLayout in combination with QButton to to provide a tab-like interface to an application:

A custom tab-like interface implemented using QStackedLayout.A custom tab-like interface implemented using QStackedLayout.

Helpfully. Qt actually provide a built-in TabWidget that provides this kind of layout out of the box — albeit in widget form. Below the tab demo is recreated using QTabWidget :

A tabbed interface using the QTabWidget.A tabbed interface using the QTabWidget.

As you can see, it’s a little more straightforward — and a bit more attractive! You can set the position of the tabs using the cardinal directions, toggle whether tabs are moveable with .setMoveable . You’ll notice that the macOS tab bar looks quite different to the others — by default on macOS tabs take on a pill or bubble style. On macOS this is typically used for tabbed configuration panels. For documents, you can turn on document mode to give slimline tabs similar to what you see on other platforms. This option has no effect on other platforms.

QTabWidget in document mode on macOS.QTabWidget in document mode on macOS.

Qmainwindow pyqt6 как сделать сетку

Summary: in this tutorial, you’ll learn how to use the PyQt QMainWindow to create the main window of an application.

Introduction to the PyQt QMainWindow

So far, you have learned how to use QWidget to create the main window for applications. The QWidget works fine for simple applications but doesn’t support common features of full-blown desktop applications like menu bars, toolbars, and status bars.

PyQt provides you with QMainWindow that support a menu bar, toolbars, and status bar out of the box. So instead of subclassing the QWidget class, you can create the main window by inheriting it from the QMainWindow class like this:

PyQt divides the QMainWindow widget into some sections as shown in the following picture:

QMainWindow Layout

Note that you should not set a layout for the QMainWindow . If you do so, you’ll break the preset arrangement of the widgets.

Set the central widget

A QMainWindow has one and only one central widget. To set a widget as a central widget, you use the setCentralWidget() method of the QMainWindow object.

For example, the following uses the setCentralWidget() method to set the QTextEdit as the central widget:

Set the window title

To set the title for the main window, you use the setWindowTitle() method. For example:

Set the window icon

To set the icon for the window, you use the setWindowIcon() method. For example:

In this example:

  • First, create a QIcon and pass in the image path ./assets/editor.png
  • Second, pass the QIcon object to the setWindowIcon() method to set the icon for the window.
Set the geometry for the main window

The geometry defines the coordinate of the window (x,y) or (top, left) and the window’s width and height:

To set the geometry for the window, you use the setGeometry() method of the QMainWindow object. For example, the following uses the setGeometry() method to set the geometry for the window:

In this example, the window will appear at (100, 100) with a width of 500px and height of 300px:

The following program creates the main window using the QMainWindow , sets the central widget, and the window’s title, icon, and geometry:

Adding a menu bar

To add a menu bar to the main window, you use the menuBar() method of the QMainWindow :

The menuBar() method returns a QMenuBar object. If a QMenuBar object doesn’t exist, the menuBar() will create a new QMenuBar object before returning it. Otherwise, it returns the existing QMenuBar object.

By default, the menu bar is empty. To add a menu to a menu bar, you use the addMenu() method. For example, the following adds three submenus File, Edit, and Help:

The addMenu() method returns a QMenu object that represents a drop-down submenu. The string that we pass to the addMenu() method is for labeling the menu in the menu bar.

The character & will underscore the character of the menu label when you press the ALT key. For example, &File will underscore the letter F .

Action

To add menu items to a menu, you need to create actions. An action is an object of the QAction class that represents the functionality of the application.

An action object requires a name and a callback to function properly. In addition, an action may contain an icon and a keyboard shortcut.

To create an action, you can call the addAction() method of a QMenu . For example, the following adds three actions to the File menu:

If you click the New menu item, the QTextEdit widget will clear all contents. Similarly, by clicking the Open menu item, you’ll see a message on the console, and clicking the Exit menu will end the program.

Also, you can create a QAction object and connects its triggered signal to a slot. For example, the following creates undo and redo actions and adds them to the Edit menu:

Note that the undo and redo actions have icons and keyboard shortcuts.

The following program shows how to add a menu bar and menu items to the File and Edit menus:

Adding a toolbar

A toolbar is a bar of icons and/or text that expose the most commonly used function of the application. To add a toolbar to the application:

  • First, create a new QToolBar object.
  • Second, add the toolbar to the application using the addToolbar() method of the QMainWindow .

For example, the following creates a new toolbar and adds it to the application:

To add an item to the toolbar, you use the addAction() method of the QToolBar object. For example:

The following program shows add a toolbar with the undo and redo actions:

Adding a status bar

A status bar is a bar located at the bottom of the main window. Typically, a status bar displays short text messages and/or informational widgets.

To add a status bar to the application, you create a QStatusBar object and set it to the main window using the setStatusBar() method:

The statusBar() method of the QMainWindow returns a QStatusBar object. It will create a new QStatusBar object if the status bar doesn’t exist.

To display a short message, you use the showMessage() method of the QStatusBar object:

Or you can directly use the QStatusBar object returned by the statusBar() method of the main window:

PyQt6 Layouts
Use layouts to effortlessly position widgets within the window

So far we’ve successfully created a window, and we’ve added a widget to it. However we normally want to add more than one widget to a window, and have some control over where it ends up. To do this in Qt we use layouts. There are 4 basic layouts available in Qt, which are listed in the following table.

Layout Behavior
QHBoxLayout Linear horizontal layout
QVBoxLayout Linear vertical layout
QGridLayout In indexable grid XxY
QStackedLayout Stacked (z) in front of one another

You can also design and lay out your interface graphically using the Qt designer. Here we’re using code, so you can understand the underlying system.

As you can see, there are three positional layouts available in Qt. The VBoxLayout , QHBoxLayout and QGridLayout . In addition there is also QStackedLayout which allows you to place widgets one on top of the other within the same space, yet showing only one layout at a time.

Before we start we need a simple application outline. Save the following code in a file named app.py — we’ll modify this application to experiment with different layouts.

To make it easier to visualize the layouts, we’ll first create a simple custom widget that displays a solid color of our choosing. This will help to distinguish widgets that we add to the layout. Add the following code to your file as a new class at the top level —

In this code we subclass QWidget to create our own custom widget Color . We accept a single parameter when creating the widget — color (a str ). We first set .setAutoFillBackground to True to tell the widget to automatically fill its background with the window cooler. Next we get the current palette (which is the global desktop palette by default) and change the current QPalette.Window color to a new QColor described by the value color we passed in. Finally we apply this palette back to the widget. The end result is a widget that is filled with a solid color, that we specified when we created it.

If you find the above confusing, don’t worry too much. We’ll cover custom widgets in more detail later. For now it’s sufficient that you understand that calling you can create a solid-filled red widget by doing the following:

First let’s test our new Color widget by using it to fill the entire window in a single color. Once it’s complete we can add it to the QMainWindow using .setCentralWidget and we get a solid red window.

 

Run it! The window will appear, filled completely with the color red. Notice how the widget expands to fill all the available space.

Next we’ll look at each of the available Qt layouts in turn. Note that to add our layouts to the window we will need a dummy QWidget to hold the layout.

QVBoxLayout vertically arranged widgets

With QVBoxLayout you arrange widgets one above the other linearly. Adding a widget adds it to the bottom of the column.

A QVBoxLayout, filled from top to bottom.A QVBoxLayout, filled from top to bottom.

Let’s add our widget to a layout. Note that in order to add a layout to the QMainWindow we need to apply it to a dummy QWidget . This allows us to then use .setCentralWidget to apply the widget (and the layout) to the window. Our colored widgets will arrange themselves in the layout, contained within the QWidget in the window. First we just add the red widget as before.

Run it! Notice the border now visible around the red widget. This is the layout spacing — we’ll see how to adjust that later.

If you add a few more colored widgets to the layout you’ll notice that they line themselves up vertical in the order they are added.

QHBoxLayout horizontally arranged widgets

QHBoxLayout is the same, except moving horizontally. Adding a widget adds it to the right hand side.

A QHBoxLayout, filled from left to right.A QHBoxLayout, filled from left to right.

To use it we can simply change the QVBoxLayout to a QHBoxLayout . The boxes now flow left to right.

Nesting layouts

For more complex layouts you can nest layouts inside one another using .addLayout on a layout. Below we add a QVBoxLayout into the main QHBoxLayout . If we add some widgets to the QVBoxLayout , they’ll be arranged vertically in the first slot of the parent layout.

Run it! The widgets should arrange themselves in 3 columns horizontally, with the first column also containing 3 widgets stacked vertically. Experiment!

You can set the spacing around the layout using .setContentMargins or set the spacing between elements using .setSpacing .

The following code shows the combination of nested widgets and layout margins and spacing. Experiment with the numbers til you get a feel for them.

QGridLayout widgets arranged in a grid

As useful as they are, if you try and using QVBoxLayout and QHBoxLayout for laying out multiple elements, e.g. for a form, you’ll find it very difficult to ensure differently sized widgets line up. The solution to this is QGridLayout .

A QGridLayout showing the grid positions for each location.A QGridLayout showing the grid positions for each location.

QGridLayout allows you to position items specifically in a grid. You specify row and column positions for each widget. You can skip elements, and they will be left empty.

Usefully, for QGridLayout you don’t need to fill all the positions in the grid.

A QGridLayout with unfilled slots.A QGridLayout with unfilled slots.

QStackedLayout multiple widgets in the same space

The final layout we’ll cover is the QStackedLayout . As described, this layout allows you to position elements directly in front of one another. You can then select which widget you want to show. You could use this for drawing layers in a graphics application, or for imitating a tab-like interface. Note there is also QStackedWidget which is a container widget that works in exactly the same way. This is useful if you want to add a stack directly to a QMainWindow with .setCentralWidget .

QStackedLayout — in use only the uppermost widget is visible, which is by default the first widget added to the layout.QStackedLayout — in use only the uppermost widget is visible, which is by default the first widget added to the layout.

QStackedLayout, with the 2nd (1) widget selected and brought to the front.QStackedLayout, with the 2nd (1) widget selected and brought to the front.

QStackedWidget is exactly how tabbed views in applications work. Only one view (‘tab’) is visible at any one time. You can control which widget to show at any time by using .setCurrentIndex() or .setCurrentWidget() to set the item by either the index (in order the widgets were added) or by the widget itself.

Below is a short demo using QStackedLayout in combination with QButton to to provide a tab-like interface to an application:

A custom tab-like interface implemented using QStackedLayout.A custom tab-like interface implemented using QStackedLayout.

Helpfully. Qt actually provide a built-in TabWidget that provides this kind of layout out of the box — albeit in widget form. Below the tab demo is recreated using QTabWidget :

A tabbed interface using the QTabWidget.A tabbed interface using the QTabWidget.

As you can see, it’s a little more straightforward — and a bit more attractive! You can set the position of the tabs using the cardinal directions, toggle whether tabs are moveable with .setMoveable . You’ll notice that the macOS tab bar looks quite different to the others — by default on macOS tabs take on a pill or bubble style. On macOS this is typically used for tabbed configuration panels. For documents, you can turn on document mode to give slimline tabs similar to what you see on other platforms. This option has no effect on other platforms.

QTabWidget in document mode on macOS.QTabWidget in document mode on macOS.

We’ll encounter more of these advanced widgets later.

Create GUI Applications with Python & Qt6

To support developers in [[ countryRegion ]] I give a [[ localizedDiscount[couponCode] ]]% discount with the code [[ couponCode ]] — Enjoy!

Python-сообщество

При попытке создать меню (а так же тулбар и статусбар) при наследовании класса QtGui.QWidget — возникает ошибка, мол нету такого метода, естественно, т.к. в туториале меню создается из QMainWindow.

При использовании QMainWindow вроде бы все хорошо, и меню можно создать и виджеты которые необходимы, но есть одно но, сетка QtGui.QGridLayout() не работает, что есть плохо, т.к. это очень удобная штука и передвигать каждый виджет через object.move() не айс.

Собственно суть вопроса — можно ли как нибудь создать меню (тулбар и статус бар) в QWidget или же создать сетку grid в QMainWindow, или может быть как нибудь можно объединить эти 2 класса в 1 графическое приложение? C PyQT только начал знакомиться, поэтому возник такой вопрос.

How do I add/remove a layout when triggering action in PyQt6? How do I change the order of a layout?

I’m in the process of making a calculator for a project, and I wanted it so that if I press an action in the menu bar it turns into a scientific calculator, and if I uncheck it, it goes back to a basic calculator.

So far I was able to successfully add the buttons for the scientific calculator, but I want it to go to the left of the horizontal layout (so the basic buttons are on the right, and the advance buttons are on the left) but I have no idea how to do that. I also don’t know yet how to revert it back to a basic calculator once it becomes a scientific calculator. Also for some reason the actions of the buttons of the scientific calculator don’t seem to be working properly (if I type a button, it should add a text to the QLineEdit ). I’m quite at a loss as I don’t know where to go from here.

Qmainwindow pyqt6 как сделать сетку

QVBoxLayout, заполняемый сверху вниз

QHBoxLayout: горизонтально расположенные виджеты

QHBoxLayout, заполняемый слева направо

QGridLayout: виджеты в сетке

В QGridLayout показываются позиции сетки для каждого местоположения

QGridLayout с незаполненными слотами

QStackedLayout: несколько виджетов в одном месте

QStackedLayout — здесь оказывается видимым только самый верхний виджет, который первым добавляется в макетQStackedLayout — здесь оказывается видимым только самый верхний виджет, который первым добавляется в макет QStackedLayout — здесь выбран 2-й виджет (обозначен цифрой 1) и выдвинут вперёдQStackedLayout — здесь выбран 2-й виджет (обозначен цифрой 1) и выдвинут вперёд

Пользовательский интерфейс в виде вкладок, реализованный с помощью QStackedLayout

Интерфейс в виде вкладок с использованием QTabWidget

QTabWidget в режиме документа на macOS

Панели инструментов, меню и QAction

Стандартные элементы графического интерфейса

Окно с панелью инструментовОкно с панелью инструментов

Панель инструментов с кнопкой QActionПанель инструментов с кнопкой QAction

Текст строки состояния обновляется при наведении курсора на actions (действия)

Включённая кнопка на панели инструментовВключённая кнопка на панели инструментов

Набор иконок Fugue от Юсукэ Камияманэ

Кнопка действий теперь с иконкойКнопка действий теперь с иконкой

Menus and toolbars in PyQt6

In this part of the PyQt6 tutorial, we create a statusbar, menubar and a toolbar. A menu is a group of commands located in a menubar. A toolbar has buttons with some common commands in the application. Statusbar shows status information, usually at the bottom of the application window.

PyQt6 QMainWindow

The QMainWindow class provides a main application window. This enables to create a classic application skeleton with a statusbar, toolbars, and a menubar.

PyQt6 statusbar

A statusbar is a widget that is used for displaying status information.

The statusbar is created with the help of the QMainWindow widget.

To get the statusbar, we call the statusBar method of the QMainWindow class. The first call of the method creates a status bar. Subsequent calls return the statusbar object. The showMessage displays a message on the statusbar.

PyQt6 simple menu

A menubar is a common part of a GUI application. It is a group of commands located in various menus. (Mac OS treats menubars differently. To get a similar outcome, we can add the following line: menubar.setNativeMenuBar(False) .)

In the above example, we create a menubar with one menu. This menu contains one action which terminates the application if selected. A statusbar is created as well. The action is accessible with the Ctrl + Q shortcut.

QAction is an abstraction for actions performed with a menubar, toolbar, or with a custom keyboard shortcut. In the above three lines, we create an action with a specific icon and an ‘Exit’ label. Furthermore, a shortcut is defined for this action. The third line creates a status tip which is shown in the statusbar when we hover a mouse pointer over the menu item.

When we select this particular action, a triggered signal is emitted. The signal is connected to the quit method of the QApplication widget. This terminates the application.

The menuBar method creates a menubar. We create a file menu with addMenu and add the action with addAction .

PyQt6 submenu

A submenu is a menu located inside another menu.

In the example, we have two menu items; one is located in the File menu and the other one in the File’s Import submenu.

New menu is created with QMenu .

An action is added to the submenu with addAction .

SubmenuFigure: Submenu

PyQt6 check menu

In the following example, we create a menu that can be checked and unchecked.

The code example creates a View menu with one action. The action shows or hides a statusbar. When the statusbar is visible, the menu item is checked.

With the checkable option we create a checkable menu.

Since the statusbar is visible from the start, we check the action with setChecked method.

Depending on the state of the action, we show or hide the statusbar.

Check menuFigure: Check menu

PyQt6 context menu

A context menu, also called a popup menu, is a list of commands that appears under some context. For example, in a Opera web browser when we right click on a web page, we get a context menu. Here we can reload a page, go back, or view a page source. If we right click on a toolbar, we get another context menu for managing toolbars.

To work with a context menu, we have to reimplement the contextMenuEvent method.

The context menu is displayed with the exec method. The get the coordinates of the mouse pointer from the event object. The mapToGlobal method translates the widget coordinates to the global screen coordinates.

If the action returned from the context menu equals to quit action, we terminate the application.

PyQt6 toolbar

Menus group all commands that we can use in an application. Toolbars provide a quick access to the most frequently used commands.

In the above example, we create a simple toolbar. The toolbar has one tool action, an exit action which terminates the application when triggered.

Similar to the menubar example above, we create an action object. The object has a label, icon, and a shorcut. A quit method of the QApplication is connected to the triggered signal.

The toolbar is created with the addToolBar method. We add an action object to the toolbar with addAction .

ToolbarFigure: Toolbar

PyQt6 main window

In the last example of this section, we create a menubar, toolbar, and a statusbar. We also create a central widget.

This code example creates a skeleton of a classic GUI application with a menubar, toolbar, and a statusbar.

Here we create a text edit widget. We set it to be the central widget of the QMainWindow . The central widget occupies all space that is left.

Main windowFigure: Main window

In this part of the PyQt6 tutorial, we worked with menus, toolbars, a statusbar, and a main application window.

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *