src\MainWindow.py formatiert

This commit is contained in:
2025-05-28 19:30:37 +02:00
parent 0e629ecaaa
commit 7426d9c50d
+44 -44
View File
@@ -3,7 +3,7 @@ import os
import pymupdf # PyMuPDF import pymupdf # PyMuPDF
from PySide6.QtCore import Qt from PySide6.QtCore import Qt
from PySide6.QtGui import QCursor, QPixmap, QImage, QPainter, QAction, QIcon from PySide6.QtGui import QCursor, QPixmap, QImage, QPainter, QAction
from PySide6.QtWidgets import QLabel, QMainWindow, QApplication, QStyleFactory from PySide6.QtWidgets import QLabel, QMainWindow, QApplication, QStyleFactory
from ui.MainWinddow_ui import Ui_MainWindow from ui.MainWinddow_ui import Ui_MainWindow
@@ -54,49 +54,49 @@ class MainWindow(QMainWindow):
# Hole alle verfügbaren Themes # Hole alle verfügbaren Themes
available_themes = QStyleFactory.keys() available_themes = QStyleFactory.keys()
current_theme = QApplication.style().objectName() current_theme = QApplication.style().objectName()
print(f"Verfügbare Themes: {available_themes}") print(f"Verfügbare Themes: {available_themes}")
print(f"Aktuelles Theme: {current_theme}") print(f"Aktuelles Theme: {current_theme}")
# Füge Theme-Aktionen zum Menü hinzu # Füge Theme-Aktionen zum Menü hinzu
for theme_name in available_themes: for theme_name in available_themes:
action = QAction(theme_name, self) action = QAction(theme_name, self)
action.setCheckable(True) action.setCheckable(True)
# Markiere das aktuelle Theme # Markiere das aktuelle Theme
if theme_name.lower() == current_theme.lower(): if theme_name.lower() == current_theme.lower():
action.setChecked(True) action.setChecked(True)
# Verbinde die Aktion mit der Theme-Wechsel-Funktion # Verbinde die Aktion mit der Theme-Wechsel-Funktion
action.triggered.connect(lambda checked, theme=theme_name: self.change_theme(theme)) action.triggered.connect(lambda checked, theme=theme_name: self.change_theme(theme))
# Füge die Aktion zum Theme-Menü hinzu # Füge die Aktion zum Theme-Menü hinzu
self.ui.menuThema.addAction(action) self.ui.menuThema.addAction(action)
def change_theme(self, theme_name): def change_theme(self, theme_name):
""" """
Wechselt das Theme der Anwendung. Wechselt das Theme der Anwendung.
Args: Args:
theme_name: Name des zu verwendenden Themes theme_name: Name des zu verwendenden Themes
""" """
print(f"Wechsle zu Theme: {theme_name}") print(f"Wechsle zu Theme: {theme_name}")
try: try:
# Erstelle den neuen Style # Erstelle den neuen Style
style = QStyleFactory.create(theme_name) style = QStyleFactory.create(theme_name)
if style: if style:
# Wende den neuen Style auf die Anwendung an # Wende den neuen Style auf die Anwendung an
QApplication.setStyle(style) QApplication.setStyle(style)
# Aktualisiere die Checkmarks im Menü # Aktualisiere die Checkmarks im Menü
for action in self.ui.menuThema.actions(): for action in self.ui.menuThema.actions():
action.setChecked(action.text() == theme_name) action.setChecked(action.text() == theme_name)
print(f"Theme erfolgreich gewechselt zu: {theme_name}") print(f"Theme erfolgreich gewechselt zu: {theme_name}")
else: else:
print(f"Fehler: Theme '{theme_name}' konnte nicht erstellt werden") print(f"Fehler: Theme '{theme_name}' konnte nicht erstellt werden")
except Exception as e: except Exception as e:
print(f"Fehler beim Wechseln des Themes: {e}") print(f"Fehler beim Wechseln des Themes: {e}")
@@ -115,7 +115,7 @@ class MainWindow(QMainWindow):
# Basis-Pfad zu den PDF-Ordnern # Basis-Pfad zu den PDF-Ordnern
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
pdf_base_dir = os.path.join(base_dir, "src", "ui", "res", "pdf") pdf_base_dir = os.path.join(base_dir, "src", "ui", "res", "pdf")
diff_dir = os.path.join(pdf_base_dir, "diff") diff_dir = os.path.join(pdf_base_dir, "diff")
ref_dir = os.path.join(pdf_base_dir, "ref") ref_dir = os.path.join(pdf_base_dir, "ref")
new_dir = os.path.join(pdf_base_dir, "new") new_dir = os.path.join(pdf_base_dir, "new")
@@ -167,10 +167,10 @@ class MainWindow(QMainWindow):
diff_page = diff_doc[page_num] diff_page = diff_doc[page_num]
ref_page = ref_doc[page_num] ref_page = ref_doc[page_num]
new_page = new_doc[page_num] new_page = new_doc[page_num]
# Seiten in hoher Auflösung rendern # Seiten in hoher Auflösung rendern
matrix = pymupdf.Matrix(2.0, 2.0) # 2x Vergrößerung für bessere Qualität matrix = pymupdf.Matrix(2.0, 2.0) # 2x Vergrößerung für bessere Qualität
# Diff-Seite für Thumbnail verwenden # Diff-Seite für Thumbnail verwenden
diff_pix = diff_page.get_pixmap(matrix=matrix) diff_pix = diff_page.get_pixmap(matrix=matrix)
diff_img_data = diff_pix.tobytes("png") diff_img_data = diff_pix.tobytes("png")
@@ -196,9 +196,9 @@ class MainWindow(QMainWindow):
thumbnail.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) thumbnail.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
thumbnail.setMouseTracking(True) thumbnail.setMouseTracking(True)
self.ui.verticalLayout_2.addWidget(thumbnail) self.ui.verticalLayout_2.addWidget(thumbnail)
# Seitennumer für Thumbnail anzeigen # Seitennumer für Thumbnail anzeigen
thumbnail_label = QLabel(f"Seite: {page_num+1}") thumbnail_label = QLabel(f"Seite: {page_num + 1}")
thumbnail_label.setAlignment(Qt.AlignmentFlag.AlignCenter) thumbnail_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.ui.verticalLayout_2.addWidget(thumbnail_label) self.ui.verticalLayout_2.addWidget(thumbnail_label)
@@ -207,9 +207,9 @@ class MainWindow(QMainWindow):
fullsize.setObjectName(f"fullsize_{pdf_filename}_page_{page_num + 1}") fullsize.setObjectName(f"fullsize_{pdf_filename}_page_{page_num + 1}")
fullsize.setAlignment(Qt.AlignmentFlag.AlignHCenter) # Horizontale Zentrierung fullsize.setAlignment(Qt.AlignmentFlag.AlignHCenter) # Horizontale Zentrierung
self.ui.verticalLayout_3.addWidget(fullsize) self.ui.verticalLayout_3.addWidget(fullsize)
# Seitennumer für Vollansich anzeigen # Seitennumer für Vollansich anzeigen
fullsize_label = QLabel(f"Seite: {page_num+1}") fullsize_label = QLabel(f"Seite: {page_num + 1}")
fullsize_label.setAlignment(Qt.AlignmentFlag.AlignCenter) fullsize_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.ui.verticalLayout_3.addWidget(fullsize_label) self.ui.verticalLayout_3.addWidget(fullsize_label)
@@ -221,13 +221,13 @@ class MainWindow(QMainWindow):
# Click-Event für das Thumbnail einrichten # Click-Event für das Thumbnail einrichten
thumbnail.mousePressEvent = lambda event, t=thumbnail: self.on_thumbnail_clicked(event, t) thumbnail.mousePressEvent = lambda event, t=thumbnail: self.on_thumbnail_clicked(event, t)
# Drag-to-Scroll Events für große Bilder einrichten # Drag-to-Scroll Events für große Bilder einrichten
fullsize.mousePressEvent = lambda event, f=fullsize: self.on_fullsize_mouse_press(event, f) fullsize.mousePressEvent = lambda event, f=fullsize: self.on_fullsize_mouse_press(event, f)
fullsize.mouseMoveEvent = lambda event, f=fullsize: self.on_fullsize_mouse_move(event, f) fullsize.mouseMoveEvent = lambda event, f=fullsize: self.on_fullsize_mouse_move(event, f)
fullsize.mouseReleaseEvent = lambda event, f=fullsize: self.on_fullsize_mouse_release(event, f) fullsize.mouseReleaseEvent = lambda event, f=fullsize: self.on_fullsize_mouse_release(event, f)
print(f"Seite {page_num+1} gerendert.") print(f"Seite {page_num + 1} gerendert.")
# PDF-Dokumente schließen # PDF-Dokumente schließen
diff_doc.close() diff_doc.close()
@@ -256,14 +256,14 @@ class MainWindow(QMainWindow):
# Zoom-Slider verbinden # Zoom-Slider verbinden
self.ui.zoom.valueChanged.connect(self.apply_zoom) self.ui.zoom.valueChanged.connect(self.apply_zoom)
# Alpha-Slider verbinden # Alpha-Slider verbinden
self.ui.alpha.valueChanged.connect(self.on_alpha_changed) self.ui.alpha.valueChanged.connect(self.on_alpha_changed)
def on_alpha_changed(self, alpha_value): def on_alpha_changed(self, alpha_value):
""" """
Wird ausgeführt, wenn der Alpha-Slider geändert wird. Wird ausgeführt, wenn der Alpha-Slider geändert wird.
Args: Args:
alpha_value: Der neue Alpha-Wert (-100 bis 100) alpha_value: Der neue Alpha-Wert (-100 bis 100)
""" """
@@ -273,22 +273,22 @@ class MainWindow(QMainWindow):
def update_layered_images(self): def update_layered_images(self):
"""Aktualisiert alle überlagerten Bilder basierend auf dem aktuellen Alpha-Wert.""" """Aktualisiert alle überlagerten Bilder basierend auf dem aktuellen Alpha-Wert."""
alpha_value = self.ui.alpha.value() alpha_value = self.ui.alpha.value()
for fullsize_label in self.ref_pixmaps.keys(): for fullsize_label in self.ref_pixmaps.keys():
# Hole die Original-Pixmaps für alle drei Ebenen # Hole die Original-Pixmaps für alle drei Ebenen
ref_pixmap = self.ref_pixmaps[fullsize_label] ref_pixmap = self.ref_pixmaps[fullsize_label]
diff_pixmap = self.diff_pixmaps[fullsize_label] diff_pixmap = self.diff_pixmaps[fullsize_label]
new_pixmap = self.new_pixmaps[fullsize_label] new_pixmap = self.new_pixmaps[fullsize_label]
# Erstelle das überlagerte Bild # Erstelle das überlagerte Bild
layered_pixmap = self.create_layered_pixmap(ref_pixmap, diff_pixmap, new_pixmap, alpha_value) layered_pixmap = self.create_layered_pixmap(ref_pixmap, diff_pixmap, new_pixmap, alpha_value)
# Wende aktuellen Zoom an # Wende aktuellen Zoom an
zoom_factor = self.current_zoom / 100.0 zoom_factor = self.current_zoom / 100.0
if zoom_factor != 1.0: if zoom_factor != 1.0:
new_width = int(layered_pixmap.width() * zoom_factor) new_width = int(layered_pixmap.width() * zoom_factor)
layered_pixmap = layered_pixmap.scaledToWidth(new_width, Qt.TransformationMode.SmoothTransformation) layered_pixmap = layered_pixmap.scaledToWidth(new_width, Qt.TransformationMode.SmoothTransformation)
# Setze das überlagerte Bild # Setze das überlagerte Bild
fullsize_label.setPixmap(layered_pixmap) fullsize_label.setPixmap(layered_pixmap)
fullsize_label.setAlignment(Qt.AlignmentFlag.AlignHCenter) fullsize_label.setAlignment(Qt.AlignmentFlag.AlignHCenter)
@@ -296,27 +296,27 @@ class MainWindow(QMainWindow):
def create_layered_pixmap(self, ref_pixmap, diff_pixmap, new_pixmap, alpha_value): def create_layered_pixmap(self, ref_pixmap, diff_pixmap, new_pixmap, alpha_value):
""" """
Erstellt ein übergelagertes Pixmap basierend auf dem Alpha-Wert. Erstellt ein übergelagertes Pixmap basierend auf dem Alpha-Wert.
Args: Args:
ref_pixmap: Unterste Ebene (ref) ref_pixmap: Unterste Ebene (ref)
diff_pixmap: Mittlere Ebene (diff) diff_pixmap: Mittlere Ebene (diff)
new_pixmap: Oberste Ebene (new) new_pixmap: Oberste Ebene (new)
alpha_value: Alpha-Wert (-100 bis 100) alpha_value: Alpha-Wert (-100 bis 100)
Returns: Returns:
QPixmap: Das überlagerte Bild QPixmap: Das überlagerte Bild
""" """
# Verwende die Größe des größten Bildes # Verwende die Größe des größten Bildes
max_width = max(ref_pixmap.width(), diff_pixmap.width(), new_pixmap.width()) max_width = max(ref_pixmap.width(), diff_pixmap.width(), new_pixmap.width())
max_height = max(ref_pixmap.height(), diff_pixmap.height(), new_pixmap.height()) max_height = max(ref_pixmap.height(), diff_pixmap.height(), new_pixmap.height())
# Erstelle ein leeres Pixmap für das Ergebnis # Erstelle ein leeres Pixmap für das Ergebnis
result = QPixmap(max_width, max_height) result = QPixmap(max_width, max_height)
result.fill(Qt.GlobalColor.white) result.fill(Qt.GlobalColor.white)
painter = QPainter(result) painter = QPainter(result)
painter.setRenderHint(QPainter.RenderHint.Antialiasing) painter.setRenderHint(QPainter.RenderHint.Antialiasing)
if alpha_value <= 0: if alpha_value <= 0:
# Alpha von -100 bis 0: Übergang von ref zu diff # Alpha von -100 bis 0: Übergang von ref zu diff
# ref_opacity: 1.0 bei -100, 0.0 bei 0 # ref_opacity: 1.0 bei -100, 0.0 bei 0
@@ -331,20 +331,20 @@ class MainWindow(QMainWindow):
ref_opacity = 0.0 ref_opacity = 0.0
diff_opacity = 1.0 - alpha_value / 100.0 diff_opacity = 1.0 - alpha_value / 100.0
new_opacity = alpha_value / 100.0 new_opacity = alpha_value / 100.0
# Zeichne die Ebenen mit entsprechender Transparenz # Zeichne die Ebenen mit entsprechender Transparenz
if ref_opacity > 0: if ref_opacity > 0:
painter.setOpacity(ref_opacity) painter.setOpacity(ref_opacity)
painter.drawPixmap(0, 0, ref_pixmap) painter.drawPixmap(0, 0, ref_pixmap)
if diff_opacity > 0: if diff_opacity > 0:
painter.setOpacity(diff_opacity) painter.setOpacity(diff_opacity)
painter.drawPixmap(0, 0, diff_pixmap) painter.drawPixmap(0, 0, diff_pixmap)
if new_opacity > 0: if new_opacity > 0:
painter.setOpacity(new_opacity) painter.setOpacity(new_opacity)
painter.drawPixmap(0, 0, new_pixmap) painter.drawPixmap(0, 0, new_pixmap)
painter.end() painter.end()
return result return result
@@ -384,7 +384,7 @@ class MainWindow(QMainWindow):
def on_fullsize_mouse_press(self, event, fullsize_label): def on_fullsize_mouse_press(self, event, fullsize_label):
""" """
Wird ausgeführt, wenn die Maustaste auf einem großen Bild gedrückt wird. Wird ausgeführt, wenn die Maustaste auf einem großen Bild gedrückt wird.
Args: Args:
event: Das Maus-Event event: Das Maus-Event
fullsize_label: Das große Bild-Label fullsize_label: Das große Bild-Label
@@ -398,7 +398,7 @@ class MainWindow(QMainWindow):
def on_fullsize_mouse_move(self, event, fullsize_label): def on_fullsize_mouse_move(self, event, fullsize_label):
""" """
Wird ausgeführt, wenn die Maus über einem großen Bild bewegt wird. Wird ausgeführt, wenn die Maus über einem großen Bild bewegt wird.
Args: Args:
event: Das Maus-Event event: Das Maus-Event
fullsize_label: Das große Bild-Label fullsize_label: Das große Bild-Label
@@ -407,31 +407,31 @@ class MainWindow(QMainWindow):
# Verwende globale Position für bessere 4K/DPI Kompatibilität # Verwende globale Position für bessere 4K/DPI Kompatibilität
current_pos = event.globalPosition().toPoint() current_pos = event.globalPosition().toPoint()
delta = current_pos - self.last_drag_position delta = current_pos - self.last_drag_position
# Prüfe ob die Bewegung groß genug ist (Anti-Jitter) # Prüfe ob die Bewegung groß genug ist (Anti-Jitter)
if abs(delta.x()) >= self.drag_threshold or abs(delta.y()) >= self.drag_threshold: if abs(delta.x()) >= self.drag_threshold or abs(delta.y()) >= self.drag_threshold:
# Hole die aktuellen Scroll-Balken # Hole die aktuellen Scroll-Balken
v_scrollbar = self.ui.scrollArea_2.verticalScrollBar() v_scrollbar = self.ui.scrollArea_2.verticalScrollBar()
h_scrollbar = self.ui.scrollArea_2.horizontalScrollBar() h_scrollbar = self.ui.scrollArea_2.horizontalScrollBar()
# Berechne neue Scroll-Positionen mit reduzierter Empfindlichkeit # Berechne neue Scroll-Positionen mit reduzierter Empfindlichkeit
scroll_delta_y = int(-delta.y() * self.scroll_sensitivity) scroll_delta_y = int(-delta.y() * self.scroll_sensitivity)
scroll_delta_x = int(-delta.x() * self.scroll_sensitivity) scroll_delta_x = int(-delta.x() * self.scroll_sensitivity)
new_v_value = v_scrollbar.value() + scroll_delta_y new_v_value = v_scrollbar.value() + scroll_delta_y
new_h_value = h_scrollbar.value() + scroll_delta_x new_h_value = h_scrollbar.value() + scroll_delta_x
# Setze die neuen Scroll-Positionen # Setze die neuen Scroll-Positionen
v_scrollbar.setValue(new_v_value) v_scrollbar.setValue(new_v_value)
h_scrollbar.setValue(new_h_value) h_scrollbar.setValue(new_h_value)
# Aktualisiere die letzte Position nur bei erfolgreichem Scroll # Aktualisiere die letzte Position nur bei erfolgreichem Scroll
self.last_drag_position = current_pos self.last_drag_position = current_pos
def on_fullsize_mouse_release(self, event, fullsize_label): def on_fullsize_mouse_release(self, event, fullsize_label):
""" """
Wird ausgeführt, wenn die Maustaste auf einem großen Bild losgelassen wird. Wird ausgeführt, wenn die Maustaste auf einem großen Bild losgelassen wird.
Args: Args:
event: Das Maus-Event event: Das Maus-Event
fullsize_label: Das große Bild-Label fullsize_label: Das große Bild-Label