Современные наукоемкие технологииrae.ru
Научный журнал

Современные наукоемкие технологии

ISSN 1812-7320«Перечень» ВАКИФ РИНЦ = 1,279

ПРОЕКТИРОВАНИЕ ГЛАВНОГО ОКНА ИНТЕРФЕЙСА ПРОГРАММНОЙ СРЕДЫ OPENFOAM НА БАЗЕ ТЕХНОЛОГИЙ PYQT4 И PYTHON 3.4

1Отдел фундаментальных проблем аэрокосмических технологий, Федеральное государственное бюджетное научное учреждение "Южно-Уральский научный центр"
2ОАО "ГРЦ Макеева"

Данная статья является продолжением опубликованной работы [1], посвященной особенностям разработки графического интерфейса для ПС OpenFOAM – открытой совместимой платформы для постановки экспериментов по численному моделированию задач механики сплошных сред, в частности задач, относящихся к области гидродинамики.

В настоящей статье подробно рассматриваются вопросы создания главного окна интерфейса: подготовка его структуры, особенности создания каждого компонента, принципы определения и вызова процедур-обработчиков при выполнении различных действий пользователем и при наступлении событий, связанных с главным окном.

Графический интерфейс любой программы, как правило, имеет главное окно, посредством которого происходит взаимодействие с пользователем. В данном случае главное окно позволяет вести работу с формой импорта файла расчетной сетки для проекта задачи OpenFOAM и с формами редактирования служебных файлов.

Целью работы является исследование возможностей технологий PyQt4 и Python 3.4 в качестве инструментария для разработки главного окна пользовательского интерфейса. Исследования основываются на изучении документации [2, 3] и учебной литературы [4, 5] по данным технологиям.

На рис. 1 отражена структура главного окна интерфейса в рамках текущей разработки. Набор вложенных директорий и конфигурационных файлов проекта задачи предполагается представить в виде дерева (левая прикрепляемая панель) с возможностью открытия формы редактирования файла. При этом формы для загрузки файла расчетной сетки и редактирования каждого конфигурационного файла должны отображаться в центральном компоненте (рабочая область). Верхняя прикрепляемая панель отвечает за вывод названия проекта задачи, а нижняя – выполняет функцию области уведомлений для информирования пользователя о событиях, связанных с работой ПС OpenFOAM. Для управления опциями главного окна используется панель инструментов.

chit1.tif

Рис. 1. Структура главного окна интерфейса ПС OpenFOAM: 1 – название проекта задачи, 2 – дерево проекта задачи, 3 – рабочая область, 4 – область уведомлений

chit2.tif

Рис. 2. Диаграмма структуры главного окна в стиле ООП: 1 – блок начальных инструкций главного класса, 2 – блок компонентов интерфейса

Описание программного кода вводной части документа

Инструкции вводной части документа отвечают за подключение стандартных библиотек и внешних пользовательских модулей, в частности вспомогательного класса «file_form» из файла «file_form», расположенного в директории «add_classes» и класса «mesh_form» из файла «mesh_form» директории «forms», соответствующего форме импорта расчетной сетки.

Листинг 1. Вводная часть документа.

from add_classes.file_form import file_form

from forms.mesh_form import mesh_form

Описание блока начальных инструкций главного класса

Программный код листинга 2 в соответствии с диаграммой структуры главного окна в стиле объектно-ориентированного программирования (рис. 2) определяет раздел главного класса, конструктора класса и вызов конструктора базового класса. При этом конструктору класса во второй строке могут быть переданы пользовательские переменные «prj_name», «new_dir», «solver», содержащие название проекта задачи, путь до проекта и название решателя OpenFOAM соответственно.

Листинг 2. Блок начальных инструкций главного класса.

class GUIWindow(QtGui.QMainWindow):

def __init__(self, prj_name, new_dir, solver,parent=None):QtGui.QMainWindow.__init__(self, parent)

Адрес проекта задачи формируется путем «сцепления» содержимого переменных «new_dir», «prj_name» и «solver» (листинг 3), переданных в главное окно из стартового окна [1]. Адрес директории проекта задачи также может быть указан в переменной «full_dir» в виде абсолютного пути, например «/home/Desktop/test», а название проекта задачи (переменная «prj_name») – в виде строки, например «test». Аналогично «вручную» может быть определен решатель «rhoCentralFoam».

Листинг 3. Переменные адреса директории, названия проекта задачи и решателя.

self.full_dir = new_dir+”/”+prj_name

self.solver = “rhoCentralFoam”

Описание блока компонентов интерфейса

Листинги 4–8 содержат инструкции создания компонентов интерфейса: панели инструментов программы, верхней (название проекта задачи), левой (область дерева проекта), нижней (область уведомлений) и центральной (рабочая область) прикрепляемых панелей.

Листинг 4. Блок инструкций панели инструментов и ее элементов управления.

self.GUI_tools = QtGui.QToolBar()

self.mesh_import = QtGui.QAction(self)

self.mesh_img = self.style().standardIcon(QtGui.QStyle.SP_DirOpenIcon)

