diff --git a/photobooth/Photobooth.py b/photobooth/Photobooth.py index 002fe6a..c49a10d 100644 --- a/photobooth/Photobooth.py +++ b/photobooth/Photobooth.py @@ -10,7 +10,6 @@ from PictureDimensions import PictureDimensions import gui - class Photobooth: def __init__(self, config, camera): diff --git a/photobooth/__init__.py b/photobooth/__init__.py index 48d5ace..c409338 100644 --- a/photobooth/__init__.py +++ b/photobooth/__init__.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -import sys, main +import sys +from .main import main if __name__ == "__main__": - sys.exit(main.main(sys.argv)) + sys.exit(main(sys.argv)) \ No newline at end of file diff --git a/photobooth/defaults.cfg b/photobooth/defaults.cfg index 738b0f4..43cc50f 100644 --- a/photobooth/defaults.cfg +++ b/photobooth/defaults.cfg @@ -22,6 +22,16 @@ trigger_channel = 23 # Pin 7 (Channel 4) switches the lamp on and off lamp_channel = 4 +[Printer] +# Enable printing (True/False) +enable = True +# Printer module to use (qt5) +module = qt5 +# Paper width in mm +width = 150 +# Paper height in mm +height = 100 + [Photobooth] # Show preview while posing time (True/False) show_preview = True diff --git a/photobooth/gui/PyQt5Gui.py b/photobooth/gui/PyQt5Gui.py index 45db8c5..259270a 100644 --- a/photobooth/gui/PyQt5Gui.py +++ b/photobooth/gui/PyQt5Gui.py @@ -1,8 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# import Gui - from PIL import ImageQt from PyQt5.QtCore import Qt, QObject, QThread, pyqtSignal @@ -10,6 +8,9 @@ from PyQt5.QtWidgets import (QApplication, QCheckBox, QComboBox, QFormLayout, QF from PyQt5.QtGui import QImage, QPainter, QPixmap from . import * +import camera, printer + +from printer.PrinterPyQt5 import PrinterPyQt5 as Printer class PyQt5Gui(Gui): @@ -23,6 +24,7 @@ class PyQt5Gui(Gui): self._app = QApplication(argv) self._p = PyQt5MainWindow() self._lastState = self.showStart + self._printer = Printer((cfg.getInt('Printer', 'width'), cfg.getInt('Printer', 'height'))) def run(self, send, recv): @@ -88,6 +90,8 @@ class PyQt5Gui(Gui): elif isinstance(state, PictureState): img = ImageQt.ImageQt(state.picture) self._p.setCentralWidget(PyQt5PictureMessage('', img)) + + self._printer.print('test.pdf', state.picture) elif isinstance(state, ErrorState): self.showError(state.title, state.message) else: @@ -284,6 +288,7 @@ class PyQt5Settings(QFrame): grid = QGridLayout() grid.addWidget(self.createGuiSettings(), 0, 0) grid.addWidget(self.createGpioSettings(), 1, 0) + grid.addWidget(self.createPrinterSettings(), 2, 0) grid.addWidget(self.createCameraSettings(), 0, 1) grid.addWidget(self.createPhotoboothSettings(), 1, 1) grid.addWidget(self.createPictureSettings(), 2, 1) @@ -295,6 +300,18 @@ class PyQt5Settings(QFrame): self.setLayout(layout) + def createModuleComboBox(self, module_list, current_module): + + cb = QComboBox() + for m in module_list: + cb.addItem(m[0]) + + idx = [x for x, m in enumerate(module_list) if m[0] == current_module] + cb.setCurrentIndex(idx[0] if len(idx) > 0 else -1) + + return cb + + def createGuiSettings(self): global cfg @@ -303,13 +320,20 @@ class PyQt5Settings(QFrame): self._value_widgets['Gui']['fullscreen'] = QCheckBox('Enable fullscreen') if cfg.getBool('Gui', 'fullscreen'): self._value_widgets['Gui']['fullscreen'].toggle() + self._value_widgets['Gui']['module'] = self.createModuleComboBox(modules, cfg.get('Gui', 'module')) self._value_widgets['Gui']['width'] = QLineEdit(cfg.get('Gui', 'width')) self._value_widgets['Gui']['height'] = QLineEdit(cfg.get('Gui', 'height')) layout = QFormLayout() layout.addRow(self._value_widgets['Gui']['fullscreen']) - layout.addRow(QLabel('Width:'), self._value_widgets['Gui']['width']) - layout.addRow(QLabel('Height:'), self._value_widgets['Gui']['height']) + layout.addRow(QLabel('Gui module:'), self._value_widgets['Gui']['module']) + + sublayout_size = QHBoxLayout() + sublayout_size.addWidget(QLabel('Window size [px]:')) + sublayout_size.addWidget(self._value_widgets['Gui']['width']) + sublayout_size.addWidget(QLabel('x')) + sublayout_size.addWidget(self._value_widgets['Gui']['height']) + layout.addRow(sublayout_size) widget = QGroupBox('Interface settings') widget.setLayout(layout) @@ -339,28 +363,39 @@ class PyQt5Settings(QFrame): return widget + def createPrinterSettings(self): + + global cfg + + self._value_widgets['Printer'] = {} + self._value_widgets['Printer']['enable'] = QCheckBox('Enable Printing') + if cfg.getBool('Printer', 'enable'): + self._value_widgets['Printer']['enable'].toggle() + self._value_widgets['Printer']['module'] = self.createModuleComboBox(printer.modules, cfg.get('Printer', 'module')) + self._value_widgets['Printer']['width'] = QLineEdit(cfg.get('Printer', 'width')) + self._value_widgets['Printer']['height'] = QLineEdit(cfg.get('Printer', 'height')) + + layout = QFormLayout() + layout.addRow(self._value_widgets['Printer']['enable']) + layout.addRow(QLabel('Printer module:'), self._value_widgets['Printer']['module']) + + sublayout_size = QHBoxLayout() + sublayout_size.addWidget(QLabel('Paper size [mm]:')) + sublayout_size.addWidget(self._value_widgets['Printer']['width']) + sublayout_size.addWidget(QLabel('x')) + sublayout_size.addWidget(self._value_widgets['Printer']['height']) + layout.addRow(sublayout_size) + + widget = QGroupBox('Printer settings') + widget.setLayout(layout) + return widget + def createCameraSettings(self): global cfg - self._camera_modules = [ - ('gphoto2-commandline', 'gphoto2 via command line'), - # ('piggyphoto', 'piggyphoto'), - ('gphoto2-cffi', 'gphoto2-cffi'), - ('python-gphoto2', 'python-gphoto2'), - ('opencv', 'OpenCV'), - ('', 'none') ] - - wrapper = QComboBox() - for m in self._camera_modules: - wrapper.addItem(m[1]) - - current_wrapper = cfg.get('Camera', 'module') - idx = [x for x, m in enumerate(self._camera_modules) if m[0] == current_wrapper] - wrapper.setCurrentIndex(idx[0] if len(idx) > 0 else -1) - self._value_widgets['Camera'] = {} - self._value_widgets['Camera']['module'] = wrapper + self._value_widgets['Camera']['module'] = self.createModuleComboBox(camera.modules, cfg.get('Camera', 'module')) layout = QFormLayout() layout.addRow(QLabel('Camera module:'), self._value_widgets['Camera']['module']) @@ -443,7 +478,7 @@ class PyQt5Settings(QFrame): btnSave = QPushButton('Save') btnSave.resize(btnSave.sizeHint()) - btnSave.clicked.connect(self.storeConfig) + btnSave.clicked.connect(self.storeConfigAndRestart) layout.addWidget(btnSave) btnCancel = QPushButton('Cancel') @@ -461,11 +496,12 @@ class PyQt5Settings(QFrame): return widget - def storeConfig(self): + def storeConfigAndRestart(self): global cfg cfg.set('Gui', 'fullscreen', str(self._value_widgets['Gui']['fullscreen'].isChecked())) + cfg.set('Gui', 'module', modules[self._value_widgets['Gui']['module'].currentIndex()][0]) cfg.set('Gui', 'width', self._value_widgets['Gui']['width'].text()) cfg.set('Gui', 'height', self._value_widgets['Gui']['height'].text()) @@ -474,6 +510,11 @@ class PyQt5Settings(QFrame): cfg.set('Gpio', 'trigger_channel', self._value_widgets['Gpio']['trigger_channel'].text()) cfg.set('Gpio', 'lamp_channel', self._value_widgets['Gpio']['lamp_channel'].text()) + cfg.set('Printer', 'enable', str(self._value_widgets['Printer']['enable'].isChecked())) + cfg.set('Printer', 'module', modules[self._value_widgets['Printer']['module'].currentIndex()][0]) + cfg.set('Printer', 'width', self._value_widgets['Printer']['width'].text()) + cfg.set('Printer', 'height', self._value_widgets['Printer']['height'].text()) + cfg.set('Photobooth', 'show_preview', str(self._value_widgets['Photobooth']['show_preview'].isChecked())) cfg.set('Photobooth', 'greeter_time', str(self._value_widgets['Photobooth']['greeter_time'].text())) cfg.set('Photobooth', 'countdown_time', str(self._value_widgets['Photobooth']['countdown_time'].text())) @@ -487,7 +528,7 @@ class PyQt5Settings(QFrame): cfg.set('Picture', 'min_dist_y', self._value_widgets['Picture']['min_dist_y'].text()) cfg.set('Picture', 'basename', self._value_widgets['Picture']['basename'].text()) - cfg.set('Camera', 'module', self._camera_modules[self._value_widgets['Camera']['module'].currentIndex()][0]) + cfg.set('Camera', 'module', camera.modules[self._value_widgets['Camera']['module'].currentIndex()][0]) cfg.write() self._gui.restart() @@ -502,6 +543,7 @@ class PyQt5Settings(QFrame): + class PyQt5PictureMessage(QFrame): def __init__(self, message, picture=None): @@ -521,8 +563,7 @@ class PyQt5PictureMessage(QFrame): def paintEvent(self, event): - painter = QPainter() - painter.begin(self) + painter = QPainter(self) if self._picture != None: if isinstance(self._picture, QImage): diff --git a/photobooth/printer/PrinterPyQt5.py b/photobooth/printer/PrinterPyQt5.py new file mode 100644 index 0000000..0e7b3e1 --- /dev/null +++ b/photobooth/printer/PrinterPyQt5.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from PIL import ImageQt + +from PyQt5.QtCore import Qt, QPoint, QSizeF +from PyQt5.QtGui import QPageSize, QPainter, QPixmap +from PyQt5.QtPrintSupport import QPrinter + +from . import Printer + +class PrinterPyQt5(Printer): + + def __init__(self, page_size): + + super().__init__() + + self._printer = QPrinter(QPrinter.HighResolution) + self._printer.setOutputFormat(QPrinter.PdfFormat) + self._printer.setPageSize(QPageSize(QSizeF(*page_size), QPageSize.Millimeter)) + + + def print(self, filename, picture): + + img = ImageQt.ImageQt(picture) + img = img.scaled(self._printer.pageRect().size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) + self._printer.setOutputFileName(filename) + painter = QPainter(self._printer) + painter.drawImage(QPoint(0, 0), img) + painter.end() diff --git a/photobooth/printer/__init__.py b/photobooth/printer/__init__.py new file mode 100644 index 0000000..03eb1d0 --- /dev/null +++ b/photobooth/printer/__init__.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + + +# Available printer modules as tuples of (config name, module name, class name) +modules = ( + ('qt5', 'PrinterPyQt5', 'PrinterPyQt5'), ) + + +class Printer: + + def __init__(self): + + pass \ No newline at end of file