diff --git a/photobooth/defaults.cfg b/photobooth/defaults.cfg
index a733062..d581446 100644
--- a/photobooth/defaults.cfg
+++ b/photobooth/defaults.cfg
@@ -9,6 +9,8 @@ width = 1024
height = 600
# Hide cursor
hide_cursor = False
+# Use specified style
+style = default
[Camera]
# Camera module to use (python-gphoto2, gphoto2-cffi, gphoto2-commandline, opencv)
diff --git a/photobooth/gui/Qt5Gui/Frames.py b/photobooth/gui/Qt5Gui/Frames.py
index cb1572f..bbfcd2a 100644
--- a/photobooth/gui/Qt5Gui/Frames.py
+++ b/photobooth/gui/Qt5Gui/Frames.py
@@ -31,6 +31,7 @@ from ... import camera
from ... import printer
from . import Widgets
+from . import styles
class Start(QtWidgets.QFrame):
@@ -492,15 +493,24 @@ class Settings(QtWidgets.QFrame):
self._cfg.get('Gui', 'module'))
self.add('Gui', 'module', module)
- width = QtWidgets.QLineEdit(self._cfg.get('Gui', 'width'))
- height = QtWidgets.QLineEdit(self._cfg.get('Gui', 'height'))
+ width = QtWidgets.QSpinBox()
+ width.setRange(100, 999999)
+ width.setValue(self._cfg.getInt('Gui', 'width'))
self.add('Gui', 'width', width)
+
+ height = QtWidgets.QSpinBox()
+ height.setRange(100, 999999)
+ height.setValue(self._cfg.getInt('Gui', 'height'))
self.add('Gui', 'height', height)
cursor = QtWidgets.QCheckBox()
cursor.setChecked(self._cfg.getBool('Gui', 'hide_cursor'))
self.add('Gui', 'hide_cursor', cursor)
+ style = self.createModuleComboBox(styles,
+ self._cfg.get('Gui', 'style'))
+ self.add('Gui', 'style', style)
+
lay_size = QtWidgets.QHBoxLayout()
lay_size.addWidget(width)
lay_size.addWidget(QtWidgets.QLabel('x'))
@@ -511,6 +521,7 @@ class Settings(QtWidgets.QFrame):
layout.addRow('Gui module:', module)
layout.addRow('Window size [px]:', lay_size)
layout.addRow('Hide cursor:', cursor)
+ layout.addRow('Appearance:', style)
widget = QtWidgets.QWidget()
widget.setLayout(layout)
@@ -524,14 +535,19 @@ class Settings(QtWidgets.QFrame):
preview.setChecked(self._cfg.getBool('Photobooth', 'show_preview'))
self.add('Photobooth', 'show_preview', preview)
- greet_time = QtWidgets.QLineEdit(self._cfg.get('Photobooth',
- 'greeter_time'))
- count_time = QtWidgets.QLineEdit(self._cfg.get('Photobooth',
- 'countdown_time'))
- displ_time = QtWidgets.QLineEdit(self._cfg.get('Photobooth',
- 'display_time'))
+ greet_time = QtWidgets.QSpinBox()
+ greet_time.setRange(0, 1000)
+ greet_time.setValue(self._cfg.getInt('Photobooth', 'greeter_time'))
self.add('Photobooth', 'greeter_time', greet_time)
+
+ count_time = QtWidgets.QSpinBox()
+ count_time.setRange(0, 1000)
+ count_time.setValue(self._cfg.getInt('Photobooth', 'countdown_time'))
self.add('Photobooth', 'countdown_time', count_time)
+
+ displ_time = QtWidgets.QSpinBox()
+ displ_time.setRange(0, 1000)
+ displ_time.setValue(self._cfg.getInt('Photobooth', 'display_time'))
self.add('Photobooth', 'display_time', displ_time)
layout = QtWidgets.QFormLayout()
@@ -563,21 +579,34 @@ class Settings(QtWidgets.QFrame):
self.init('Picture')
- num_x = QtWidgets.QLineEdit(self._cfg.get('Picture', 'num_x'))
- num_y = QtWidgets.QLineEdit(self._cfg.get('Picture', 'num_y'))
+ num_x = QtWidgets.QSpinBox()
+ num_x.setRange(1, 99)
+ num_x.setValue(self._cfg.getInt('Picture', 'num_x'))
self.add('Picture', 'num_x', num_x)
+
+ num_y = QtWidgets.QSpinBox()
+ num_y.setRange(1, 99)
+ num_y.setValue(self._cfg.getInt('Picture', 'num_y'))
self.add('Picture', 'num_y', num_y)
- size_x = QtWidgets.QLineEdit(self._cfg.get('Picture', 'size_x'))
- size_y = QtWidgets.QLineEdit(self._cfg.get('Picture', 'size_y'))
+ size_x = QtWidgets.QSpinBox()
+ size_x.setRange(1, 999999)
+ size_x.setValue(self._cfg.getInt('Picture', 'size_x'))
self.add('Picture', 'size_x', size_x)
+
+ size_y = QtWidgets.QSpinBox()
+ size_y.setRange(1, 999999)
+ size_y.setValue(self._cfg.getInt('Picture', 'size_y'))
self.add('Picture', 'size_y', size_y)
- min_dist_x = QtWidgets.QLineEdit(self._cfg.get('Picture',
- 'min_dist_x'))
- min_dist_y = QtWidgets.QLineEdit(self._cfg.get('Picture',
- 'min_dist_y'))
+ min_dist_x = QtWidgets.QSpinBox()
+ min_dist_x.setRange(0, 999999)
+ min_dist_x.setValue(self._cfg.getInt('Picture', 'min_dist_x'))
self.add('Picture', 'min_dist_x', min_dist_x)
+
+ min_dist_y = QtWidgets.QSpinBox()
+ min_dist_y.setRange(0, 999999)
+ min_dist_y.setValue(self._cfg.getInt('Picture', 'min_dist_y'))
self.add('Picture', 'min_dist_y', min_dist_y)
basedir = QtWidgets.QLineEdit(self._cfg.get('Picture', 'basedir'))
@@ -603,7 +632,7 @@ class Settings(QtWidgets.QFrame):
def file_dialog():
dialog = QtWidgets.QFileDialog.getExistingDirectory
basedir.setText(dialog(self, 'Select directory',
- os.expanduser('~'),
+ os.path.expanduser('~'),
QtWidgets.QFileDialog.ShowDirsOnly))
file_button = QtWidgets.QPushButton('Select directory')
@@ -635,11 +664,19 @@ class Settings(QtWidgets.QFrame):
enable.setChecked(self._cfg.getBool('Gpio', 'enable'))
self.add('Gpio', 'enable', enable)
- exit_pin = QtWidgets.QLineEdit(self._cfg.get('Gpio', 'exit_pin'))
- trig_pin = QtWidgets.QLineEdit(self._cfg.get('Gpio', 'trigger_pin'))
- lamp_pin = QtWidgets.QLineEdit(self._cfg.get('Gpio', 'lamp_pin'))
+ exit_pin = QtWidgets.QSpinBox()
+ exit_pin.setRange(1, 40)
+ exit_pin.setValue(self._cfg.getInt('Gpio', 'exit_pin'))
self.add('Gpio', 'exit_pin', exit_pin)
+
+ trig_pin = QtWidgets.QSpinBox()
+ trig_pin.setRange(1, 40)
+ trig_pin.setValue(self._cfg.getInt('Gpio', 'trigger_pin'))
self.add('Gpio', 'trigger_pin', trig_pin)
+
+ lamp_pin = QtWidgets.QSpinBox()
+ lamp_pin.setRange(1, 40)
+ lamp_pin.setValue(self._cfg.getInt('Gpio', 'lamp_pin'))
self.add('Gpio', 'lamp_pin', lamp_pin)
layout = QtWidgets.QFormLayout()
@@ -664,8 +701,12 @@ class Settings(QtWidgets.QFrame):
self._cfg.get('Printer', 'module'))
self.add('Printer', 'module', module)
- width = QtWidgets.QLineEdit(self._cfg.get('Printer', 'width'))
- height = QtWidgets.QLineEdit(self._cfg.get('Printer', 'height'))
+ width = QtWidgets.QSpinBox()
+ width.setRange(0, 999999)
+ width.setValue(self._cfg.getInt('Printer', 'width'))
+ height = QtWidgets.QSpinBox()
+ height.setRange(0, 999999)
+ height.setValue(self._cfg.getInt('Printer', 'height'))
self.add('Printer', 'width', width)
self.add('Printer', 'height', height)
@@ -693,6 +734,8 @@ class Settings(QtWidgets.QFrame):
self._cfg.set('Gui', 'height', self.get('Gui', 'height').text())
self._cfg.set('Gui', 'hide_cursor',
str(self.get('Gui', 'hide_cursor').isChecked()))
+ self._cfg.set('Gui', 'style',
+ styles[self.get('Gui', 'style').currentIndex()][0])
self._cfg.set('Photobooth', 'show_preview',
str(self.get('Photobooth', 'show_preview').isChecked()))
diff --git a/photobooth/gui/Qt5Gui/PyQt5Gui.py b/photobooth/gui/Qt5Gui/PyQt5Gui.py
index f6f1c8e..3c513f4 100644
--- a/photobooth/gui/Qt5Gui/PyQt5Gui.py
+++ b/photobooth/gui/Qt5Gui/PyQt5Gui.py
@@ -18,6 +18,7 @@
# along with this program. If not, see .
import logging
+import os
from PyQt5 import QtCore
from PyQt5 import QtWidgets
@@ -27,6 +28,7 @@ from PIL import ImageQt
from .. import GuiState
from ..GuiSkeleton import GuiSkeleton
+from . import styles
from . import Frames
from . import Postprocessor
from . import Receiver
@@ -79,7 +81,14 @@ class PyQt5Gui(GuiSkeleton):
self._disableTrigger()
+ style = self._cfg.get('Gui', 'style')
+ filename = next((file for name, file in styles if name == style))
+
+ with open(os.path.join(os.path.dirname(__file__), filename), 'r') as f:
+ stylesheet = f.read()
+
self._app = QtWidgets.QApplication(argv)
+ self._app.setStyleSheet(stylesheet)
self._gui = PyQt5MainWindow(self._cfg, self._handleKeypressEvent)
def _initReceiver(self):
diff --git a/photobooth/gui/Qt5Gui/__init__.py b/photobooth/gui/Qt5Gui/__init__.py
index 4ff9c2e..8e97318 100644
--- a/photobooth/gui/Qt5Gui/__init__.py
+++ b/photobooth/gui/Qt5Gui/__init__.py
@@ -17,4 +17,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+# Available style sheets as tuples of (style name, style file)
+styles = (('default', 'stylesheets/default.qss'),
+ ('dark', 'stylesheets/dark.qss'))
+
from .PyQt5Gui import PyQt5Gui # noqa
diff --git a/photobooth/gui/Qt5Gui/stylesheets/dark.qss b/photobooth/gui/Qt5Gui/stylesheets/dark.qss
new file mode 100644
index 0000000..9e94741
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/stylesheets/dark.qss
@@ -0,0 +1,87 @@
+QMainWindow, QWidget {
+ background-color: black;
+ color: #eeeeee;
+}
+
+/* Customizing settings */
+
+QTabWidget {
+ background-color: black;
+ color: #eeeeee;
+}
+
+QTabBar::tab {
+ background-color: #333333;
+ border-style: outset;
+ border-width: 2px;
+ border-top-left-radius: 15px;
+ border-top-right-radius: 15px;
+ border-color: #eeeeee;
+ padding: 8px;
+}
+
+QTabBar::tab:selected {
+ background-color: #666666;
+}
+
+QCheckBox::indicator {
+ width: 25px;
+ height: 25px;
+ background-color: #333333;
+ border-style: outset;
+ border-width: 2px;
+ border-radius: 5px;
+ border-color: #eeeeee;
+}
+
+QCheckBox::indicator::unchecked {
+ background: none;
+}
+
+QCheckBox::indicator::checked {
+ background-color: #eeeeee;
+}
+
+QComboBox, QDateEdit, QLineEdit, QSpinBox, QTimeEdit {
+ height: 25px;
+ background-color: #333333;
+ border-style: outset;
+ border-width: 2px;
+ border-radius: 5px;
+ border-color: #eeeeee;
+ padding: 8px;
+}
+
+QComboBox QAbstractItemView {
+ background-color: #333333;
+ selection-background-color: #666666;
+ border-style: outset;
+ border-width: 2px;
+ border-radius: 5px;
+ border-color: #eeeeee;
+ padding: 8px;
+}
+
+QComboBox::drop-down, QDateEdit::drop-down, QSpinBox::down-button,
+QTimeEdit::down-button {
+ background: #666666;
+ color: #eeeeee;
+ border: none;
+ width: 20px;
+}
+
+QSpinBox::up-button, QTimeEdit::up-button {
+ background: #999999;
+ color: #eeeeee;
+ border: none;
+ width: 20px;
+}
+
+QPushButton {
+ background-color: #333333;
+ border-style: outset;
+ border-width: 2px;
+ border-radius: 15px;
+ border-color: #eeeeee;
+ padding: 8px;
+}
diff --git a/photobooth/gui/Qt5Gui/stylesheets/default.qss b/photobooth/gui/Qt5Gui/stylesheets/default.qss
new file mode 100644
index 0000000..70721cb
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/stylesheets/default.qss
@@ -0,0 +1 @@
+/* empty stylesheet: use system colors */
\ No newline at end of file