#5 — Отображение изображения и статуса

В уроке мы научимся добавлять изображение в приложение, а также научимся работать с компонентом QStatusBar. Мы рассмотрим несколько способов добавление картинок, а также отображение различных статусов.
Видеоурок
В фреймворке Qt нет компонента, который отвечает конкретно за картинки. Чтобы добавить изображение в программу необходимо добавить текстовый объект и при помощи кода разместить в нем изображение.
Все изображения лучше всего хранить в самом проекте, а не на компьютере в какой-либо папке. Для хранения файлов в проекте необходимо создать папку resource и в неё добавить файлы.
Чтобы отобразить картинку необходимо использовать класс QPixMap , а также приблизительно следующий код:
QPixmap pix(":/resourec/img/image_name.png"); int w = ui->image->width(); int h = ui->image->height(); ui->image->setPixmap(pix.scaled(w, h, Qt::KeepAspectRatio));
Весь код записан в главном методе MainWindow , который вызывается каждый раз при создании приложения.
Статус бар
Для работы со статус баром используется объект statusBar , который автоматически присутствует в любом пустом приложении. Чтобы поместить туда информацию необходимо воспользоваться методом «showMessage».
Как вывести фоновую картинку PyQt5?
Все прекрасно работало, после пришлось переустановить ОС, вместе с ним и питон, запускаю проект, и нет картинки. Выводит следущее сообещие: Could not create pixmap from bg-01.jpg
Изображение лежит в папке с дирикторией.
Пробовал откатывать версию PyQt5. Не помогло.
- Вопрос задан более двух лет назад
- 464 просмотра
1 комментарий
Простой 1 комментарий
Масштабирование изображения в QWidget
Начнем с функции main — ее задача создать экземпляр главного окна и запустить обработку событий:
#include «mainwindow.h» #include int main(int argc, char *argv[])
В проект добавим форму Qt Designer — MainWindow , класс которой наследует QMainWindow. На форму кинем кнопку ( QPushButton ) с именем load и объект для отображения картинки (экземпляр QLabel ). Немного перепишем содержимое сгенерированных файлов.
В заголовочном файле:
namespace Ui < class MainWindow; >class MainWindow : public QMainWindow < Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void load_file(); private: Ui::MainWindow* ui; >;
Добавился приватный слот load_file, который будет вызываться при нажатии на кнопку.
В файле реализации:
#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) < ui->setupUi(this); connect(ui->open, SIGNAL(clicked(bool)), SLOT(load_file())); > void MainWindow::load_file() < auto path = QFileDialog::getOpenFileName( this, "Open Dialog", "", "*.png *.jpg *.bmp *.JPG"); if (path.isEmpty()) return; QPixmap pixmap(path); ui->image->setPixmap(pixmap); > MainWindow::~MainWindow()
В конструктор добавлено соединения сигнала от кнопки со слотом-обработчиком. Слот создает стандартный диалог выбора файла, одним из аргументов при этом задаются расширения открываемых файлов. Функция выбора файла возвращает путь, выбранный пользователем (или пустую строку если пользователь решил ничего не выбирать). Путь используется при конструировании объекта типа QPixmap , который передается в функцию setPixmap объекта на форме.
В результате мы получили приложение, которое умеет открывать картинку и отображать ее на QLabel , однако картинка не масштабируется (ведь на настоящий момент наш код использует стандартный QLabel ), чтобы решить проблему нам нужен новый класс.
Посмотрим как работает стандартный QLabel . Этот класс имеет метод setPixmap , который копирует переданную картинку в свой внутренний буфер и запускает обновление (метод paintEvent ). Функция paintEvent (виртуальная, можно написать свою реализацию) смотрит что для QLabel была выставлена картинка и отрисовывает ее (не так как нам надо), но кроме этого она делает еще много всего, например рисует текст, анимацию ( QMovie ) и т. п. Таким образом, если мы создадим наследника класс QLabel — то задавать нужное нам поведение надо будет в методе paintEvent . Однако, если пользователь видит, что наш класс является наследником QLabel , а значит имеет все соответствующие методы — то он может попытаться добавить на него например анимацию. Чтобы отображение этой анимации работало корректно (наш класс вел себя как полноценный QLabel ) в методе paintEvent нам будет надо вызвать QLabel::paintEvent , однако при этом все наши старания по отображению картинки пойдут на смарку — как было описано выше, он посмотрит, что был выставлен pixmap и отрисует его (не так, как мы хотим). Вывод этого сложного абзаца в том, что наследовать класс QLabel нам не стоит.
Итак, нам нужен класс, который будет уметь отображать картинку и мастабироваться, ну а еще, возможно отображать всякие стандартный рамочки и т. п. Весь нужный нам функционал кроме картинок есть в QWidget , его и наследуем:
#include class ScaledPixmap : public QWidget < public: ScaledPixmap(QWidget *parent = 0); void setScaledPixmap(const QPixmap &pixmap); protected: void paintEvent(QPaintEvent *event); private: QPixmap m_pixmap; >;
В класс добавлена картинка, которую будем добавлять и метод для ее установки. Реализуем методы:
ScaledPixmap::ScaledPixmap(QWidget *parent): QWidget(parent) < >void ScaledPixmap::setScaledPixmap(const QPixmap &pixmap) < m_pixmap = pixmap; update(); >void ScaledPixmap::paintEvent(QPaintEvent *event) < QPainter painter(this); if (false == m_pixmap.isNull()) < QSize widgetSize = size(); QPixmap scaledPixmap = m_pixmap.scaled(widgetSize, Qt::KeepAspectRatio); QPoint center((widgetSize.width() - scaledPixmap.width())/2, (widgetSize.height() - scaledPixmap.height())/2); painter.drawPixmap(center, scaledPixmap); >QWidget::paintEvent(event); >
После установки картинки, вызываем функцию обновления (чтобы перерисовать виджет). В функции paintEvent проверяем что картинка не пуста, получаем размер виджета, создаем новую картинку, подогнанную под размер виджета без искажения пропорций ( KeepAspectRatio ), определяем координаты центра виджета и отрисываем по центру картинку. После всех этих действий запускаем отрисовку рамочек, обновление части виджета и т. п. ( QWidget::paintEvent )
Вернемся к QLabel . Ведь мы можем для него точно также добавить метод setScaledPixmap и хранить еще одну картинку внутри него, которую и отрисовывать в paintEvent … (я бы не писал про это, если бы не встретил такую реализацию). Да потому что наш класс ведет себя не так, как QLabel , что будет если пользователь вызовет сначала setScaledPixmap , а потом QLabel::setPixmap ? – либо нашу картинку вообще не будет видно (поверх нее будет другая), либо (если сначала вызвать QLabel::paintEvent , а потом нарисовать то, что нам надо) – нарисовано будет две разных картинки. Все это нарушает принцип подстановки Лисков:
поведение наследуемых классов должно быть ожидаемым для кода, использующего переменную базового типа.
И так, мы описали наш класс, который умеет отображать картинку и перерисовывает ее при изменении своего размера. Чтобы отобразить его на нашей форме — заменяем в QtDesigner объект типа QLabel на объект QWidget . Нажимаем на него правой кнопкой мыши, выбираем «преобразование виджетов». Добавляем туда информацию о нашем новом классе (наследует QWidget, называется ScaledPixmap, находится в файле scaledpixmap.h). Осталось только изменить обращение к нему в слоте загрузки картинки:
void MainWindow::load_file() < auto path = QFileDialog::getOpenFileName( this, "Open Dialog", "", "*.png *.jpg *.bmp *.JPG"); if (path.isEmpty()) return; QPixmap pixmap(path); ui->image->setScaledPixmap(pixmap); >
Запускаем и наслаждаемся результатом.
Взять исходники можно в репозитории.
Images