self.mesh_import.setIcon(self.mesh_img)

self.mesh_import.setToolTip('Открыть форму импорта сетки')

self.mesh_import.triggered.connect(self.on_mesh_import)

self.GUI_tools.addAction(self.mesh_import)

self.addToolBar(QtCore.Qt.TopToolBarArea, self.GUI_tools)

Листинг 5. Блок инструкций верхней прикрепляемой панели с названием проекта задачи.

self.pnl = QtGui.QDockWidget()

self.pnl.setFeatures(self.pnl.NoDockWidgetFeatures)

self.project_name_lbl = QtGui.QLabel("Название проекта: " + self.prj_name)

self.project_name_lbl.setStyleSheet("border-style: none;")

self.pnl.setWidget(self.project_name_lbl)

self.addDockWidget(QtCore.Qt.TopDockWidgetArea, self.pnl)

Листинг 6. Блок инструкций левой прикрепляемой панели с деревом проекта задачи.

self.fsw = QtGui.QDockWidget()

self.fsw.setFeatures(self.fsw.NoDockWidgetFeatures)

self.fsw_lbl = QtGui.QLabel("Файловая структура проекта")

self.fsw_lbl.setStyleSheet("border-style: none;" "font-size: 8pt;")

self.fsw_lbl.setAlignment(QtCore.Qt.AlignCenter)

self.fsw_tab = QtGui.QGridLayout()

self.fsw_tab.addWidget(self.fsw_lbl, 0, 0)

self.fsw_fr = QtGui.QFrame()

self.fsw_fr.setFixedSize(400, 32)

self.fsw_fr.setStyleSheet("background-color: beige;" "border-width: 1px;" "border-style: solid;" "border-color: dimgray;" "border-radius: 4px;")

self.fsw_fr.setLayout(self.fsw_tab)

self.fsw.setTitleBarWidget(self.fsw_fr)

self.prj_struc = QtGui.QTreeView()

self.prj_struc.setFixedSize(400, 680)

self.prj_struc.mod = QtGui.QFileSystemModel()

self.prj_struc.mod.setRootPath(self.full_dir)

self.prj_struc.setModel(self.prj_tree.mod)

self.prj_struc.header().hide()

self.prj_struc.setColumnHidden(1, True)

self.prj_struc.setColumnHidden(2, True)

self.prj_struc.setColumnHidden(3, True)

self.prj_struc.setRootIndex(self.prj_struc.mod.index(self.full_dir))

self.prj_struc.mod.directoryLoaded.connect(self.fetchAndExpand)

self.prj_struc.setItemsExpandable(False)

self.prj_struc.clicked.connect(self.on_prj_struc_clicked)

self.fsw.setWidget(self.prj_struc)

self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.fsw)

Для отображения вложенности папок и файлов при открытии главного окна реализована процедура-обработчик «fetchAndExpand» (листинг 10). Она выполняется при наступлении события «directoryLoaded». За открытие форм редактирования конфигурационных файлов проекта задачи отвечает функция «on_prj_struc_clicked» (листинг 11).

Листинг 7. Блок инструкций нижней прикрепляемой панели (области уведомлений).

self.serv_mes = QtGui.QDockWidget("Служебные сообщения")

self.serv_mes.setFixedSize(1000, 170)

self.serv_mes.setFeatures(self.serv_mes.NoDockWidgetFeatures)

self.listWidget = QtGui.QListWidget()

self.serv_mes.setWidget(self.listWidget)

self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.serv_mes)

Следующий программный код (листинг 8) определяет прикрепляемую панель, используемую в качестве рабочей области (центрального компонента). В ней отображается форма импорта файла расчетной сетки, а также форма редактирования конфигурационного файла, выбранного пользователем, и фрейм с заголовком.

Листинг 8. Блок инструкций центральной прикрепляемой панели (рабочей области).

self.ffw = QtGui.QDockWidget()

self.ffw.setFeatures(self.ffw.NoDockWidgetFeatures)

self.ffw_lbl = QtGui.QLabel()

self.ffw_lbl.setAlignment(QtCore.Qt.AlignCenter)

self.ffw_tab = QtGui.QGridLayout()

self.ffw_tab.addWidget(self.ffw_lbl, 0, 0)

self.ffw_frame = QtGui.QFrame()

self.ffw_frame.setFixedSize(590, 43)

self.ffw_frame.setStyleSheet("border-width: 1px;" "border-style: solid;" "border-color: dimgray;" "border-radius: 4px;" "background-color: beige;")

self.ffw_frame.setLayout(self.ffw_tab)

self.setCentralWidget(self.ffw)

Описание программного кода функций главного окна

Первой используемой функцией главного окна является функция открытия в прикрепляемой панели центрального компонента формы импорта расчетной сетки после нажатия пользователем соответствующей кнопки панели инструментов (листинг 4). Программный код этой функции главного окна представлен в листинге 9.

Листинг 9. Функция открытия формы импорта расчетной сетки.

def on_mesh_import(self):

self.ffw.setTitleBarWidget(self.ffw_frame)

