Многие приложения, наподобие фотошопа умеют открывать проекты (изображения, тексты и т.д.) внутри окон, которые открываются внутри основного окна приложения. 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(); }