KNZSOFT Разработка ПО, консультации, учебные материалы
Князев Алексей Александрович. Независимый программист и консультант.
Qt для начинающих. Урок 3. Использование QMainWindow. Комбинации разных менеджеров компоновки
Вернуться к общему содержанию «Qt для начинающих».
Проект с главным окном на основе базового класса QMainWindow
В уроке 1, в разделе «Пример создания шаблона GUI-приложения из QtCreator», мы создали заготовку для GUI-приложения главное окно которого было основано на базовом классе QWidget. Здесь мы будем рассматривать аналогичную заготовку, в которой класс главного окна будет наследоваться не от QWidget, а от QMainWindow. Для этого, необходимо, на четвертой странице мастера создания нового проекта выбрать в качестве базового класса главного окна класс QMainWindow.
Класс QMainWindow отличается от QWidget тем, что уже содержит в себе обобщенные средства для создания на их основе главных окон приложения. Так, если QWidget только содержит в себе средства для установки какого-нибудь менеджера компоновки, то QMainWindow уже имеет в себе менеджер компоновки, в который можно добавить объекты классов QToolBars (панели инструментов), QDockWidgets (стыкуемые окна), QMenuBar (строка меню) и QStatusBar (строка статуса). Кроме этого, компоновка включает центральную область, которая может быть занята каким-либо виджетом. При создании приложений с однодокументным интерфейсом (SDI), центральную область занимает обычный виджет в котором делается разметка в согласии с целями приложения. Для приложения многодокументного интерфейса (MDI) центральный виджет занимает какой-нибудь объект управления дочерними окнами, например, объект класса QMdiArea. Ниже приведен рисунок из справочного руководства по Qt, на котором показана разметка, реализованая в классе QMainWindow.
Текущая цель урока заключается в адаптации нашей начальной практики разработки главного окна приложения под использование класса QMainWindow. Прежде мы уже использовали создание интерьера формы в специальном методе createFormEnvironment(). Это правильная практика разделения функционала, которая будет поддерживаться в традициях данного руководства. В начале этого раздела была сделана заготовка приложения с главным окном на основе класса QMainWindow. Представим снимки измененных файлов главного окна приложения, которые содержат заготовку для метода createFormEnvironment().
Файл mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include class MainWindow : public QMainWindow < Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private: void createFormInterior(); >; #endif // MAINWINDOW_H
Файл mainwindow.cpp
#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) < setWindowTitle(tr("Something Title")); createFormInterior(); >MainWindow::~MainWindow() < >void MainWindow::createFormInterior() < QWidget * wgt = new QWidget(this); setCentralWidget(wgt); // Далее здесь следует создать менеджер компоновки // для центрального виджета wgt, внутри которого // реализовать требуемый интерьер формы. >
В файле mainwindow.h мы лишь объявили в приватной области видимости метод создания интерьера. Этого требуют формальные правила ООП в C++. Интереснее изменения в файле mainwindow.cpp. Рассмотрим, чем отличается реализация метода создания интерьера для окон на основе классов QWidget и QMainWindow.
Выше уже говорилось, что внутри графической области класса QMainWindow реализована некоторая разметка, в которой определена центральная область для установки пользовательских виджетов. Наша заготовка для createFormInterior() как раз заполняет эту область специально созданным для этого виджетом. При создании центрального виджета, его владельцем объявлен класс главного окна, следовательно наш центральный виджет будет уничтожен автоматически при уничтожении главного окна приложения. Для установки созданного виджета в центр разметки объекта класса QMainWindow используется специальный метод setCentralWidget(). Дальнейшее создание интерьера должно строиться на этом центральном виджете. При использовании менеджеров компоновки следует создать центральный менеджер компоновки, связать его с центральным виджетом и уложить в его ячейки требуемые элементы интерьера, возможно, через использование вложенных компоновщиков.
Использование менеджеров компоновки QVBoxLayout и QHBoxLayout
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.
Чем отличается QMainWindow и QWidget?
Начал знакомство с PyQt5 и столкнулся c непониманием в чем отличия между виджетами QMainWindow и QWidget ?
И такой вопрос, у меня есть класс, который отображает QWidget , а можно ли создать класс с QMainWindow и туда поместить разные созданные виджеты?
Отслеживать
73.3k 109 109 золотых знаков 38 38 серебряных знаков 55 55 бронзовых знаков
задан 20 апр 2020 в 15:07
575 2 2 серебряных знака 13 13 бронзовых знаков
Можно, Qt Main Window Framework doc.qt.io/qt-5/qmainwindow.html#qt-main-window-framework
20 апр 2020 в 15:11
а собственно чем отличаются эти классы?
20 апр 2020 в 15:22
QMainWindow наследует QWidget и добавляет необходимый минимум элементов, свойственных главному окну: статусбар, главное меню, центральный виджет и что-то там еще
20 апр 2020 в 15:39
спасибо, помогли.
20 апр 2020 в 16:19
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Главное окно QMainWindow В более крупных, более сложных и более функциональных приложениях мы обычно наследуем класс QMainWindow для разработки. Это главное окно предоставляет очень хорошую основу для построения пользовательского интерфейса приложения.
Класс главного окна QMainWindow предоставляет нам
- строку меню, Menu Bar
- панель инструментов, Toolbars
- виджеты Dock и
- строку состояния, Status Bar и мы можем добавить их столько, сколько захотим. Кроме того, это позволяет нам быстро разработать функционально сложное и удобное приложение.
Блокнот / Notepad Простое приложение блокнота, чтобы понять, как использовать QMainWindow
import sys from PyQt5.QtGui import QIcon from PyQt5.QtCore import QMimeData from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QAction, QFileDialog, QMessageBox,\ QFontDialog, QColorDialog class Demo(QMainWindow): # В начале класса мы устанавливаем несколько переменных класса, которые используются # для определения того, был ли сохранен текст, сохраняется ли это в первый раз, # и для сохранения пути к файлу: is_saved = True is_saved_first = True path = '' def __init__(self): super(Demo, self).__init__() # Затем мы начинаем добавлять строку меню, панель инструментов и строку состояния: self.file_menu = self.menuBar().addMenu('File') self.edit_menu = self.menuBar().addMenu('Edit') self.help_menu = self.menuBar().addMenu('Help') self.file_toolbar = self.addToolBar('File') self.edit_toolbar = self.addToolBar('Edit') self.status_bar = self.statusBar() # Далее нам нужно только добавить различные действия к строке меню и панели инструментов, # то есть QAction. Этот класс обычно используется с панелью меню и панелью инструментов. # Вы можете думать о действии как о команде. Всякий раз, когда пользователь нажимает # на действие, запускается определенная команда, и программа выполняет соответствующую команду. # Теперь нам нужно создать несколько действий: self.new_action = QAction('New', self) self.open_action = QAction('Open', self) self.save_action = QAction('Save', self) self.save_as_action = QAction('Save As', self) self.close_action = QAction('Close', self) self.cut_action = QAction('Cut', self) self.copy_action = QAction('Copy', self) self.paste_action = QAction('Paste', self) self.font_action = QAction('Font', self) self.color_action = QAction('Color', self) self.about_action = QAction('Qt', self) # Поскольку это Notepad, должен быть текстовый редактор, поэтому, конечно, # в функции инициализации класса должен быть создан экземпляр элемента управления QTextEdit: self.text_edit = QTextEdit(self) # С помощью функции вырезания и вставки мы естественно думаем # о буфере обмена и классе QMimeData: self.mime_data = QMimeData() # QMimeData self.clipboard = QApplication.clipboard() # буфере обмена # Вызвать метод setCentralWidget() класса QMainWindow, чтобы установить # центральный элемент управления главного окна, # в котором мы устанавливаем поле редактирования текста text_edit для центрального # элемента управления. self.setCentralWidget(self.text_edit) # Вызовите метод resize(), чтобы установить для окна соответствующий размер; self.resize(450, 600) self.menu_init() # После того, как строка меню установлена, мы можем установить панель инструментов: self.toolbar_init() # Настройка строки состояния очень проста. self.status_bar_init() self.action_init() # установить действия self.text_edit_int() def menu_init(self): """ добавляем соответствующее действие в строку меню: """ # Видно, что мы можем добавлять к нему действия, вызывая метод addAction(). # Метод addSeparator(), как следует из названия, добавляет разделитель, что означает, # что close_action отделено от четырех вышеуказанных действий, что выглядит более организованным. self.file_menu.addAction(self.new_action) self.file_menu.addAction(self.open_action) self.file_menu.addAction(self.save_action) self.file_menu.addAction(self.save_as_action) self.file_menu.addSeparator() self.file_menu.addAction(self.close_action) self.edit_menu.addAction(self.cut_action) self.edit_menu.addAction(self.copy_action) self.edit_menu.addAction(self.paste_action) self.edit_menu.addSeparator() self.edit_menu.addAction(self.font_action) self.edit_menu.addAction(self.color_action) self.help_menu.addAction(self.about_action) def toolbar_init(self): self.file_toolbar.addAction(self.new_action) self.file_toolbar.addAction(self.open_action) self.file_toolbar.addAction(self.save_action) self.file_toolbar.addAction(self.save_as_action) self.edit_toolbar.addAction(self.cut_action) self.edit_toolbar.addAction(self.copy_action) self.edit_toolbar.addAction(self.paste_action) self.edit_toolbar.addAction(self.font_action) self.edit_toolbar.addAction(self.color_action) def status_bar_init(self): # Нам просто нужно вызвать метод showMessage() и передать состояние, # которое программа хочет отобразить при открытии программы. self.status_bar.showMessage('Ready to compose') def action_init(self): # Передайте параметр QIcon через метод setIcon(), чтобы установить значок действия. # Метод setShortCut() используется для установки сочетания клавиш. # Здесь мы устанавливаем сочетание клавиш нового действия на Ctrl + N. # Тогда нажатие Ctrl+N эквивалентно нажатию этого действия (независимо от платформы, # здесь используется Ctrl равномерно. (Даже на Mac, но после запуска программы пользователи # Mac должны нажать Ctrl + N). # Метод setToolTip() можно использовать для установки небольшого всплывающего приглашения. # Когда указатель мыши находится над действием, будет отображаться соответствующее # приглашение (конечно, мы также можем использовать этот метод для других объектов, # таких как QPushButton). # Метод setStatusTip() предназначен для установки информации в строке состояния. # Когда курсор мыши находится над действием, строка состояния отображает # соответствующую информацию. # Наконец, мы связываем сработавший сигнал new_action с пользовательской функцией слота: self.new_action.setIcon(QIcon('images/new.ico')) self.new_action.setShortcut('Ctrl+N') self.new_action.setToolTip('Create a new file') self.new_action.setStatusTip('Create a new file') self.new_action.triggered.connect(self.new_func) self.open_action.setIcon(QIcon('images/open.png')) self.open_action.setShortcut('Ctrl+O') self.open_action.setToolTip('Open an existing file') self.open_action.setStatusTip('Open an existing file') self.open_action.triggered.connect(self.open_file_func) self.save_action.setIcon(QIcon('images/save.png')) self.save_action.setShortcut('Ctrl+S') self.save_action.setToolTip('Save the file') self.save_action.setStatusTip('Save the file') self.save_action.triggered.connect(lambda: self.save_func(self.text_edit.toHtml())) self.save_as_action.setIcon(QIcon('img/save_as.png')) self.save_as_action.setShortcut('Ctrl+A') self.save_as_action.setToolTip('Save the file to a specified location') self.save_as_action.setStatusTip('Save the file to a specified location') self.save_as_action.triggered.connect(lambda: self.save_as_func(self.text_edit.toHtml())) self.close_action.setIcon(QIcon('img/exit.png')) # close.ico self.close_action.setShortcut('Ctrl+E') self.close_action.setToolTip('Close the window') self.close_action.setStatusTip('Close the window') self.close_action.triggered.connect(self.close_func) self.cut_action.setIcon(QIcon('img/cut.png')) self.cut_action.setShortcut('Ctrl+X') self.cut_action.setToolTip('Cut the text to clipboard') self.cut_action.setStatusTip('Cut the text') self.cut_action.triggered.connect(self.cut_func) self.copy_action.setIcon(QIcon('img/copy.png')) self.copy_action.setShortcut('Ctrl+C') self.copy_action.setToolTip('Copy the text') self.copy_action.setStatusTip('Copy the text') self.copy_action.triggered.connect(self.copy_func) self.paste_action.setIcon(QIcon('img/paste.png')) self.paste_action.setShortcut('Ctrl+V') self.paste_action.setToolTip('Paste the text') self.paste_action.setStatusTip('Paste the text') self.paste_action.triggered.connect(self.paste_func) self.font_action.setIcon(QIcon('img/font.png')) self.font_action.setShortcut('Ctrl+T') self.font_action.setToolTip('Change the font') self.font_action.setStatusTip('Change the font') self.font_action.triggered.connect(self.font_func) self.color_action.setIcon(QIcon('img/color.png')) self.color_action.setShortcut('Ctrl+R') self.color_action.setToolTip('Change the color') self.color_action.setStatusTip('Change the color') self.color_action.triggered.connect(self.color_func) self.about_action.setIcon(QIcon('img/about.png')) self.about_action.setShortcut('Ctrl+Q') self.about_action.setToolTip('What is Qt?') self.about_action.setStatusTip('What is Qt?') self.about_action.triggered.connect(self.about_func) # В конце у нас остается только поле ввода текста QTextEdit, оставленное неустановленным. # Подключите сигнал textChanged к функции слота. # В функции slot(text_changed_func) мы можем установить переменную self.is_saved: def text_edit_int(self): self.text_edit.textChanged.connect(self.text_changed_func) def text_changed_func(self): if self.text_edit.toPlainText(): self.is_saved = False else: self.is_saved = True # Перед созданием нового файла нам нужно определить, сохранен ли текущий текст. # Если нет, появится всплывающее окно с вопросом, хотите ли вы сохранить его. # Если вы нажмете Да, вы вызовете функцию save_func() для его сохранения. # Если вы нажмете Нет, чтобы сохранить, он будет очищен. # Если вы нажмете `Отмена` для отмены, никакие действия не будут предприняты, # если они были сохранены, вы можете просто очистить поле для редактирования текста; def new_func(self): if not self.is_saved: choice = QMessageBox.question(self, '', 'Do you want to save the text?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if choice == QMessageBox.Yes: self.save_func() self.text_edit.clear() elif choice == QMessageBox.No: self.text_edit.clear() else: pass else: self.text_edit.clear() # Метод установки действия open_action похож, мы в основном рассмотрим функцию подключенного слота: # Логика очень похожа на новое действие, за исключением того, что операция очистки поля # редактирования текста заменяется операцией открытия диалогового окна файла; def open_file_func(self): if not self.is_saved: choice = QMessageBox.question(self, '', 'Do you want to save the text?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if choice == QMessageBox.Yes: self.save_func() file, _ = QFileDialog.getOpenFileName(self, 'Open File', './', 'Files (*.html *.txt *.log)') if file: with open(file, 'r') as f: self.text_edit.clear() self.text_edit.setText(f.read()) self.is_saved = True elif choice == QMessageBox.No: file, _ = QFileDialog.getOpenFileName(self, 'Open File', './', 'Files (*.html *.txt *.log)') if file: with open(file, 'r') as f: self.text_edit.clear() self.text_edit.setText(f.read()) self.is_saved = True else: pass else: file, _ = QFileDialog.getOpenFileName(self, 'Open File', './', 'Files (*.html *.txt *.log)') if file: with open(file, 'r') as f: self.text_edit.clear() self.text_edit.setText(f.read()) self.is_saved = True # Функции слотов def save_func(self, text): if self.is_saved_first: self.save_as_func(text) else: with open(self.path, 'w') as f: f.write(text) self.is_saved = True def save_as_func(self, text): self.path, _ = QFileDialog.getSaveFileName(self, 'Save File', './', 'Files (*.html *.txt *.log)') if self.path: with open(self.path, 'w') as f: f.write(text) self.is_saved = True self.is_saved_first = False # Функция close_func() ниже аналогична методу реализации события закрытия окна. # Обратите внимание, что поскольку в нашем блокноте используется цвет, мы не можем вызвать # метод toPlainText() класса QTextEdit, поскольку этот метод получает чистый текст, # цвет будет потерян. Метод toHtml() должен быть вызван для сохранения цвета; def close_func(self): if not self.is_saved: choice = QMessageBox.question(self, 'Save File', 'Do you want to save the text?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if choice == QMessageBox.Yes: self.save_func(self.text_edit.toHtml()) self.close() elif choice == QMessageBox.No: self.close() else: pass def closeEvent(self, QCloseEvent): if not self.is_saved: choice = QMessageBox.question(self, 'Save File', 'Do you want to save the text?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if choice == QMessageBox.Yes: self.save_func(self.text_edit.toHtml()) QCloseEvent.accept() elif choice == QMessageBox.No: QCloseEvent.accept() else: QCloseEvent.ignore() # Функция слота, связанная с помощью cut_action, выглядит следующим образом: # Метод self.text_edit.textCursor() может получить текущий указатель # текстового поля редактирования (тип QTextCursor), а затем вызвать метод selection(), # чтобы получить содержимое, в настоящий момент выбранное указателем, но типом в данный # момент является QTextDocumentFragment, мы Вам нужно вызвать метод toHtml(), # чтобы получить текстовое содержимое. # Когда пользователь режет, обрезанный текст должен исчезнуть, # поэтому вызовите метод removeSelectedText() QTextCursor. def cut_func(self): self.mime_data.setHtml(self.text_edit.textCursor().selection().toHtml()) self.clipboard.setMimeData(self.mime_data) self.text_edit.textCursor().removeSelectedText() # Функция слота copy_action выглядит следующим образом, метод тот же, за исключением того, # что текст не нужно удалять в это время: def copy_func(self): self.mime_data.setHtml(self.text_edit.textCursor().selection().toHtml()) self.clipboard.setMimeData(self.mime_data) # В слоте функции paste_action нам просто нужно вызвать метод insetHtml() # для вставки текста в буфер обмена (этот метод вставит текст в позицию указателя): def paste_func(self): self.text_edit.insertHtml(self.clipboard.mimeData().html()) def font_func(self): font, ok = QFontDialog.getFont() if ok: self.text_edit.setFont(font) def color_func(self): color = QColorDialog.getColor() if color.isValid(): self.text_edit.setTextColor(color) # Слот-функция, связанная с about_action, является самой простой, # просто откройте окно сообщения о Qt: def about_func(self): QMessageBox.aboutQt(self, 'About Qt') if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
Управление макетом в PyQt5
Значимая сторона в программировании графических приложений – управление макетом, то есть расположение виджетов в окне приложения. Управление макетом можно осуществлять двумя основными способами: с помощью абсолютного позиционирования или специальных классов.
Абсолютное позиционирование
Программист указывает позицию и размер каждого виджета в пикселях. При использовании абсолютного позиционирования, у нас есть следующие ограничения:
- Размеры и позиция виджета не меняются, если мы меняем размер окна
- Приложения могут выглядеть по-разному на разных платформах
- Изменение шрифтов в нашем приложении может испортить макет
- Если мы решаем изменить наш макет, мы должны полностью переделать его, что утомительно и занимает много времени
Следующий пример размещает виджеты с помощью абсолютного позиционирования.
Мы используем метод move(), чтобы разместить наши виджеты. В нашем случае ими являются метки. Мы размещаем их путём предоставления координат x и y. Начало координатной системы – левый верхний угол экрана. Значения x возрастают слева направо. Значения y – сверху вниз.
Виджет метки располагается в x=15 и y=10.
Блочный макет
Управление макетом классами макета является более гибким и практичным. Это предпочтительный путь размещения виджетов в окне. QHBoxLayout и QVBoxLayout – это основные классы макета, которые выстраивают виджеты горизонтально или вертикально.
Представьте, что мы хотим разместить две кнопки в правом нижнем углу. Чтобы создать такой макет, мы будем использовать один горизонтальный и один вертикальный блок. Чтобы создать необходимое свободное пространство, мы добавим показатель растяжения.
В этом примере мы размещаем две кнопки в нижнем правом углу окна. Они остаются там, когда мы изменяем размер окна приложения. Мы можем использовать и QHBoxLayout, и QVBoxLayout.
Здесь мы создаём две кнопки.
Мы создаём макет горизонтального блока, добавляем показатель растяжения и обе кнопки. Растяжение добавляет растянутое свободное пространство перед двумя кнопками. Это прижмёт их к правому краю окна.
Чтобы создать необходимый макет, мы поставим горизонтальный макет в вертикальный. Показатель растяжения в вертикальном блоке прижмёт горизонтальный блок с кнопками к нижней части окна.
Наконец, мы устанавливаем главный макет окна.
QGridLayout (сеточный макет)
Самый универсальный класс макета – это сеточный макет. Этот макет делит пространство на строки и столбцы. Чтобы создать сеточный макет, мы используем класс QGridLayout.
В нашем примере, мы создаём сетку из кнопок. Чтобы заполнить один промежуток, мы добавляем один виджет QLabel.
Создаётся экземпляр QGridLayout, он назначается как макет окна приложения.
Это метки, используемые в дальнейшем для кнопок.
Мы создаём список позиций для сетки.
С помощью метода addWidget, создаются и добавляются кнопки к макету.
Обзорный пример
Виджеты могут занимать несколько столбцов и строк в сетке. В следующем примере мы продемонстрируем это.
Мы создаём окно, в котором у нас есть три метки, две строки редактирования и один виджет редактирования текста. Макет сделан с помощью QGridLayout.
Мы создаём сеточный макет и устанавливаем промежуток между виджетами.
Если мы добавляем виджет к сетке, мы можем обеспечить объединение строк и столбцов виджета. В нашем примере, мы делаем так, что виджет reviewEdit объединяет 5 строк.
Эта часть руководства по PyQt5 была посвящена управлению макетом.
Для вставки кода на Python в комментарий заключайте его в теги
- Модуль csv - чтение и запись CSV файлов
- Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
- Онлайн-обучение Python: сравнение популярных программ
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
- Сделай свой вклад в развитие сайта!
- Самоучитель Python
- Карта сайта
- Отзывы на книги по Python
- Реклама на сайте
Что лучше для конкретного случая QWidget или QMainWindow?
Посоветуйте, что лучше выбрать для создания программы с одним главным окном и парой дилоговых окон?
QMainWindow или QWidget ?
И в чем разница ?
Заранее спасибо.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
QWidget или QMainWindow
Здравствуйте, Когда создаю класс-наследник от QWidget - все виджеты отображаются корректно.
Полиморфизм классический и для конкретного случая
Если правильно понимаю, то классический полиморфизм это следующее: public class Shape
QMainWindow + QWidget + QPushButton
Доброго времени суток всем. Для главного окна программы, решил унаследоваться от QMainWindow, для.
разница между QWidget & QMainWindow
в чем собственно разница что выбирать при создании нового проекта? QWidget или QMainWindow?
Регистрация: 21.05.2013
Сообщений: 70
QWidget это общий класс виджета.
QMainWindow- класс основного окна, то бишь тебе в нем можно будет создать менюшку сверху, как в стандартных программах, панель инструментов с иконками быстрого вызова, статусную панель (вниу окна отображает какую-либо информацию), ну и любый виджеты подцепить. Это вкратце.
Ну и если нужы приколюхи, которые я описал,то делай QMainWindow.
27697 / 17314 / 3811
Регистрация: 24.12.2010
Сообщений: 38,979
m0system, Есть еще вариант с QDialog.
596 / 396 / 79
Регистрация: 23.10.2013
Сообщений: 1,143
Да можно вообще любой виджет главным сделать. Все зависит от того, что конкретно нужно.
59 / 46 / 11
Регистрация: 16.09.2014
Сообщений: 124
Посоветуйте, что лучше выбрать для создания программы с одним главным окном и парой дилоговых окон?
Если еще раз внимательно прочитать вопрос, то можно прямо в нем увидеть ответ.
QMainWindow - главное окно.
QDialog - диалоговые окна.
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
Сообщение от Pancir
QMainWindow - главное окно.
QDialog - диалоговые окна.
Нет. Четкого разделения окон нет. Разница лишь в разном отображении на разных ОС.
Ни кто не машет использовать только QWidget для всех окон.