self.ffw_lbl.setText("Форма импорта сетки")

self.ffw_lbl.setStyleSheet("border-style:

none;" "font-size: 8pt;")

self.ffw.setWidget(mesh_form(self))

Функция «fetchAndExpand» (листинг 10) выполняется при загрузке модели данных проекта задачи в виджет-дерево и автоматически раскрывает содержимое папок: «0», «system», «constant», «polyMesh».

Листинг 10. Функция раскрытия содержимого проекта задачи.

def fetchAndExpand(self, full_dir):

index = self.prj_struc.mod.index(full_dir)

self.prj_struc.expand(index)

for i in range(self.prj_struc.mod.rowCount(index)):

child = index.child(i, 0)

if self.prj_struc.mod.isDir(child) and self.prj_

struc.mod.fileName(child) == "0" or

self.prj_struc.mod.fileName(child) == "system"

or self.prj_struc.mod.fileName(child)==

«constant» or

self.prj_struc.mod.fileName(child)==

"polyMesh":

self.prj_struc.mod.setRootPath(self.

prj_struc.mod.filePath(child))

Третья функция главного окна (листинг 11) описывает поведение приложения при выборе пользователем определенной «ветви» дерева проекта задачи, т.е. при выборе определенного файла проекта. При этом происходит открытие формы редактирования файла с заголовком, в котором отображается надпись с именем файла.

Листинг 11. Функция выбора пользователем «ветви» дерева проекта задачи.

def on_prj_struc_clicked(self, index):

indexItem = self.prj_struc.mod.index(index.

row(), 0, index.parent())

file_name = self.prj_struc.mod.fileName(indexItem)

file_form.inp_file_form_func(self, file_name)

file_name_title = file_form.out_file_name_func()

if file_name_title != None:

self.ffw.setTitleBarWidget(self.ffw_frame)

self.ffw_lbl.setText("Форма параметров

файла: « + "<font color='peru'>" + file_

name_title +"</font>")

self.ffw_label.setStyleSheet("border-style:

none;" "font-size: 8pt;")

else:

self.clear_label = QtGui.QLabel()

self.ffw.setTitleBarWidget(self.clear_label)

file_form = file_form.out_file_form_func()

self.ffw.setWidget(file_form)

В рассматриваемом примере главное окно программы взаимодействует со вспомогательным классом (листинг 12), который при выборе файла из виджета-дерева передает в главное окно название выбранного файла и ссылку на форму его редактирования. Благодаря использованию вспомогательного класса при расширении списка форм, с которыми работает главное окно, изменения вносятся во вспомогательный класс, а не в структуру программного кода главного окна.

Листинг 12. Вспомогательный класс приложения.

from forms.controlDict_form import controlDict_form

class file_form:

def inp_file_form_func(self, file_name):

global file_name_gl

global file_form

file_name_gl = file_name

if file_name_gl == "controlDict":

file_form = controlDict_form(self)

else:

file_name_gl = None

file_form = None

def out_file_name_func(): return file_name_gl

def out_file_form_func(): return file_form

Тестирование работы приложения

В ходе проведенной работы созданы два файла: «file_system.py», содержащий программный код главного окна, и «file_form.py», содержащий инструкции вспомогательного класса. Для запуска приведенного примера необходимо создать отдельную папку, в которую поместить запускаемый файл «file_system.py» и две директории: «add_classes» и «forms». Запускаемый файл должен содержать программный код листингов 1–11, а блоки кода – расположены в соответствии с диаграммой структуры главного окна в стиле ООП (рис. 2). Кроме того, в запускаемом файле необходимо наличие инструкций, отвечающих за создание объекта приложения и вызов главного класса. Файл «file_form.py» должен содержать код листинга 12. Результат запуска файла «file_system.py» с выбранной ветвью (файлом) «controlDict» представлен на рис. 3.

chit3.tif

Рис. 3. Результат запуска файла «file_system.py»

Заключение

В настоящей статье рассмотрена практическая реализация главного окна интерфейса в виде SDI-приложения для ПС OpenFOAM. Представлен пошаговый процесс создания версии главного окна графической оболочки с базовым набором опций. Материалы, изложенные в настоящей работе, могут быть применены пользователями ПС OpenFOAM для создания собственных интерфейсов, а также разработчиками интерфейсов для других консольных (и не только) программ. Данную статью можно использовать в качестве учебного пособия для изучения основ программирования на базе высокоуровневых языков.


Библиографическая ссылка

Читалов Д.И., Калашников С.Т. ПРОЕКТИРОВАНИЕ ГЛАВНОГО ОКНА ИНТЕРФЕЙСА ПРОГРАММНОЙ СРЕДЫ OPENFOAM НА БАЗЕ ТЕХНОЛОГИЙ PYQT4 И PYTHON 3.4 // Современные наукоемкие технологии. 2017. № 9. С. 71-76;
URL: https://top-technologies.ru/article/view?id=36803 (дата обращения: 16.09.2026).
DOI: https://doi.org/10.17513/snt.36803