The Image component is used for adding images to the UI in several supported formats, including bitmap formats, such as PNG and JPEG, and vector graphics formats, such as SVG. To use any image files in your designs, you need to first add them to Assets:
- Select Assets >.
- Select the image file, and then select Open.
- Select the location where the image will be saved in the Add Resources dialog.
- Select OK.
Your image is now available in Assets.

When you drag-and-drop an image file from Assets to Navigator or the 2D view, Qt Design Studio automatically creates an instance of the Image component for you with the path to the image file set as the value of the Source field in Properties.
To load images from a URL using a supported URL scheme, specify the URL in the Source field.
You can use the Border Image component to display an image, such as a PNG file, as a border and a background. For more information about using border images to create buttons, see Creating Scalable Buttons and Borders.
If you need to display animated images, such as GIFs, use the Animated Image component.
Image Size

If the image Size is not specified, the size of the source image is used automatically.
By default, explicitly setting the width and height of the component causes the image to be scaled to that size. To change this behavior, set the value of the Fill mode field. Images can be stretched, tiled, or scaled uniformly to the specified size with or without cropping. The Pad option means that the image is not transformed.
Note: If the Clip check box is not selected, the component might paint outside its bounding rectangle even if the Fill mode is set to PreserveAspectCrop.
Select the Smooth check box to smoothly filter images when scaled or transformed. Smooth filtering gives better visual quality, but it may be slower on some hardware. If the image is displayed at its natural size, this property has no visual or performance effect.
Select the Mipmap check box to use mipmap filtering when scaling or transforming images. Mipmap filtering gives better visual quality when scaling down compared with smooth filtering, but it may come at a performance cost both when initializing the image and during rendering.
Select the Auto transform check box if the image should automatically apply image transformation metadata, such as EXIF orientation.
Source Size
The Source size property specifies the scaled width and height of the full-frame image. Unlike the value of the Size property, which scales the painting of the image, this property sets the maximum number of pixels stored for the loaded image so that large images do not use more memory than necessary. This ensures the image in memory is no larger than the set source size, regardless of its set size.
If the image’s actual size is larger than the source size, the image is scaled down. If only one dimension of the size is set to greater than 0, the other dimension is set in proportion to preserve the source image’s aspect ratio. The Fill mode is independent of this.
If both the source size width and height are set, the image is scaled down to fit within the specified size maintaining the image’s aspect ratio. However, if PreserveAspectCrop or PreserveAspectFit are used, the image is scaled to match the optimal size for cropping or fitting.
If the source is an intrinsically scalable image (such as SVG), source size determines the size of the loaded image regardless of intrinsic size. Avoid changing the source size property dynamically because rendering an SVG is slow compared with rendering other image formats.
If the source is a non-scalable image (such as JPEG), the loaded image will be no greater than the source size specifies. For some formats, the whole image will never actually be loaded into memory.
Note: Changing this property dynamically causes the image source to be reloaded, potentially even from the network, if it is not in the disk cache. Select the Cache check box to cache the image.
Image Alignment
You can align images horizontally and vertically in the Alignment H and Alignment V fields. By default, images are centered.
Select the Mirror check box to horizontally invert the image, effectively displaying a mirrored image.
Performance
By default, locally available images are loaded immediately, and the UI is blocked until loading is complete. If a large image is to be loaded, it may be preferable to load the image in a low priority thread, by selecting the Asynchronous check box. If the image is obtained from a network rather than a local resource, it is automatically loaded asynchronously.
Images are cached and shared internally, so if several images have the same Source, only one copy of the image will be loaded.
Note: Images are often the greatest user of memory in UIs. We recommended that you set the Source size of images that do not form a part of the UI. This is especially important for content that is loaded from external sources or provided by the user.
Border Image
The Border Image component extends the features of the Image component. It is used to create borders out of images by scaling or tiling parts of each image. A source image is broken into 9 regions that are scaled or tiled individually. The corner regions are not scaled at all, while the horizontal and vertical regions are scaled according to the values of the Tile mode H and Tile mode V field, or both.
The Stretch option scales the image to fit the available area. The Repeat option tiles the image until there is no more space. To ensure that the last image is not cropped, select the Round option that scales the images down when necessary.
Specify the regions of the image in the Border left, Border right, Border top, and Border bottom fields. The regions describe the distance from each edge of the source image to use as a border.

