reworked with tkinter, UI improements needed
This commit is contained in:
parent
d3878857af
commit
3ae07ca289
26 changed files with 1488 additions and 1751 deletions
|
|
@ -1,361 +1,469 @@
|
|||
"""
|
||||
EquipmentDialog - диалог управления оборудованием
|
||||
Камеры, объективы и телескопы
|
||||
EquipmentDialog - диалог управления оборудованием (tkinter)
|
||||
"""
|
||||
from PySide6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QListWidget,
|
||||
QPushButton, QInputDialog, QMessageBox, QWidget, QTabWidget,
|
||||
QFormLayout, QDoubleSpinBox, QSpinBox, QLineEdit
|
||||
)
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QFont
|
||||
|
||||
from services.config_service import ConfigService
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
from threading import Thread
|
||||
|
||||
|
||||
class EquipmentDialog(QDialog):
|
||||
class EquipmentDialog(tk.Toplevel):
|
||||
"""Диалог для управления оборудованием"""
|
||||
|
||||
def __init__(self, parent, config_service: ConfigService):
|
||||
def __init__(self, parent, config_service):
|
||||
super().__init__(parent)
|
||||
|
||||
self.parent = parent
|
||||
self.config_service = config_service
|
||||
self.setWindowTitle("Управление оборудованием")
|
||||
self.setMinimumSize(700, 500)
|
||||
self.resize(800, 550)
|
||||
|
||||
# Загружаем данные
|
||||
self.cameras = self.config_service.get_cameras()
|
||||
self.lenses = self.config_service.get_lenses()
|
||||
self.telescopes = self.config_service.get_telescopes()
|
||||
|
||||
self.selected_camera = None
|
||||
self.selected_lens = None
|
||||
self.selected_telescope = None
|
||||
|
||||
self.title("Manage Equipment")
|
||||
self.geometry("750x500")
|
||||
self.minsize(700, 450)
|
||||
self.transient(parent)
|
||||
self.grab_set()
|
||||
|
||||
self._create_ui()
|
||||
self._update_cameras_list()
|
||||
self._update_lenses_list()
|
||||
self._update_telescopes_list()
|
||||
self._center_window()
|
||||
|
||||
def _create_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSpacing(15)
|
||||
layout.setContentsMargins(20, 20, 20, 20)
|
||||
# Notebook for tabs
|
||||
notebook = ttk.Notebook(self)
|
||||
notebook.pack(fill='both', expand=True, padx=10, pady=10)
|
||||
|
||||
# Заголовок
|
||||
title_label = QLabel("Управление оборудованием")
|
||||
title_font = QFont()
|
||||
title_font.setPointSize(16)
|
||||
title_font.setBold(True)
|
||||
title_label.setFont(title_font)
|
||||
title_label.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(title_label)
|
||||
# Tab 1: Cameras
|
||||
cameras_frame = ttk.Frame(notebook)
|
||||
notebook.add(cameras_frame, text="Cameras")
|
||||
self._create_cameras_tab(cameras_frame)
|
||||
|
||||
# Используем QTabWidget для трёх вкладок
|
||||
tab_widget = QTabWidget()
|
||||
# Tab 2: Lenses
|
||||
lenses_frame = ttk.Frame(notebook)
|
||||
notebook.add(lenses_frame, text="Lenses")
|
||||
self._create_lenses_tab(lenses_frame)
|
||||
|
||||
# Вкладка: Камеры
|
||||
cameras_tab = self._create_cameras_tab()
|
||||
tab_widget.addTab(cameras_tab, "📷 Камеры")
|
||||
# Tab 3: Telescopes
|
||||
telescopes_frame = ttk.Frame(notebook)
|
||||
notebook.add(telescopes_frame, text="Telescopes")
|
||||
self._create_telescopes_tab(telescopes_frame)
|
||||
|
||||
# Вкладка: Объективы
|
||||
lenses_tab = self._create_lenses_tab()
|
||||
tab_widget.addTab(lenses_tab, "🔭 Объективы")
|
||||
# Close button
|
||||
btn_frame = ttk.Frame(self)
|
||||
btn_frame.pack(pady=10)
|
||||
ttk.Button(btn_frame, text="Close", command=self.destroy).pack()
|
||||
|
||||
# Вкладка: Телескопы
|
||||
telescopes_tab = self._create_telescopes_tab()
|
||||
tab_widget.addTab(telescopes_tab, "🪐 Телескопы")
|
||||
def _center_window(self):
|
||||
self.update_idletasks()
|
||||
x = self.parent.winfo_x() + (self.parent.winfo_width() // 2) - (self.winfo_width() // 2)
|
||||
y = self.parent.winfo_y() + (self.parent.winfo_height() // 2) - (self.winfo_height() // 2)
|
||||
self.geometry(f'+{x}+{y}')
|
||||
|
||||
layout.addWidget(tab_widget)
|
||||
def _create_cameras_tab(self, parent):
|
||||
# Listbox
|
||||
list_frame = ttk.Frame(parent)
|
||||
list_frame.pack(fill='both', expand=True, padx=10, pady=10)
|
||||
|
||||
# Кнопка закрытия
|
||||
close_btn = QPushButton("Закрыть")
|
||||
close_btn.clicked.connect(self.accept)
|
||||
close_layout = QHBoxLayout()
|
||||
close_layout.addStretch()
|
||||
close_layout.addWidget(close_btn)
|
||||
layout.addLayout(close_layout)
|
||||
scrollbar = ttk.Scrollbar(list_frame)
|
||||
scrollbar.pack(side='right', fill='y')
|
||||
|
||||
def _create_cameras_tab(self) -> QWidget:
|
||||
"""Создаёт вкладку с камерами"""
|
||||
tab = QWidget()
|
||||
layout = QVBoxLayout(tab)
|
||||
self.cameras_listbox = tk.Listbox(list_frame, yscrollcommand=scrollbar.set,
|
||||
bg='#2d2d2d', fg='#e0e0e0',
|
||||
selectbackground='#4CAF50', selectforeground='white',
|
||||
font=('Segoe UI', 10))
|
||||
self.cameras_listbox.pack(fill='both', expand=True)
|
||||
scrollbar.config(command=self.cameras_listbox.yview)
|
||||
|
||||
# Список камер
|
||||
self.cameras_list = QListWidget()
|
||||
self.cameras_list.itemClicked.connect(lambda item: self._select_camera(item.text()))
|
||||
layout.addWidget(self.cameras_list)
|
||||
|
||||
# Кнопки
|
||||
buttons_layout = QHBoxLayout()
|
||||
|
||||
add_btn = QPushButton("➕ Добавить камеру")
|
||||
add_btn.clicked.connect(self._add_camera)
|
||||
buttons_layout.addWidget(add_btn)
|
||||
|
||||
self.remove_camera_btn = QPushButton("❌ Удалить")
|
||||
self.remove_camera_btn.setEnabled(False)
|
||||
self.remove_camera_btn.clicked.connect(self._remove_camera)
|
||||
buttons_layout.addWidget(self.remove_camera_btn)
|
||||
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
return tab
|
||||
|
||||
def _create_lenses_tab(self) -> QWidget:
|
||||
"""Создаёт вкладку с объективами"""
|
||||
tab = QWidget()
|
||||
layout = QVBoxLayout(tab)
|
||||
|
||||
# Список объективов
|
||||
self.lenses_list = QListWidget()
|
||||
self.lenses_list.itemClicked.connect(lambda item: self._select_lens(item.text()))
|
||||
layout.addWidget(self.lenses_list)
|
||||
|
||||
# Кнопки
|
||||
buttons_layout = QHBoxLayout()
|
||||
|
||||
add_btn = QPushButton("➕ Добавить объектив")
|
||||
add_btn.clicked.connect(self._add_lens)
|
||||
buttons_layout.addWidget(add_btn)
|
||||
|
||||
self.remove_lens_btn = QPushButton("❌ Удалить")
|
||||
self.remove_lens_btn.setEnabled(False)
|
||||
self.remove_lens_btn.clicked.connect(self._remove_lens)
|
||||
buttons_layout.addWidget(self.remove_lens_btn)
|
||||
|
||||
edit_btn = QPushButton("✏ Редактировать")
|
||||
edit_btn.clicked.connect(self._edit_lens)
|
||||
buttons_layout.addWidget(edit_btn)
|
||||
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
return tab
|
||||
|
||||
def _create_telescopes_tab(self) -> QWidget:
|
||||
"""Создаёт вкладку с телескопами"""
|
||||
tab = QWidget()
|
||||
layout = QVBoxLayout(tab)
|
||||
|
||||
# Список телескопов
|
||||
self.telescopes_list = QListWidget()
|
||||
self.telescopes_list.itemClicked.connect(lambda item: self._select_telescope(item.text()))
|
||||
layout.addWidget(self.telescopes_list)
|
||||
|
||||
# Кнопки
|
||||
buttons_layout = QHBoxLayout()
|
||||
|
||||
add_btn = QPushButton("➕ Добавить телескоп")
|
||||
add_btn.clicked.connect(self._add_telescope)
|
||||
buttons_layout.addWidget(add_btn)
|
||||
|
||||
self.remove_telescope_btn = QPushButton("❌ Удалить")
|
||||
self.remove_telescope_btn.setEnabled(False)
|
||||
self.remove_telescope_btn.clicked.connect(self._remove_telescope)
|
||||
buttons_layout.addWidget(self.remove_telescope_btn)
|
||||
|
||||
edit_btn = QPushButton("✏ Редактировать")
|
||||
edit_btn.clicked.connect(self._edit_telescope)
|
||||
buttons_layout.addWidget(edit_btn)
|
||||
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
return tab
|
||||
|
||||
# ===== Методы для камер =====
|
||||
|
||||
def _update_cameras_list(self):
|
||||
self.cameras_list.clear()
|
||||
for camera in self.cameras:
|
||||
self.cameras_list.addItem(camera)
|
||||
self._selected_camera = None
|
||||
self.remove_camera_btn.setEnabled(False)
|
||||
self.cameras_listbox.insert('end', camera)
|
||||
|
||||
def _select_camera(self, camera: str):
|
||||
self._selected_camera = camera
|
||||
self.remove_camera_btn.setEnabled(True)
|
||||
self.lenses_list.clearSelection()
|
||||
self.telescopes_list.clearSelection()
|
||||
self._selected_lens = None
|
||||
self._selected_telescope = None
|
||||
self.remove_lens_btn.setEnabled(False)
|
||||
self.remove_telescope_btn.setEnabled(False)
|
||||
self.cameras_listbox.bind('<<ListboxSelect>>', self._on_camera_select)
|
||||
|
||||
# Buttons
|
||||
btn_frame = ttk.Frame(parent)
|
||||
btn_frame.pack(pady=10)
|
||||
|
||||
ttk.Button(btn_frame, text="Add Camera", command=self._add_camera).pack(side='left', padx=5)
|
||||
self.remove_camera_btn = ttk.Button(btn_frame, text="Remove", command=self._remove_camera, state='disabled')
|
||||
self.remove_camera_btn.pack(side='left', padx=5)
|
||||
self.edit_camera_btn = ttk.Button(btn_frame, text="Edit", command=self._edit_camera, state='disabled')
|
||||
self.edit_camera_btn.pack(side='left', padx=5)
|
||||
|
||||
def _on_camera_select(self, event):
|
||||
selection = self.cameras_listbox.curselection()
|
||||
if selection:
|
||||
self.selected_camera = self.cameras_listbox.get(selection[0])
|
||||
self.remove_camera_btn.config(state='normal')
|
||||
self.edit_camera_btn.config(state='normal')
|
||||
|
||||
def _add_camera(self):
|
||||
name, ok = QInputDialog.getText(self, "Добавить камеру", "Введите название камеры:")
|
||||
if ok and name and name.strip():
|
||||
new_name = name.strip()
|
||||
if new_name in self.cameras:
|
||||
QMessageBox.warning(self, "Ошибка", "Такая камера уже существует!")
|
||||
return
|
||||
self.cameras.append(new_name)
|
||||
self.config_service.add_camera(new_name)
|
||||
self._update_cameras_list()
|
||||
QMessageBox.information(self, "Успех", f"Камера '{new_name}' добавлена")
|
||||
dialog = tk.Toplevel(self)
|
||||
dialog.title("Add Camera")
|
||||
dialog.geometry("350x120")
|
||||
dialog.transient(self)
|
||||
dialog.grab_set()
|
||||
|
||||
ttk.Label(dialog, text="Camera name:", font=('Segoe UI', 10)).pack(pady=15)
|
||||
entry = ttk.Entry(dialog, width=40)
|
||||
entry.pack(pady=5)
|
||||
entry.focus()
|
||||
|
||||
def save():
|
||||
new_camera = entry.get().strip()
|
||||
if new_camera:
|
||||
if new_camera in self.cameras:
|
||||
messagebox.showerror("Error", "Camera already exists!", parent=dialog)
|
||||
return
|
||||
self.cameras.append(new_camera)
|
||||
self.config_service.add_camera(new_camera)
|
||||
self.cameras_listbox.insert('end', new_camera)
|
||||
dialog.destroy()
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Please enter camera name!", parent=dialog)
|
||||
|
||||
ttk.Button(dialog, text="OK", command=save).pack(pady=10)
|
||||
dialog.bind('<Return>', lambda e: save())
|
||||
|
||||
def _remove_camera(self):
|
||||
if hasattr(self, '_selected_camera') and self._selected_camera:
|
||||
reply = QMessageBox.question(self, "Подтверждение",
|
||||
f"Удалить камеру '{self._selected_camera}'?",
|
||||
QMessageBox.Yes | QMessageBox.No)
|
||||
if reply == QMessageBox.Yes:
|
||||
self.cameras.remove(self._selected_camera)
|
||||
self.config_service.remove_camera(self._selected_camera)
|
||||
self._update_cameras_list()
|
||||
if self.selected_camera:
|
||||
reply = messagebox.askyesno("Remove Camera", f"Remove '{self.selected_camera}'?", parent=self)
|
||||
if reply:
|
||||
self.cameras.remove(self.selected_camera)
|
||||
self.config_service.remove_camera(self.selected_camera)
|
||||
self.cameras_listbox.delete(0, 'end')
|
||||
for camera in self.cameras:
|
||||
self.cameras_listbox.insert('end', camera)
|
||||
self.selected_camera = None
|
||||
self.remove_camera_btn.config(state='disabled')
|
||||
self.edit_camera_btn.config(state='disabled')
|
||||
|
||||
# ===== Методы для объективов =====
|
||||
def _edit_camera(self):
|
||||
if self.selected_camera:
|
||||
dialog = tk.Toplevel(self)
|
||||
dialog.title("Edit Camera")
|
||||
dialog.geometry("350x120")
|
||||
dialog.transient(self)
|
||||
dialog.grab_set()
|
||||
|
||||
ttk.Label(dialog, text="New camera name:", font=('Segoe UI', 10)).pack(pady=15)
|
||||
entry = ttk.Entry(dialog, width=40)
|
||||
entry.insert(0, self.selected_camera)
|
||||
entry.pack(pady=5)
|
||||
entry.focus()
|
||||
|
||||
def save():
|
||||
new_name = entry.get().strip()
|
||||
if new_name and new_name != self.selected_camera:
|
||||
if new_name in self.cameras:
|
||||
messagebox.showerror("Error", "Camera already exists!", parent=dialog)
|
||||
return
|
||||
idx = self.cameras.index(self.selected_camera)
|
||||
self.cameras[idx] = new_name
|
||||
self.config_service.remove_camera(self.selected_camera)
|
||||
self.config_service.add_camera(new_name)
|
||||
self.cameras_listbox.delete(0, 'end')
|
||||
for camera in self.cameras:
|
||||
self.cameras_listbox.insert('end', camera)
|
||||
self.selected_camera = new_name
|
||||
dialog.destroy()
|
||||
elif new_name == self.selected_camera:
|
||||
dialog.destroy()
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Please enter a name!", parent=dialog)
|
||||
|
||||
ttk.Button(dialog, text="Save", command=save).pack(pady=10)
|
||||
dialog.bind('<Return>', lambda e: save())
|
||||
|
||||
def _create_lenses_tab(self, parent):
|
||||
# Listbox
|
||||
list_frame = ttk.Frame(parent)
|
||||
list_frame.pack(fill='both', expand=True, padx=10, pady=10)
|
||||
|
||||
scrollbar = ttk.Scrollbar(list_frame)
|
||||
scrollbar.pack(side='right', fill='y')
|
||||
|
||||
self.lenses_listbox = tk.Listbox(list_frame, yscrollcommand=scrollbar.set,
|
||||
bg='#2d2d2d', fg='#e0e0e0',
|
||||
selectbackground='#4CAF50', selectforeground='white',
|
||||
font=('Segoe UI', 10))
|
||||
self.lenses_listbox.pack(fill='both', expand=True)
|
||||
scrollbar.config(command=self.lenses_listbox.yview)
|
||||
|
||||
def _update_lenses_list(self):
|
||||
self.lenses_list.clear()
|
||||
for lens in self.lenses:
|
||||
self.lenses_list.addItem(lens)
|
||||
self._selected_lens = None
|
||||
self.remove_lens_btn.setEnabled(False)
|
||||
self.lenses_listbox.insert('end', lens)
|
||||
|
||||
def _select_lens(self, lens: str):
|
||||
self._selected_lens = lens
|
||||
self.remove_lens_btn.setEnabled(True)
|
||||
self.cameras_list.clearSelection()
|
||||
self.telescopes_list.clearSelection()
|
||||
self._selected_camera = None
|
||||
self._selected_telescope = None
|
||||
self.remove_camera_btn.setEnabled(False)
|
||||
self.remove_telescope_btn.setEnabled(False)
|
||||
self.lenses_listbox.bind('<<ListboxSelect>>', self._on_lens_select)
|
||||
|
||||
# Buttons
|
||||
btn_frame = ttk.Frame(parent)
|
||||
btn_frame.pack(pady=10)
|
||||
|
||||
ttk.Button(btn_frame, text="Add Lens", command=self._add_lens).pack(side='left', padx=5)
|
||||
self.remove_lens_btn = ttk.Button(btn_frame, text="Remove", command=self._remove_lens, state='disabled')
|
||||
self.remove_lens_btn.pack(side='left', padx=5)
|
||||
self.edit_lens_btn = ttk.Button(btn_frame, text="Edit", command=self._edit_lens, state='disabled')
|
||||
self.edit_lens_btn.pack(side='left', padx=5)
|
||||
|
||||
def _on_lens_select(self, event):
|
||||
selection = self.lenses_listbox.curselection()
|
||||
if selection:
|
||||
self.selected_lens = self.lenses_listbox.get(selection[0])
|
||||
self.remove_lens_btn.config(state='normal')
|
||||
self.edit_lens_btn.config(state='normal')
|
||||
|
||||
def _add_lens(self):
|
||||
name, ok = QInputDialog.getText(self, "Добавить объектив", "Введите название объектива:")
|
||||
if ok and name and name.strip():
|
||||
new_name = name.strip()
|
||||
if new_name in self.lenses:
|
||||
QMessageBox.warning(self, "Ошибка", "Такой объектив уже существует!")
|
||||
return
|
||||
self.lenses.append(new_name)
|
||||
self.config_service.add_lens(new_name)
|
||||
self._update_lenses_list()
|
||||
QMessageBox.information(self, "Успех", f"Объектив '{new_name}' добавлен")
|
||||
dialog = tk.Toplevel(self)
|
||||
dialog.title("Add Lens")
|
||||
dialog.geometry("350x120")
|
||||
dialog.transient(self)
|
||||
dialog.grab_set()
|
||||
|
||||
ttk.Label(dialog, text="Lens name:", font=('Segoe UI', 10)).pack(pady=15)
|
||||
entry = ttk.Entry(dialog, width=40)
|
||||
entry.pack(pady=5)
|
||||
entry.focus()
|
||||
|
||||
def save():
|
||||
new_lens = entry.get().strip()
|
||||
if new_lens:
|
||||
if new_lens in self.lenses:
|
||||
messagebox.showerror("Error", "Lens already exists!", parent=dialog)
|
||||
return
|
||||
self.lenses.append(new_lens)
|
||||
self.config_service.add_lens(new_lens)
|
||||
self.lenses_listbox.insert('end', new_lens)
|
||||
dialog.destroy()
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Please enter lens name!", parent=dialog)
|
||||
|
||||
ttk.Button(dialog, text="OK", command=save).pack(pady=10)
|
||||
dialog.bind('<Return>', lambda e: save())
|
||||
|
||||
def _remove_lens(self):
|
||||
if hasattr(self, '_selected_lens') and self._selected_lens:
|
||||
reply = QMessageBox.question(self, "Подтверждение",
|
||||
f"Удалить объектив '{self._selected_lens}'?",
|
||||
QMessageBox.Yes | QMessageBox.No)
|
||||
if reply == QMessageBox.Yes:
|
||||
self.lenses.remove(self._selected_lens)
|
||||
self.config_service.remove_lens(self._selected_lens)
|
||||
self._update_lenses_list()
|
||||
if self.selected_lens:
|
||||
reply = messagebox.askyesno("Remove Lens", f"Remove '{self.selected_lens}'?", parent=self)
|
||||
if reply:
|
||||
self.lenses.remove(self.selected_lens)
|
||||
self.config_service.remove_lens(self.selected_lens)
|
||||
self.lenses_listbox.delete(0, 'end')
|
||||
for lens in self.lenses:
|
||||
self.lenses_listbox.insert('end', lens)
|
||||
self.selected_lens = None
|
||||
self.remove_lens_btn.config(state='disabled')
|
||||
self.edit_lens_btn.config(state='disabled')
|
||||
|
||||
def _edit_lens(self):
|
||||
if hasattr(self, '_selected_lens') and self._selected_lens:
|
||||
new_name, ok = QInputDialog.getText(self, "Редактировать объектив",
|
||||
f"Изменить '{self._selected_lens}' на:",
|
||||
text=self._selected_lens)
|
||||
if ok and new_name and new_name.strip():
|
||||
new_name = new_name.strip()
|
||||
if new_name != self._selected_lens:
|
||||
if self.selected_lens:
|
||||
dialog = tk.Toplevel(self)
|
||||
dialog.title("Edit Lens")
|
||||
dialog.geometry("350x120")
|
||||
dialog.transient(self)
|
||||
dialog.grab_set()
|
||||
|
||||
ttk.Label(dialog, text="New lens name:", font=('Segoe UI', 10)).pack(pady=15)
|
||||
entry = ttk.Entry(dialog, width=40)
|
||||
entry.insert(0, self.selected_lens)
|
||||
entry.pack(pady=5)
|
||||
entry.focus()
|
||||
|
||||
def save():
|
||||
new_name = entry.get().strip()
|
||||
if new_name and new_name != self.selected_lens:
|
||||
if new_name in self.lenses:
|
||||
QMessageBox.warning(self, "Ошибка", "Такой объектив уже существует!")
|
||||
messagebox.showerror("Error", "Lens already exists!", parent=dialog)
|
||||
return
|
||||
idx = self.lenses.index(self._selected_lens)
|
||||
idx = self.lenses.index(self.selected_lens)
|
||||
self.lenses[idx] = new_name
|
||||
# Обновляем в конфиге (пока просто удаляем старый и добавляем новый)
|
||||
self.config_service.remove_lens(self._selected_lens)
|
||||
self.config_service.remove_lens(self.selected_lens)
|
||||
self.config_service.add_lens(new_name)
|
||||
self._update_lenses_list()
|
||||
self.lenses_listbox.delete(0, 'end')
|
||||
for lens in self.lenses:
|
||||
self.lenses_listbox.insert('end', lens)
|
||||
self.selected_lens = new_name
|
||||
dialog.destroy()
|
||||
elif new_name == self.selected_lens:
|
||||
dialog.destroy()
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Please enter a name!", parent=dialog)
|
||||
|
||||
# ===== Методы для телескопов =====
|
||||
ttk.Button(dialog, text="Save", command=save).pack(pady=10)
|
||||
dialog.bind('<Return>', lambda e: save())
|
||||
|
||||
def _create_telescopes_tab(self, parent):
|
||||
# Listbox
|
||||
list_frame = ttk.Frame(parent)
|
||||
list_frame.pack(fill='both', expand=True, padx=10, pady=10)
|
||||
|
||||
scrollbar = ttk.Scrollbar(list_frame)
|
||||
scrollbar.pack(side='right', fill='y')
|
||||
|
||||
self.telescopes_listbox = tk.Listbox(list_frame, yscrollcommand=scrollbar.set,
|
||||
bg='#2d2d2d', fg='#e0e0e0',
|
||||
selectbackground='#4CAF50', selectforeground='white',
|
||||
font=('Segoe UI', 10))
|
||||
self.telescopes_listbox.pack(fill='both', expand=True)
|
||||
scrollbar.config(command=self.telescopes_listbox.yview)
|
||||
|
||||
def _update_telescopes_list(self):
|
||||
self.telescopes_list.clear()
|
||||
for telescope in self.telescopes:
|
||||
self.telescopes_list.addItem(telescope)
|
||||
self._selected_telescope = None
|
||||
self.remove_telescope_btn.setEnabled(False)
|
||||
self.telescopes_listbox.insert('end', telescope)
|
||||
|
||||
def _select_telescope(self, telescope: str):
|
||||
self._selected_telescope = telescope
|
||||
self.remove_telescope_btn.setEnabled(True)
|
||||
self.cameras_list.clearSelection()
|
||||
self.lenses_list.clearSelection()
|
||||
self._selected_camera = None
|
||||
self._selected_lens = None
|
||||
self.remove_camera_btn.setEnabled(False)
|
||||
self.remove_lens_btn.setEnabled(False)
|
||||
self.telescopes_listbox.bind('<<ListboxSelect>>', self._on_telescope_select)
|
||||
|
||||
# Buttons
|
||||
btn_frame = ttk.Frame(parent)
|
||||
btn_frame.pack(pady=10)
|
||||
|
||||
ttk.Button(btn_frame, text="Add Telescope", command=self._add_telescope).pack(side='left', padx=5)
|
||||
self.remove_telescope_btn = ttk.Button(btn_frame, text="Remove", command=self._remove_telescope, state='disabled')
|
||||
self.remove_telescope_btn.pack(side='left', padx=5)
|
||||
self.edit_telescope_btn = ttk.Button(btn_frame, text="Edit", command=self._edit_telescope, state='disabled')
|
||||
self.edit_telescope_btn.pack(side='left', padx=5)
|
||||
|
||||
def _on_telescope_select(self, event):
|
||||
selection = self.telescopes_listbox.curselection()
|
||||
if selection:
|
||||
self.selected_telescope = self.telescopes_listbox.get(selection[0])
|
||||
self.remove_telescope_btn.config(state='normal')
|
||||
self.edit_telescope_btn.config(state='normal')
|
||||
|
||||
def _add_telescope(self):
|
||||
"""Добавляет телескоп с указанием диафрагмы (фиксированной)"""
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle("Добавить телескоп")
|
||||
dialog.setMinimumWidth(400)
|
||||
dialog = tk.Toplevel(self)
|
||||
dialog.title("Add Telescope")
|
||||
dialog.geometry("400x320")
|
||||
dialog.transient(self)
|
||||
dialog.grab_set()
|
||||
|
||||
layout = QVBoxLayout(dialog)
|
||||
ttk.Label(dialog, text="Telescope name:").pack(pady=(15, 5))
|
||||
name_entry = ttk.Entry(dialog, width=40)
|
||||
name_entry.pack()
|
||||
|
||||
form_layout = QFormLayout()
|
||||
ttk.Label(dialog, text="Aperture (f/):").pack(pady=(10, 5))
|
||||
aperture_entry = ttk.Entry(dialog, width=20)
|
||||
aperture_entry.insert(0, "5.0")
|
||||
aperture_entry.pack()
|
||||
|
||||
name_edit = QLineEdit()
|
||||
name_edit.setPlaceholderText("例如: Celestron 8\"")
|
||||
form_layout.addRow("Название:", name_edit)
|
||||
ttk.Label(dialog, text="Focal length (mm):").pack(pady=(10, 5))
|
||||
focal_entry = ttk.Entry(dialog, width=20)
|
||||
focal_entry.insert(0, "1000")
|
||||
focal_entry.pack()
|
||||
|
||||
aperture_spin = QDoubleSpinBox()
|
||||
aperture_spin.setRange(0.5, 20.0)
|
||||
aperture_spin.setSingleStep(0.1)
|
||||
aperture_spin.setValue(5.0)
|
||||
aperture_spin.setSuffix(" (f/)")
|
||||
form_layout.addRow("Диафрагма (f/):", aperture_spin)
|
||||
ttk.Label(dialog, text="Diameter (mm):").pack(pady=(10, 5))
|
||||
diameter_entry = ttk.Entry(dialog, width=20)
|
||||
diameter_entry.insert(0, "200")
|
||||
diameter_entry.pack()
|
||||
|
||||
focal_spin = QSpinBox()
|
||||
focal_spin.setRange(100, 5000)
|
||||
focal_spin.setSingleStep(50)
|
||||
focal_spin.setSuffix(" мм")
|
||||
form_layout.addRow("Фокусное расстояние:", focal_spin)
|
||||
def save():
|
||||
name = name_entry.get().strip()
|
||||
if not name:
|
||||
messagebox.showerror("Error", "Please enter telescope name!", parent=dialog)
|
||||
return
|
||||
|
||||
diameter_spin = QSpinBox()
|
||||
diameter_spin.setRange(50, 500)
|
||||
diameter_spin.setSingleStep(10)
|
||||
diameter_spin.setSuffix(" мм")
|
||||
form_layout.addRow("Диаметр объектива:", diameter_spin)
|
||||
try:
|
||||
aperture = float(aperture_entry.get())
|
||||
focal = int(focal_entry.get())
|
||||
diameter = int(diameter_entry.get())
|
||||
except ValueError:
|
||||
messagebox.showerror("Error", "Invalid numeric values!", parent=dialog)
|
||||
return
|
||||
|
||||
layout.addLayout(form_layout)
|
||||
telescope_info = f"{name} (f/{aperture}, F={focal}mm, D={diameter}mm)"
|
||||
if telescope_info in self.telescopes:
|
||||
messagebox.showerror("Error", "Telescope already exists!", parent=dialog)
|
||||
return
|
||||
|
||||
buttons_layout = QHBoxLayout()
|
||||
ok_btn = QPushButton("OK")
|
||||
cancel_btn = QPushButton("Отмена")
|
||||
buttons_layout.addWidget(ok_btn)
|
||||
buttons_layout.addWidget(cancel_btn)
|
||||
layout.addLayout(buttons_layout)
|
||||
self.telescopes.append(telescope_info)
|
||||
self.config_service.add_telescope(telescope_info)
|
||||
self.telescopes_listbox.insert('end', telescope_info)
|
||||
dialog.destroy()
|
||||
|
||||
ok_btn.clicked.connect(dialog.accept)
|
||||
cancel_btn.clicked.connect(dialog.reject)
|
||||
|
||||
if dialog.exec():
|
||||
name = name_edit.text().strip()
|
||||
if name:
|
||||
telescope_info = f"{name} (f/{aperture_spin.value()}, F={focal_spin.value()}mm, D={diameter_spin.value()}mm)"
|
||||
if telescope_info not in self.telescopes:
|
||||
self.telescopes.append(telescope_info)
|
||||
self.config_service.add_telescope(telescope_info)
|
||||
self._update_telescopes_list()
|
||||
QMessageBox.information(self, "Успех", f"Телескоп '{name}' добавлен")
|
||||
btn_frame = ttk.Frame(dialog)
|
||||
btn_frame.pack(pady=20)
|
||||
ttk.Button(btn_frame, text="OK", command=save).pack(side='left', padx=10)
|
||||
ttk.Button(btn_frame, text="Cancel", command=dialog.destroy).pack(side='left', padx=10)
|
||||
|
||||
def _remove_telescope(self):
|
||||
if hasattr(self, '_selected_telescope') and self._selected_telescope:
|
||||
reply = QMessageBox.question(self, "Подтверждение",
|
||||
f"Удалить телескоп '{self._selected_telescope}'?",
|
||||
QMessageBox.Yes | QMessageBox.No)
|
||||
if reply == QMessageBox.Yes:
|
||||
self.telescopes.remove(self._selected_telescope)
|
||||
self.config_service.remove_telescope(self._selected_telescope)
|
||||
self._update_telescopes_list()
|
||||
if self.selected_telescope:
|
||||
reply = messagebox.askyesno("Remove Telescope", f"Remove '{self.selected_telescope}'?", parent=self)
|
||||
if reply:
|
||||
self.telescopes.remove(self.selected_telescope)
|
||||
self.config_service.remove_telescope(self.selected_telescope)
|
||||
self.telescopes_listbox.delete(0, 'end')
|
||||
for telescope in self.telescopes:
|
||||
self.telescopes_listbox.insert('end', telescope)
|
||||
self.selected_telescope = None
|
||||
self.remove_telescope_btn.config(state='disabled')
|
||||
self.edit_telescope_btn.config(state='disabled')
|
||||
|
||||
def _edit_telescope(self):
|
||||
if hasattr(self, '_selected_telescope') and self._selected_telescope:
|
||||
new_name, ok = QInputDialog.getText(self, "Редактировать телескоп",
|
||||
f"Изменить '{self._selected_telescope}' на:",
|
||||
text=self._selected_telescope)
|
||||
if ok and new_name and new_name.strip():
|
||||
new_name = new_name.strip()
|
||||
if new_name != self._selected_telescope:
|
||||
if new_name in self.telescopes:
|
||||
QMessageBox.warning(self, "Ошибка", "Такой телескоп уже существует!")
|
||||
return
|
||||
idx = self.telescopes.index(self._selected_telescope)
|
||||
self.telescopes[idx] = new_name
|
||||
self.config_service.remove_telescope(self._selected_telescope)
|
||||
self.config_service.add_telescope(new_name)
|
||||
self._update_telescopes_list()
|
||||
if self.selected_telescope:
|
||||
import re
|
||||
match = re.search(r'(.+?) \(f/([\d\.]+), F=(\d+)mm, D=(\d+)mm\)', self.selected_telescope)
|
||||
if match:
|
||||
old_name = match.group(1)
|
||||
old_aperture = match.group(2)
|
||||
old_focal = match.group(3)
|
||||
old_diameter = match.group(4)
|
||||
else:
|
||||
old_name = self.selected_telescope
|
||||
old_aperture = "5.0"
|
||||
old_focal = "1000"
|
||||
old_diameter = "200"
|
||||
|
||||
dialog = tk.Toplevel(self)
|
||||
dialog.title("Edit Telescope")
|
||||
dialog.geometry("400x320")
|
||||
dialog.transient(self)
|
||||
dialog.grab_set()
|
||||
|
||||
ttk.Label(dialog, text="Telescope name:").pack(pady=(15, 5))
|
||||
name_entry = ttk.Entry(dialog, width=40)
|
||||
name_entry.insert(0, old_name)
|
||||
name_entry.pack()
|
||||
|
||||
ttk.Label(dialog, text="Aperture (f/):").pack(pady=(10, 5))
|
||||
aperture_entry = ttk.Entry(dialog, width=20)
|
||||
aperture_entry.insert(0, old_aperture)
|
||||
aperture_entry.pack()
|
||||
|
||||
ttk.Label(dialog, text="Focal length (mm):").pack(pady=(10, 5))
|
||||
focal_entry = ttk.Entry(dialog, width=20)
|
||||
focal_entry.insert(0, old_focal)
|
||||
focal_entry.pack()
|
||||
|
||||
ttk.Label(dialog, text="Diameter (mm):").pack(pady=(10, 5))
|
||||
diameter_entry = ttk.Entry(dialog, width=20)
|
||||
diameter_entry.insert(0, old_diameter)
|
||||
diameter_entry.pack()
|
||||
|
||||
def save():
|
||||
new_name = name_entry.get().strip()
|
||||
try:
|
||||
aperture = float(aperture_entry.get())
|
||||
focal = int(focal_entry.get())
|
||||
diameter = int(diameter_entry.get())
|
||||
except ValueError:
|
||||
messagebox.showerror("Error", "Invalid numeric values!", parent=dialog)
|
||||
return
|
||||
|
||||
new_info = f"{new_name} (f/{aperture}, F={focal}mm, D={diameter}mm)"
|
||||
if new_info != self.selected_telescope and new_info in self.telescopes:
|
||||
messagebox.showerror("Error", "Telescope already exists!", parent=dialog)
|
||||
return
|
||||
|
||||
idx = self.telescopes.index(self.selected_telescope)
|
||||
self.telescopes[idx] = new_info
|
||||
self.config_service.remove_telescope(self.selected_telescope)
|
||||
self.config_service.add_telescope(new_info)
|
||||
self.telescopes_listbox.delete(0, 'end')
|
||||
for telescope in self.telescopes:
|
||||
self.telescopes_listbox.insert('end', telescope)
|
||||
dialog.destroy()
|
||||
|
||||
btn_frame = ttk.Frame(dialog)
|
||||
btn_frame.pack(pady=20)
|
||||
ttk.Button(btn_frame, text="Save", command=save).pack(side='left', padx=10)
|
||||
ttk.Button(btn_frame, text="Cancel", command=dialog.destroy).pack(side='left', padx=10)
|
||||
Loading…
Add table
Add a link
Reference in a new issue