Реклама

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

QMdiArea, QWidget, Qt

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

Реклама

Комментарии

Комментарии

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

Qt - Тест 001. Сигналы и слоты

  • Результат 5 баллов
  • Очки рейтинга -10

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

  • Результат 57 баллов
  • Очки рейтинга -2

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

  • Результат 7 баллов
  • Очки рейтинга -10
Последние комментарии
  • EVILEG
  • 7 декабря 2017 г. 9:47

Django - Урок 011. Добавление комментариев на сайт с Django

Визуальный пример чего? комментариев? При ответе на конкретный комментарий рядом с ником отвечающего будет стрелочка и указание ник другого пользователя. Который будет ссылкой на коммента...

  • Bernar
  • 7 декабря 2017 г. 9:24

Django - Урок 011. Добавление комментариев на сайт с Django

есть визуальный пример ?

  • EVILEG
  • 6 декабря 2017 г. 11:30

Django - Урок 011. Добавление комментариев на сайт с Django

Да, так будет даже лучше, я на сайте уже обновил до такого вида код Вот это уже не нужно if request.method == 'POST': Поскольку Вы и так используете метод post, то есть эта про...

  • Bernar
  • 6 декабря 2017 г. 11:19

Django - Урок 011. Добавление комментариев на сайт с Django

сделал немного по другому class EArticleView(View): template_name = 'knowledge/article.html' comment_form = CommentForm def get(self, request, *args, **kwargs): ...

Сейчас обсуждают на форуме
  • Миша
  • 15 декабря 2017 г. 11:26

Как найти в QVector макс и мин

Спасибо

  • Galant
  • 14 декабря 2017 г. 19:58

LPT

Понял! Спасибо!

  • EVILEG
  • 14 декабря 2017 г. 13:38

QCustomPlot можно ли построить прерывистую линию на одном графике?

Во-первых: В pro файле проект по идее достаточно указать следующий define для включения возможности рендеринга через OpenGL DEFINES += QCUSTOMPLOT_USE_OPENGL И во вторых:...

  • EVILEG
  • 13 декабря 2017 г. 8:05

В многопоточности выполнять действие только в одном из потоков

Статическиe методs QThread::currentThread(); и QThread::currentThreadId() могут возвращать указатель на поток и его handle id соответственно. Можете попробовать через как...

  • EVILEG
  • 13 декабря 2017 г. 7:57

А что по поводу авторизации ?

Наличие токена - это правильный подход. Например, у меня на сайте в каждой форме есть токен, чтобы не было возможности подделки запросов. Что касается SSL, то стоит поискать информацию н...