|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2004 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the UI Previewer main window. |
|
8 """ |
|
9 |
|
10 import contextlib |
|
11 import pathlib |
|
12 |
|
13 from PyQt6.QtCore import QDir, QEvent, QSize, Qt |
|
14 from PyQt6.QtGui import QAction, QKeySequence, QImageWriter, QPainter |
|
15 from PyQt6.QtWidgets import ( |
|
16 QSizePolicy, QSpacerItem, QWidget, QHBoxLayout, QWhatsThis, QDialog, |
|
17 QScrollArea, QApplication, QStyleFactory, QFrame, QMainWindow, |
|
18 QComboBox, QVBoxLayout, QLabel |
|
19 ) |
|
20 from PyQt6.QtPrintSupport import QPrinter, QPrintDialog |
|
21 from PyQt6 import uic |
|
22 |
|
23 |
|
24 from EricWidgets import EricMessageBox, EricFileDialog |
|
25 from EricWidgets.EricMainWindow import EricMainWindow |
|
26 from EricWidgets.EricApplication import ericApp |
|
27 from EricGui.EricOverrideCursor import EricOverrideCursor |
|
28 |
|
29 import Preferences |
|
30 import UI.PixmapCache |
|
31 import UI.Config |
|
32 |
|
33 |
|
34 class UIPreviewer(EricMainWindow): |
|
35 """ |
|
36 Class implementing the UI Previewer main window. |
|
37 """ |
|
38 def __init__(self, filename=None, parent=None, name=None): |
|
39 """ |
|
40 Constructor |
|
41 |
|
42 @param filename name of a UI file to load |
|
43 @param parent parent widget of this window (QWidget) |
|
44 @param name name of this window (string) |
|
45 """ |
|
46 self.mainWidget = None |
|
47 self.currentFile = QDir.currentPath() |
|
48 |
|
49 super().__init__(parent) |
|
50 if not name: |
|
51 self.setObjectName("UIPreviewer") |
|
52 else: |
|
53 self.setObjectName(name) |
|
54 |
|
55 self.setStyle(Preferences.getUI("Style"), |
|
56 Preferences.getUI("StyleSheet")) |
|
57 |
|
58 self.resize(QSize(600, 480).expandedTo(self.minimumSizeHint())) |
|
59 self.statusBar() |
|
60 |
|
61 self.setWindowIcon(UI.PixmapCache.getIcon("eric")) |
|
62 self.setWindowTitle(self.tr("UI Previewer")) |
|
63 |
|
64 self.cw = QWidget(self) |
|
65 self.cw.setObjectName("centralWidget") |
|
66 |
|
67 self.UIPreviewerLayout = QVBoxLayout(self.cw) |
|
68 self.UIPreviewerLayout.setContentsMargins(6, 6, 6, 6) |
|
69 self.UIPreviewerLayout.setSpacing(6) |
|
70 self.UIPreviewerLayout.setObjectName("UIPreviewerLayout") |
|
71 |
|
72 self.styleLayout = QHBoxLayout() |
|
73 self.styleLayout.setContentsMargins(0, 0, 0, 0) |
|
74 self.styleLayout.setSpacing(6) |
|
75 self.styleLayout.setObjectName("styleLayout") |
|
76 |
|
77 self.styleLabel = QLabel(self.tr("Select GUI Theme"), self.cw) |
|
78 self.styleLabel.setObjectName("styleLabel") |
|
79 self.styleLayout.addWidget(self.styleLabel) |
|
80 |
|
81 self.styleCombo = QComboBox(self.cw) |
|
82 self.styleCombo.setObjectName("styleCombo") |
|
83 self.styleCombo.setEditable(False) |
|
84 self.styleCombo.setToolTip(self.tr("Select the GUI Theme")) |
|
85 self.styleLayout.addWidget(self.styleCombo) |
|
86 self.styleCombo.addItems(sorted(QStyleFactory().keys())) |
|
87 currentStyle = Preferences.getSettings().value('UIPreviewer/style') |
|
88 if currentStyle is not None: |
|
89 self.styleCombo.setCurrentIndex(int(currentStyle)) |
|
90 |
|
91 styleSpacer = QSpacerItem( |
|
92 40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) |
|
93 self.styleLayout.addItem(styleSpacer) |
|
94 self.UIPreviewerLayout.addLayout(self.styleLayout) |
|
95 |
|
96 self.previewSV = QScrollArea(self.cw) |
|
97 self.previewSV.setObjectName("preview") |
|
98 self.previewSV.setFrameShape(QFrame.Shape.NoFrame) |
|
99 self.previewSV.setFrameShadow(QFrame.Shadow.Plain) |
|
100 self.previewSV.setSizePolicy( |
|
101 QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) |
|
102 self.UIPreviewerLayout.addWidget(self.previewSV) |
|
103 |
|
104 self.setCentralWidget(self.cw) |
|
105 |
|
106 self.styleCombo.activated[int].connect(self.__guiStyleSelected) |
|
107 |
|
108 self.__initActions() |
|
109 self.__initMenus() |
|
110 self.__initToolbars() |
|
111 |
|
112 self.__updateActions() |
|
113 |
|
114 # defere loading of a UI file until we are shown |
|
115 self.fileToLoad = filename |
|
116 |
|
117 def show(self): |
|
118 """ |
|
119 Public slot to show this dialog. |
|
120 |
|
121 This overloaded slot loads a UI file to be previewed after |
|
122 the main window has been shown. This way, previewing a dialog |
|
123 doesn't interfere with showing the main window. |
|
124 """ |
|
125 super().show() |
|
126 if self.fileToLoad is not None: |
|
127 fn, self.fileToLoad = (self.fileToLoad, None) |
|
128 self.__loadFile(fn) |
|
129 |
|
130 def __initActions(self): |
|
131 """ |
|
132 Private method to define the user interface actions. |
|
133 """ |
|
134 self.openAct = QAction( |
|
135 UI.PixmapCache.getIcon("openUI"), |
|
136 self.tr('&Open File'), self) |
|
137 self.openAct.setShortcut( |
|
138 QKeySequence(self.tr("Ctrl+O", "File|Open"))) |
|
139 self.openAct.setStatusTip(self.tr('Open a UI file for display')) |
|
140 self.openAct.setWhatsThis(self.tr( |
|
141 """<b>Open File</b>""" |
|
142 """<p>This opens a new UI file for display.</p>""" |
|
143 )) |
|
144 self.openAct.triggered.connect(self.__openFile) |
|
145 |
|
146 self.printAct = QAction( |
|
147 UI.PixmapCache.getIcon("print"), |
|
148 self.tr('&Print'), self) |
|
149 self.printAct.setShortcut( |
|
150 QKeySequence(self.tr("Ctrl+P", "File|Print"))) |
|
151 self.printAct.setStatusTip(self.tr('Print a screen capture')) |
|
152 self.printAct.setWhatsThis(self.tr( |
|
153 """<b>Print</b>""" |
|
154 """<p>Print a screen capture.</p>""" |
|
155 )) |
|
156 self.printAct.triggered.connect(self.__printImage) |
|
157 |
|
158 self.printPreviewAct = QAction( |
|
159 UI.PixmapCache.getIcon("printPreview"), |
|
160 self.tr('Print Preview'), self) |
|
161 self.printPreviewAct.setStatusTip(self.tr( |
|
162 'Print preview a screen capture')) |
|
163 self.printPreviewAct.setWhatsThis(self.tr( |
|
164 """<b>Print Preview</b>""" |
|
165 """<p>Print preview a screen capture.</p>""" |
|
166 )) |
|
167 self.printPreviewAct.triggered.connect(self.__printPreviewImage) |
|
168 |
|
169 self.imageAct = QAction( |
|
170 UI.PixmapCache.getIcon("screenCapture"), |
|
171 self.tr('&Screen Capture'), self) |
|
172 self.imageAct.setShortcut( |
|
173 QKeySequence(self.tr("Ctrl+S", "File|Screen Capture"))) |
|
174 self.imageAct.setStatusTip(self.tr( |
|
175 'Save a screen capture to an image file')) |
|
176 self.imageAct.setWhatsThis(self.tr( |
|
177 """<b>Screen Capture</b>""" |
|
178 """<p>Save a screen capture to an image file.</p>""" |
|
179 )) |
|
180 self.imageAct.triggered.connect(self.__saveImage) |
|
181 |
|
182 self.exitAct = QAction( |
|
183 UI.PixmapCache.getIcon("exit"), self.tr('&Quit'), self) |
|
184 self.exitAct.setShortcut( |
|
185 QKeySequence(self.tr("Ctrl+Q", "File|Quit"))) |
|
186 self.exitAct.setStatusTip(self.tr('Quit the application')) |
|
187 self.exitAct.setWhatsThis(self.tr( |
|
188 """<b>Quit</b>""" |
|
189 """<p>Quit the application.</p>""" |
|
190 )) |
|
191 self.exitAct.triggered.connect(ericApp().closeAllWindows) |
|
192 |
|
193 self.copyAct = QAction( |
|
194 UI.PixmapCache.getIcon("editCopy"), self.tr('&Copy'), self) |
|
195 self.copyAct.setShortcut( |
|
196 QKeySequence(self.tr("Ctrl+C", "Edit|Copy"))) |
|
197 self.copyAct.setStatusTip( |
|
198 self.tr('Copy screen capture to clipboard')) |
|
199 self.copyAct.setWhatsThis(self.tr( |
|
200 """<b>Copy</b>""" |
|
201 """<p>Copy screen capture to clipboard.</p>""" |
|
202 )) |
|
203 self.copyAct.triggered.connect(self.__copyImageToClipboard) |
|
204 |
|
205 self.whatsThisAct = QAction( |
|
206 UI.PixmapCache.getIcon("whatsThis"), |
|
207 self.tr('&What\'s This?'), self) |
|
208 self.whatsThisAct.setShortcut(QKeySequence(self.tr("Shift+F1"))) |
|
209 self.whatsThisAct.setStatusTip(self.tr('Context sensitive help')) |
|
210 self.whatsThisAct.setWhatsThis(self.tr( |
|
211 """<b>Display context sensitive help</b>""" |
|
212 """<p>In What's This? mode, the mouse cursor shows an arrow""" |
|
213 """ with a question mark, and you can click on the interface""" |
|
214 """ elements to get a short description of what they do and""" |
|
215 """ how to use them. In dialogs, this feature can be accessed""" |
|
216 """ using the context help button in the titlebar.</p>""" |
|
217 )) |
|
218 self.whatsThisAct.triggered.connect(self.__whatsThis) |
|
219 |
|
220 self.aboutAct = QAction(self.tr('&About'), self) |
|
221 self.aboutAct.setStatusTip(self.tr( |
|
222 'Display information about this software')) |
|
223 self.aboutAct.setWhatsThis(self.tr( |
|
224 """<b>About</b>""" |
|
225 """<p>Display some information about this software.</p>""" |
|
226 )) |
|
227 self.aboutAct.triggered.connect(self.__about) |
|
228 |
|
229 self.aboutQtAct = QAction(self.tr('About &Qt'), self) |
|
230 self.aboutQtAct.setStatusTip( |
|
231 self.tr('Display information about the Qt toolkit')) |
|
232 self.aboutQtAct.setWhatsThis(self.tr( |
|
233 """<b>About Qt</b>""" |
|
234 """<p>Display some information about the Qt toolkit.</p>""" |
|
235 )) |
|
236 self.aboutQtAct.triggered.connect(self.__aboutQt) |
|
237 |
|
238 def __initMenus(self): |
|
239 """ |
|
240 Private method to create the menus. |
|
241 """ |
|
242 mb = self.menuBar() |
|
243 |
|
244 menu = mb.addMenu(self.tr('&File')) |
|
245 menu.setTearOffEnabled(True) |
|
246 menu.addAction(self.openAct) |
|
247 menu.addAction(self.imageAct) |
|
248 menu.addSeparator() |
|
249 menu.addAction(self.printPreviewAct) |
|
250 menu.addAction(self.printAct) |
|
251 menu.addSeparator() |
|
252 menu.addAction(self.exitAct) |
|
253 |
|
254 menu = mb.addMenu(self.tr("&Edit")) |
|
255 menu.setTearOffEnabled(True) |
|
256 menu.addAction(self.copyAct) |
|
257 |
|
258 mb.addSeparator() |
|
259 |
|
260 menu = mb.addMenu(self.tr('&Help')) |
|
261 menu.setTearOffEnabled(True) |
|
262 menu.addAction(self.aboutAct) |
|
263 menu.addAction(self.aboutQtAct) |
|
264 menu.addSeparator() |
|
265 menu.addAction(self.whatsThisAct) |
|
266 |
|
267 def __initToolbars(self): |
|
268 """ |
|
269 Private method to create the toolbars. |
|
270 """ |
|
271 filetb = self.addToolBar(self.tr("File")) |
|
272 filetb.setIconSize(UI.Config.ToolBarIconSize) |
|
273 filetb.addAction(self.openAct) |
|
274 filetb.addAction(self.imageAct) |
|
275 filetb.addSeparator() |
|
276 filetb.addAction(self.printPreviewAct) |
|
277 filetb.addAction(self.printAct) |
|
278 filetb.addSeparator() |
|
279 filetb.addAction(self.exitAct) |
|
280 |
|
281 edittb = self.addToolBar(self.tr("Edit")) |
|
282 edittb.setIconSize(UI.Config.ToolBarIconSize) |
|
283 edittb.addAction(self.copyAct) |
|
284 |
|
285 helptb = self.addToolBar(self.tr("Help")) |
|
286 helptb.setIconSize(UI.Config.ToolBarIconSize) |
|
287 helptb.addAction(self.whatsThisAct) |
|
288 |
|
289 def __whatsThis(self): |
|
290 """ |
|
291 Private slot called in to enter Whats This mode. |
|
292 """ |
|
293 QWhatsThis.enterWhatsThisMode() |
|
294 |
|
295 def __guiStyleSelected(self, index): |
|
296 """ |
|
297 Private slot to handle the selection of a GUI style. |
|
298 |
|
299 @param index index of the selected entry |
|
300 @type int |
|
301 """ |
|
302 selectedStyle = self.styleCombo.itemText(index) |
|
303 if self.mainWidget: |
|
304 self.__updateChildren(selectedStyle) |
|
305 |
|
306 def __about(self): |
|
307 """ |
|
308 Private slot to show the about information. |
|
309 """ |
|
310 EricMessageBox.about( |
|
311 self, |
|
312 self.tr("UI Previewer"), |
|
313 self.tr( |
|
314 """<h3> About UI Previewer </h3>""" |
|
315 """<p>The UI Previewer loads and displays Qt User-Interface""" |
|
316 """ files with various styles, which are selectable via a""" |
|
317 """ selection list.</p>""" |
|
318 ) |
|
319 ) |
|
320 |
|
321 def __aboutQt(self): |
|
322 """ |
|
323 Private slot to show info about Qt. |
|
324 """ |
|
325 EricMessageBox.aboutQt(self, self.tr("UI Previewer")) |
|
326 |
|
327 def __openFile(self): |
|
328 """ |
|
329 Private slot to load a new file. |
|
330 """ |
|
331 fn = EricFileDialog.getOpenFileName( |
|
332 self, |
|
333 self.tr("Select UI file"), |
|
334 self.currentFile, |
|
335 self.tr("Qt User-Interface Files (*.ui)")) |
|
336 if fn: |
|
337 self.__loadFile(fn) |
|
338 |
|
339 def __loadFile(self, fn): |
|
340 """ |
|
341 Private slot to load a ui file. |
|
342 |
|
343 @param fn name of the ui file to be laoded |
|
344 @type str |
|
345 """ |
|
346 if self.mainWidget: |
|
347 self.mainWidget.close() |
|
348 self.previewSV.takeWidget() |
|
349 del self.mainWidget |
|
350 self.mainWidget = None |
|
351 |
|
352 # load the file |
|
353 with contextlib.suppress(Exception): |
|
354 self.mainWidget = uic.loadUi(fn) |
|
355 |
|
356 if self.mainWidget: |
|
357 self.currentFile = fn |
|
358 self.__updateChildren(self.styleCombo.currentText()) |
|
359 if isinstance(self.mainWidget, (QDialog, QMainWindow)): |
|
360 self.mainWidget.show() |
|
361 self.mainWidget.installEventFilter(self) |
|
362 else: |
|
363 self.previewSV.setWidget(self.mainWidget) |
|
364 self.mainWidget.show() |
|
365 else: |
|
366 EricMessageBox.warning( |
|
367 self, |
|
368 self.tr("Load UI File"), |
|
369 self.tr( |
|
370 """<p>The file <b>{0}</b> could not be loaded.</p>""") |
|
371 .format(fn)) |
|
372 self.__updateActions() |
|
373 |
|
374 def __updateChildren(self, sstyle): |
|
375 """ |
|
376 Private slot to change the style of the show UI. |
|
377 |
|
378 @param sstyle name of the selected style (string) |
|
379 """ |
|
380 with EricOverrideCursor(): |
|
381 qstyle = QStyleFactory.create(sstyle) |
|
382 self.mainWidget.setStyle(qstyle) |
|
383 |
|
384 lst = self.mainWidget.findChildren(QWidget) |
|
385 for obj in lst: |
|
386 with contextlib.suppress(AttributeError): |
|
387 obj.setStyle(qstyle) |
|
388 del lst |
|
389 |
|
390 self.mainWidget.hide() |
|
391 self.mainWidget.show() |
|
392 |
|
393 self.lastQStyle = qstyle |
|
394 self.lastStyle = sstyle |
|
395 Preferences.getSettings().setValue( |
|
396 'UIPreviewer/style', self.styleCombo.currentIndex()) |
|
397 |
|
398 def __updateActions(self): |
|
399 """ |
|
400 Private slot to update the actions state. |
|
401 """ |
|
402 if self.mainWidget: |
|
403 self.imageAct.setEnabled(True) |
|
404 self.printAct.setEnabled(True) |
|
405 if self.printPreviewAct: |
|
406 self.printPreviewAct.setEnabled(True) |
|
407 self.copyAct.setEnabled(True) |
|
408 self.styleCombo.setEnabled(True) |
|
409 else: |
|
410 self.imageAct.setEnabled(False) |
|
411 self.printAct.setEnabled(False) |
|
412 if self.printPreviewAct: |
|
413 self.printPreviewAct.setEnabled(False) |
|
414 self.copyAct.setEnabled(False) |
|
415 self.styleCombo.setEnabled(False) |
|
416 |
|
417 def __handleCloseEvent(self): |
|
418 """ |
|
419 Private slot to handle the close event of a viewed QMainWidget. |
|
420 """ |
|
421 if self.mainWidget: |
|
422 self.mainWidget.removeEventFilter(self) |
|
423 del self.mainWidget |
|
424 self.mainWidget = None |
|
425 self.__updateActions() |
|
426 |
|
427 def eventFilter(self, obj, ev): |
|
428 """ |
|
429 Public method called to filter an event. |
|
430 |
|
431 @param obj object, that generated the event (QObject) |
|
432 @param ev the event, that was generated by object (QEvent) |
|
433 @return flag indicating if event was filtered out |
|
434 """ |
|
435 if obj == self.mainWidget: |
|
436 if ev.type() == QEvent.Type.Close: |
|
437 self.__handleCloseEvent() |
|
438 return True |
|
439 else: |
|
440 if isinstance(self.mainWidget, QDialog): |
|
441 return QDialog.eventFilter(self, obj, ev) |
|
442 elif isinstance(self.mainWidget, QMainWindow): |
|
443 return QMainWindow.eventFilter(self, obj, ev) |
|
444 else: |
|
445 return False |
|
446 |
|
447 def __saveImage(self): |
|
448 """ |
|
449 Private slot to handle the Save Image menu action. |
|
450 """ |
|
451 if self.mainWidget is None: |
|
452 EricMessageBox.critical( |
|
453 self, |
|
454 self.tr("Save Image"), |
|
455 self.tr("""There is no UI file loaded.""")) |
|
456 return |
|
457 |
|
458 defaultExt = "PNG" |
|
459 filters = "" |
|
460 formats = QImageWriter.supportedImageFormats() |
|
461 for imageFormat in formats: |
|
462 filters = "{0}*.{1} ".format( |
|
463 filters, bytes(imageFormat).decode().lower()) |
|
464 fileFilter = self.tr("Images ({0})").format(filters[:-1]) |
|
465 |
|
466 fname = EricFileDialog.getSaveFileName( |
|
467 self, |
|
468 self.tr("Save Image"), |
|
469 "", |
|
470 fileFilter) |
|
471 if not fname: |
|
472 return |
|
473 |
|
474 fpath = pathlib.Path(fname) |
|
475 ext = fpath.suffix.upper().replace(".", "") |
|
476 if not ext: |
|
477 ext = defaultExt |
|
478 fpath = fpath.with_suffix(".{0}".format(defaultExt.lower())) |
|
479 |
|
480 pix = self.mainWidget.grab() |
|
481 self.__updateChildren(self.lastStyle) |
|
482 if not pix.save(str(fpath), str(ext)): |
|
483 EricMessageBox.critical( |
|
484 self, |
|
485 self.tr("Save Image"), |
|
486 self.tr( |
|
487 """<p>The file <b>{0}</b> could not be saved.</p>""") |
|
488 .format(fpath)) |
|
489 |
|
490 def __copyImageToClipboard(self): |
|
491 """ |
|
492 Private slot to handle the Copy Image menu action. |
|
493 """ |
|
494 if self.mainWidget is None: |
|
495 EricMessageBox.critical( |
|
496 self, |
|
497 self.tr("Save Image"), |
|
498 self.tr("""There is no UI file loaded.""")) |
|
499 return |
|
500 |
|
501 cb = QApplication.clipboard() |
|
502 cb.setPixmap(self.mainWidget.grab()) |
|
503 self.__updateChildren(self.lastStyle) |
|
504 |
|
505 def __printImage(self): |
|
506 """ |
|
507 Private slot to handle the Print Image menu action. |
|
508 """ |
|
509 if self.mainWidget is None: |
|
510 EricMessageBox.critical( |
|
511 self, |
|
512 self.tr("Print Image"), |
|
513 self.tr("""There is no UI file loaded.""")) |
|
514 return |
|
515 |
|
516 settings = Preferences.getSettings() |
|
517 printer = QPrinter(QPrinter.PrinterMode.HighResolution) |
|
518 printer.setFullPage(True) |
|
519 |
|
520 printerName = Preferences.getPrinter("UIPreviewer/printername") |
|
521 if printerName: |
|
522 printer.setPrinterName(printerName) |
|
523 printer.setPageSize( |
|
524 QPrinter.PageSize(int(settings.value("UIPreviewer/pagesize")))) |
|
525 printer.setPageOrder( |
|
526 QPrinter.PageOrder(int(settings.value("UIPreviewer/pageorder")))) |
|
527 printer.setOrientation(QPrinter.Orientation( |
|
528 int(settings.value("UIPreviewer/orientation")))) |
|
529 printer.setColorMode( |
|
530 QPrinter.ColorMode(int(settings.value("UIPreviewer/colormode")))) |
|
531 |
|
532 printDialog = QPrintDialog(printer, self) |
|
533 if printDialog.exec() == QDialog.DialogCode.Accepted: |
|
534 self.statusBar().showMessage(self.tr("Printing the image...")) |
|
535 self.__print(printer) |
|
536 |
|
537 settings.setValue("UIPreviewer/printername", printer.printerName()) |
|
538 settings.setValue("UIPreviewer/pagesize", printer.pageSize()) |
|
539 settings.setValue("UIPreviewer/pageorder", printer.pageOrder()) |
|
540 settings.setValue("UIPreviewer/orientation", printer.orientation()) |
|
541 settings.setValue("UIPreviewer/colormode", printer.colorMode()) |
|
542 |
|
543 self.statusBar().showMessage( |
|
544 self.tr("Image sent to printer..."), 2000) |
|
545 |
|
546 def __printPreviewImage(self): |
|
547 """ |
|
548 Private slot to handle the Print Preview menu action. |
|
549 """ |
|
550 from PyQt6.QtPrintSupport import QPrintPreviewDialog |
|
551 |
|
552 if self.mainWidget is None: |
|
553 EricMessageBox.critical( |
|
554 self, |
|
555 self.tr("Print Preview"), |
|
556 self.tr("""There is no UI file loaded.""")) |
|
557 return |
|
558 |
|
559 settings = Preferences.getSettings() |
|
560 printer = QPrinter(QPrinter.PrinterMode.HighResolution) |
|
561 printer.setFullPage(True) |
|
562 |
|
563 printerName = Preferences.getPrinter("UIPreviewer/printername") |
|
564 if printerName: |
|
565 printer.setPrinterName(printerName) |
|
566 printer.setPageSize( |
|
567 QPrinter.PageSize(int(settings.value("UIPreviewer/pagesize")))) |
|
568 printer.setPageOrder( |
|
569 QPrinter.PageOrder(int(settings.value("UIPreviewer/pageorder")))) |
|
570 printer.setOrientation(QPrinter.Orientation( |
|
571 int(settings.value("UIPreviewer/orientation")))) |
|
572 printer.setColorMode( |
|
573 QPrinter.ColorMode(int(settings.value("UIPreviewer/colormode")))) |
|
574 |
|
575 preview = QPrintPreviewDialog(printer, self) |
|
576 preview.paintRequested.connect(self.__print) |
|
577 preview.exec() |
|
578 |
|
579 def __print(self, printer): |
|
580 """ |
|
581 Private slot to the actual printing. |
|
582 |
|
583 @param printer reference to the printer object (QPrinter) |
|
584 """ |
|
585 p = QPainter(printer) |
|
586 marginX = ( |
|
587 printer.pageLayout().paintRectPixels(printer.resolution()).x() - |
|
588 printer.pageLayout().fullRectPixels(printer.resolution()).x() |
|
589 ) // 2 |
|
590 marginY = ( |
|
591 printer.pageLayout().paintRectPixels(printer.resolution()).y() - |
|
592 printer.pageLayout().fullRectPixels(printer.resolution()).y() |
|
593 ) // 2 |
|
594 |
|
595 # double the margin on bottom of page |
|
596 if printer.orientation() == QPrinter.Orientation.Portrait: |
|
597 width = printer.width() - marginX * 2 |
|
598 height = printer.height() - marginY * 3 |
|
599 else: |
|
600 marginX *= 2 |
|
601 width = printer.width() - marginX * 2 |
|
602 height = printer.height() - marginY * 2 |
|
603 img = self.mainWidget.grab().toImage() |
|
604 self.__updateChildren(self.lastStyle) |
|
605 p.drawImage( |
|
606 marginX, marginY, img.scaled( |
|
607 width, height, |
|
608 Qt.AspectRatioMode.KeepAspectRatio, |
|
609 Qt.TransformationMode.SmoothTransformation |
|
610 ) |
|
611 ) |
|
612 p.end() |