Создание приложения
В данном разделе рассмотрим создание простейшего приложения, которое можно запускать из оболочки python.
При этом пользовательский интерфейс будет строится исходя из предпочтений пользователя.
В рамках примера создадим приложение, которое будет открывать файл и показывать его в окне карты. Также вставим
стандартное окно управления слоями карты axipy.LayerControlWidget
.
Примечание
Для использования библиотеки axipy без интерфейса Аксиомы требуется платная лицензия.
Первым шагом проинициализируем ядро (подробнее см. Initialization, Finalization, and Threads) и определим главное окно нашего будущего приложения. Код будет выглядеть следующим образом:
from PySide2.QtWidgets import QMainWindow
from axipy import init_axioma
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Пример окна приложения")
# Инициализация ядра
app = init_axioma()
# Создание и отображение главного окна
main_window = MainWindow()
main_window.resize(1200, 800)
main_window.show()
# Запуск основного цикла программы
app.exec_()
После того как мы создали пустое окно добавим панель инструментов со стандартными действиями (полный список действий
можно посмотреть axipy.ActionManager.items()
).
Код будет выглядеть следующим образом:
from PySide2.QtWidgets import QMainWindow
from axipy import init_axioma, ActionManager
class MainWindow(QMainWindow):
def __init__(self) -> None:
super().__init__()
self.setWindowTitle("Пример окна приложения")
self._add_buttons()
def _add_buttons(self) -> None:
def _add_action(name) -> None:
# Добавляем системное действие
act = ActionManager.get(name)
if act:
self.toolbar.addAction(act)
# Создаем панель инструментов
self.toolbar = self.addToolBar("Панель")
# Добавляем стандартные кнопки
_add_action("SaveTables")
_add_action("Select")
_add_action("Pan")
_add_action("ZoomIn")
_add_action("ZoomOut")
_add_action("PointDraw")
# Инициализация ядра
app = init_axioma()
# Создание и отображение главного окна
main_window = MainWindow()
main_window.resize(1200, 800)
main_window.show()
# Запуск основного цикла программы
app.exec_()
После запуска окно будет выглядеть примерно так:
Далее, нам необходимо добавить пользовательское действие и, как реакция на него, будет открытие и отображение файла в окне карты. Одновременно с этим создается окно управления слоями.
Результирующий код будет выглядеть следующим образом:
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QMainWindow, QFileDialog, QDockWidget, QAction
from axipy import (
init_axioma, provider_manager, Layer, view_manager, Map, LayerControlWidget, ActionManager
)
class MainWindow(QMainWindow):
def __init__(self) -> None:
super().__init__()
self.setWindowTitle("Пример окна приложения")
self._add_buttons()
# Открытие файла
def __open_file(self) -> None:
file_name, _ = QFileDialog.getOpenFileName(self, "Открыть", filter="MapInfo TAB (*.tab)")
if file_name:
table = provider_manager.openfile(file_name)
# создаем слой
layer = Layer.create(table)
# если карты нет, то создаем ее
if not view_manager.active:
map_ = Map([layer])
mapview = view_manager.create_mapview(map_)
self._create_layer_control_dock()
view_manager.activate(mapview)
self.setCentralWidget(mapview.widget)
# если есть, добавляем слой в окно карты
else:
view_manager.active.map.layers.append(layer)
# Добавление по левой стороне окно управления слоями карты
def _create_layer_control_dock(self) -> None:
self._layer_control_w = LayerControlWidget()
dock_layer_control = QDockWidget(self._layer_control_w.widget.windowTitle(), self)
dock_layer_control.setWidget(self._layer_control_w.widget)
self.addDockWidget(Qt.LeftDockWidgetArea, dock_layer_control)
# Добавление кнопок на панель инструментов
def _add_buttons(self) -> None:
# Создаем панель инструментов
self.toolbar = self.addToolBar("Панель")
# Пользовательское действие открытия файла
self.action_open = QAction(ActionManager.icon_by_name("open"), "Открыть файл")
self.action_open.triggered.connect(self.__open_file)
self.toolbar.addAction(self.action_open)
def _add_action(name) -> None:
# Добавляем системное действие
act = ActionManager.get(name)
if act:
self.toolbar.addAction(act)
_add_action("SaveTables")
_add_action("Select")
_add_action("Pan")
_add_action("ZoomIn")
_add_action("ZoomOut")
_add_action("PointDraw")
# Инициализация ядра
app = init_axioma()
# Создание и отображение главного окна
main_window = MainWindow()
main_window.resize(1200, 800)
main_window.show()
# Запуск основного цикла программы
app.exec_()
Результат работы:
Следующим этапом попробуем усложнить пример и сделать приложение, которое содержит помимо окна карты и окна с деревом слоев и другие. Перечислим их:
from PySide2.QtCore import Qt, Slot
from PySide2.QtWidgets import QMainWindow, QDockWidget, QStackedWidget
import os
from axipy import (Notifications, LayerControlWidget, DataManagerWidget, NotificationWidget, ViewManagerWidget,
PythonConsoleWidget, view_manager, init_axioma, provider_manager, Layer, Map, View, ActionManager)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Пример окна приложения")
self._stacked_widget = QStackedWidget()
view_manager.active_changed.connect(self.set_stacked_widget)
self.setCentralWidget(self._stacked_widget)
self.__initButtons()
def _add_action(self, id):
act = ActionManager[id]
if act:
self.toolbar.addAction(act)
self.menu.addAction(act)
def __initButtons(self):
self.toolbar = self.addToolBar('Панель')
self.menu = self.menuBar().addMenu('Меню')
self._add_action('Select')
self._add_action('SelectInRect')
self._add_action('Pan')
self._add_action('ZoomIn')
self._add_action('ZoomOut')
self.toolbar.addSeparator()
self._add_action('PointDraw')
self._add_action('RectangleDraw')
self._add_action('SymbolStyle')
ActionManager.activate("Pan")
def _create_maps_dock(self):
self._layer_control_w = LayerControlWidget()
self._layer_control_w.mapview_activated.connect(self.set_center_widget)
dock_layer_control = QDockWidget(self._layer_control_w.widget.windowTitle(), main_window)
dock_layer_control.setWidget(self._layer_control_w.widget)
self.addDockWidget(Qt.LeftDockWidgetArea, dock_layer_control)
def _create_data_manager_dock(self):
data_manager_w = DataManagerWidget()
dock_catalog = QDockWidget(data_manager_w.widget.windowTitle())
dock_catalog.setWidget(data_manager_w.widget)
def notify_selection():
"""
Отслеживание выборки в списке открытых данных.
"""
objects = data_manager_w.objects
if len(objects) > 0:
names = ', '.join(obj.name for obj in objects)
Notifications.push("Выбрано", names, Notifications.Warning)
data_manager_w.selection_changed.connect(notify_selection)
self.addDockWidget(Qt.LeftDockWidgetArea, dock_catalog)
def _create_notification_dock(self):
notification_w = NotificationWidget()
notification_w.widget.setFixedHeight(150)
dock_notification = QDockWidget(notification_w.widget.windowTitle())
dock_notification.setWidget(notification_w.widget)
self.addDockWidget(Qt.BottomDockWidgetArea, dock_notification)
def _create_python_dock(self):
notification_w = PythonConsoleWidget()
notification_w.widget.setFixedHeight(150)
dock_notification = QDockWidget(notification_w.widget.windowTitle())
dock_notification.setWidget(notification_w.widget)
self.addDockWidget(Qt.BottomDockWidgetArea, dock_notification)
def _create_view_manager_dock(self):
self._view_manager_w = ViewManagerWidget()
self._view_manager_w.view_changed.connect(self.set_center_widget)
dock_widget = QDockWidget(self._view_manager_w.widget.windowTitle(), main_window)
dock_widget.setWidget(self._view_manager_w.widget)
self.addDockWidget(Qt.LeftDockWidgetArea, dock_widget)
def init_gui(self):
# Окно управления слоями
self._create_maps_dock()
# Открытые источники
self._create_data_manager_dock()
# Окно уведомлений
self._create_notification_dock()
# Окно консоли python
self._create_python_dock()
# Список окон
self._create_view_manager_dock()
@Slot(View)
def set_center_widget(self, inp_view: View):
"""
Устанавливает активное окно.
"""
view_manager.activate(inp_view)
@Slot()
def set_stacked_widget(self):
w = view_manager.active.widget
i = self._stacked_widget.indexOf(w)
if i == -1:
self._stacked_widget.insertWidget(0, w)
else:
self._stacked_widget.setCurrentIndex(i)
# Инициализция ядра
app = init_axioma()
# Создаем главное окно приложения
main_window = MainWindow()
main_window.init_gui()
# Открываем таблицы
def path_to_file(file_name: str) -> str:
return os.path.join(os.path.dirname(__file__), "tab", file_name)
table_world = provider_manager.openfile(path_to_file("world.tab"))
table_world_cap = provider_manager.openfile(path_to_file("worldcap.tab"))
table_rf = provider_manager.openfile(path_to_file("SubjectRF.TAB"))
# Создаем слои
layer_world = Layer.create(table_world)
layer_world_cap = Layer.create(table_world_cap)
layer_rf = Layer.create(table_rf)
# Создаем окно карты
map_world_all = Map([layer_world_cap, layer_world])
mapview = view_manager.create_mapview(map_world_all)
# Еще одна карта
map_world = Map([layer_rf, layer_world])
view_manager.create_mapview(map_world)
# Таблицы просмотра
view_manager.create_tableview(table_world)
view_manager.create_tableview(table_rf)
# Отчет
#view_manager.create_reportview()
# Первое окно как основное
main_window.set_center_widget(mapview)
# Левый верхний угол окна
x, y = 200, 10
# Ширина и высота окна
width, height = 1200, 800
main_window.resize(width, height)
main_window.move(x, y)
# Показываем главное окно
main_window.show()
app.exec_()
Результат работы: