Евгений Легоцкой25 апреля 2017 г. 12:23

Qt/C++ - Урок 063. Добавление окон внутри главного окна приложения с помощью QMdiArea

Многие приложения, наподобие фотошопа умеют открывать проекты (изображения, тексты и т.д.) внутри окон, которые открываются внутри основного окна приложения. Qt предоставляет подобный фукционал в виде класса QMdiArea. В объект данного класса можно помещать объекты классов, наследованных от класса QWidget , и соответственно класса QWidget. Эти объекты будут отображать как окна, только будут расположены внутри QMdiArea.

Посмотрим пример с окном внутри окна.

Структура проекта

В составе проекта следующие файлы:

  • MdiWindow.pro - профайл проекта, создан по умолчанию;
  • main.cpp - стартовый файл программы с main функцией, создан по умолчанию;
  • mainwindow.h - заголовочный файл основного окна приложения;
  • mainwindow.cpp - файл исходных кодов основного окна приложения;
  • mainwindow.ui - форма основного окна приложения;
  • icons.qrc - файл ресурсов, содержит одну иконку.

Файлы MdiWindow.pro и main.cpp рассматривать не будем, поскольку они создаются по умолчанию. Файл icons.qrc содержит одну иконку, которая видна на тулбуре главного окна приложения. Данная кнопка отвечает за создание дополнительного окна приложения и добавляется через графический дизайнер. Данный Action нужен лишь для того, чтобы испускать сигнал на добавление новых окон в QMdiArea.

А теперь перейдём к сути проекта.

mainwindow.h

Заголовочный файл главного окна приложения. Содержит объявление указателя на объект QMdiArea , а также объявление слота для добавления новых окон, который был создан через графический дизайнер.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMdiArea>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_actionAddWindow_triggered();

private:
    Ui::MainWindow *ui;
    QMdiArea * mdiArea;  // Область, в которую будут добавляться окна
};

#endif // MAINWINDOW_H

mainwindow.cpp

Объект QMdiArea устанавливается в качестве центрального виджета главного окна приложения. Также настраиваем скроллбары, чтобы они появлялись только в случае необходимости. В слоте добавления окон добавляем объект QWidget с надписью. Здесь есть один момент. Если QWidget не будет содержать никакого контента, то он будет открываться с минимальными размерами, даже если вы выставите его размеры. И только когда вы попробуете передвинуть окно, этот виджет примет выставленный размер.

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QGridLayout>
#include <QLabel>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mdiArea = new QMdiArea(this);  // инициализируем QMdiArea
    // Настраиваем скроллбары
    mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    // Устанавливаем Mdi Area в качестве центрального виджета
    setCentralWidget(mdiArea);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionAddWindow_triggered()
{
    // Создаём виджет, который будет окном
    QWidget *widget = new QWidget(mdiArea);
    // Добавляем в него размещение
    QGridLayout *gridLayout = new QGridLayout(widget);
    widget->setLayout(gridLayout);
    // Добавляем на виджет надпись
    QLabel *label = new QLabel("Hello, I am sub window!!!", widget);
    gridLayout->addWidget(label);

    // Добавляем виджет в качестве подокна в Mdi Area
    mdiArea->addSubWindow(widget);
    // Устанавливаем заголовок окна
    widget->setWindowTitle("Sub Window");
    // и показываем виджет
    widget->show();
}

Скачать проект с примером QMdiArea

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Поддержать автора Donate

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Timeweb

Позвольте мне порекомендовать вам отличный хостинг, на котором расположен EVILEG.

В течение многих лет Timeweb доказывает свою стабильность.

Для проектов на Django рекомендую VDS хостинг

Посмотреть Хостинг
VD

C++ - Тест 001. Первая программа и типы данных

  • Результат:73баллов,
  • Очки рейтинга1
Ds

C++ - Тест 003. Условия и циклы

  • Результат:64баллов,
  • Очки рейтинга-1
o

C++ - Тест 001. Первая программа и типы данных

  • Результат:86баллов,
  • Очки рейтинга6
Последние комментарии
RK
РГ

QML - Урок 016. База данных SQLite и работа с ней в QML Qt

Добрый день! можно как то обойтись без метода updateModel()? После вызова этого метода происходит перерисовка страницы(если я правильно понимаю), и все элементы, например, CheckBox перерисовываю…
D:

QML - Урок 016. База данных SQLite и работа с ней в QML Qt

Добрый день, пытаюсь разобраться и подргнать пример под себя. Есть бд с огромным количеством полей. В приложении на виджетах при использовании QTableView все работает и путем простого sql запрос…

Django - Урок 039. Добавление личных сообщений и чатов на сайте - Часть 2 (Счётчик диалогов и чатов с непрочитанными сообщениями)

Добавляйте поле файла в модель сообщения. И в форме сообщения указывайте, что поле с файлом.
Сейчас обсуждают на форуме
ДК

Уйти от gtk

ошибка: Gtk-Message: 15:56:06.190: Failed to load module "atk-bridge" Привет. Начало истории здесь Кратко: на АЛЬТ линукс при запуске в консоли приложения по…
ДК

применяется некорректное разрешение для стилей под обычным пользователем

Привет. Такая проблема на ALT Linux: если запускать приложение от руута, то со стилями и размером шрифта всё в полном порядке. Если же мы запускаем приложение под обычным пользователем, то …

Наследование QWidget

Это утверждение ничего не значит. Наличие методов и т.д. не делает обязательным наследование в том виде, в котором вы его изначально попытались сделать. Тем более, если у вас будет два видж…
  • BlinCT
  • 7 августа 2020 г. 9:05

Динамическое заполнение StackLayout в qml

Всем привет. Пытаюсь решить такую задачку, есть TabBar и его кнопки. StackLayout{ currentIndex: tabBar.currentIndex A {id: tabA} B {id: tabB} C {id: tabC} D {id: ta…
М

QML: изменение стиля при наведении и при нажатии на кнопку

enabled = false перестанет быть активной и не будет ни на что реагировать) Хм.. по-моему пробовал такое. Проверю ещё раз после работы. Ура, спасибо большо…
О нас
Услуги
© EVILEG 2015-2020
Рекомендует хостинг TIMEWEB