da es unter tkinter keinen fertigen Drucker-Dialog gibt, dachte ich, ich mache es mir einfach und nehme den hübschen QT5-Dialog.
Offenbar geht das nicht so, wie ich dachte. Ich habe mir ein Script aus dem Netz gefischt, das den Zugriff für txt und html zeigte und bastelte das für pdf in meinem Projekt um:
Code: Alles auswählen
# gui.qt5_print_dialog_pdf.py
import sys
from pathlib import Path
import fitz
from PyQt5.QtWidgets import QApplication, QFileDialog, QMessageBox, QWidget
from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
from PyQt5.QtGui import QPainter, QImage
def print_pdf_dialog(pdf_path: str = None, parent: QWidget = None) -> bool:
"""
Öffnet einen PDF-Druck-Dialog.
- Wenn pdf_path None, öffnet sich ein QFileDialog.
- parent kann ein QWidget sein (z.B. dein Hauptfenster).
Returns True, wenn gedruckt oder Dialog abgebrochen wurde, False bei Fehler.
"""
# 1) QApplication sicherstellen
app_created = False
app = QApplication.instance()
if not app:
app = QApplication(sys.argv)
app_created = True
# 2) PDF-Pfad ermitteln
if not pdf_path:
pdf_path, _ = QFileDialog.getOpenFileName(
parent, "PDF auswählen", "", "PDF-Dateien (*.pdf)"
)
if not pdf_path:
# Nutzer hat abgebrochen
if app_created:
app.quit()
return False
# 3) PDF laden
try:
doc = fitz.open(pdf_path)
except Exception as e:
QMessageBox.critical(parent, "Fehler", f"PDF konnte nicht geladen werden:\n{e}")
if app_created:
app.quit()
return False
# 4) Drucker-Dialog anzeigen
printer = QPrinter()
dlg = QPrintDialog(printer, parent)
if dlg.exec_() != QPrintDialog.Accepted:
# Abgebrochen, aber kein Fehler
if app_created:
app.quit()
return True
# 5) Seiten drucken
painter = QPainter(printer)
for page_num in range(doc.page_count):
page = doc.load_page(page_num)
pix = page.get_pixmap(dpi=printer.resolution())
img = QImage(
pix.samples, pix.width, pix.height, pix.stride, QImage.Format_RGB888
)
# Bild im Druckbereich skalieren
rect = painter.viewport()
size = img.size()
size.scale(rect.size(), 1) # 1 == Qt.KeepAspectRatio
painter.setViewport(rect.x(), rect.y(), size.width(), size.height())
painter.setWindow(img.rect())
painter.drawImage(0, 0, img)
if page_num < doc.page_count - 1:
printer.newPage()
painter.end()
if app_created:
app.quit()
return True
if __name__ == "__main__":
# Nur beim direkten Aufruf wird der Dialog geöffnet
success = print_pdf_dialog()
sys.exit(0 if success else 1)
Sobald ich es irgendwie anfasse - also schon beim Import, startet es den Dialog. Auch aus einem python-Terminal heraus, einzige Codezeile '"import qt5_printer..." und Dialog geht auf. Das ist ärgerlich (für mich) aber ich hätte hier auch weiter herum gesucht, aber das wirklich Böse ist, dass, wenn ich den Dialog wegklicke, mein GUI mit stirbt.
Wie im Titel geschrieben, ich habe von QT keine Ahnung, ich weiß nicht, ob das so gehört - aber vielleicht gibt es ja eine Möglichkeit, dass es erst mit Methodenaufruf loslegt? Danke für eure Hilfe vorab