Note: You cannot change the Source size of a border image.
For examples of using border images, see the documentation of the BorderImage component.
Animated Image
The Animated Image component extends the features of the Image component, providing a way to play animations stored as images containing a series of frames, such as those stored in GIF files.
Set the speed of the animation in the Speed field. The speed is measured in percentage of the original animated image speed. The default speed is 1.0, which means the original speed.

To play the animation, select the Playing check box.
![]()
To pause the animation, select the (Paused) check box.
When the Cache check box is selected, every frame of the animation is cached. Deselect the check box if you are playing a long or large animation and you want to conserve memory.
If the image data comes from a sequential device (such as a socket), Animated Image can only loop if caching is enabled.
For more information, watch the following video:
Iso Icon
Note: The Iso Icon component is not available if you selected Qt 6 when creating the project.
The Iso Icon component specifies an icon from an ISO 7000 icon library as a Picture component. The icon to use for the type and its color can be specified.
To select an icon in the ISO Icon Browser in Qt Design Studio, select the ISO icon in the Navigator or 2D view, and then select Choose Icon in the context menu.
![]()
You can use the color picker in Properties to set the value of Icon color.
![]()
Summary of Images
The following table lists the components that you can use to add images. The Location column contains the tab name where you can find the component in Components. The MCU column indicates which components are supported on MCUs.
| Icon | Name | Location | MCU | Purpose |
|---|---|---|---|---|
| Animated Image | Default Components — Basic | An images that stores animations containing a series of frames, such as those stored in GIF files. | ||
| Border Image | Default Components — Basic | ![]() |
An image that is used as a border or background. | |
| Image | Default Components — Basic | ![]() |
An image in one of the supported formats, including bitmap formats such as PNG and JPEG and vector graphics formats such as SVG. | |
| Iso Icon | Qt Quick Studio Components | An icon from an ISO 7000 icon library specified as a Picture component. You can select the icon to use and its color. |
Note: This component is not supported on Qt 6.
Available under certain Qt licenses.
Find out more.
