diff --git a/photobooth/gui/Qt5Gui/Frames.py b/photobooth/gui/Qt5Gui/Frames.py
index f633dea..c766353 100644
--- a/photobooth/gui/Qt5Gui/Frames.py
+++ b/photobooth/gui/Qt5Gui/Frames.py
@@ -82,23 +82,22 @@ class IdleMessage(QtWidgets.QFrame):
def __init__(self):
super().__init__()
+ self.setObjectName('IdleMessage')
- self._message = 'Hit the button!'
+ self._message_label = 'Hit the'
+ self._message_button = 'Button!'
- def _paintMessage(self, painter):
+ self.initFrame()
- f = self.font()
- f.setPixelSize(self.height() / 5)
- painter.setFont(f)
+ def initFrame(self):
- rect = self.rect()
- painter.drawText(rect, QtCore.Qt.AlignCenter, self._message)
+ lbl = QtWidgets.QLabel(self._message_label)
+ btn = QtWidgets.QPushButton(self._message_button)
- def paintEvent(self, event):
-
- painter = QtGui.QPainter(self)
- self._paintMessage(painter)
- painter.end()
+ lay = QtWidgets.QVBoxLayout()
+ lay.addWidget(lbl)
+ lay.addWidget(btn)
+ self.setLayout(lay)
class GreeterMessage(QtWidgets.QFrame):
@@ -106,34 +105,31 @@ class GreeterMessage(QtWidgets.QFrame):
def __init__(self, num_x, num_y):
super().__init__()
+ self.setObjectName('GreeterMessage')
- self._title = 'Get ready!'
+ self._text_title = 'Get ready!'
+ self._text_button = 'Start countdown'
if num_x * num_y > 1:
- self._text = ('Capturing {} pictures...'.format(num_x * num_y))
+ self._text_label = ('for {} pictures...'.format(num_x * num_y))
else:
- self._text = 'Starting the countdown...'
+ self._text_label = ''
- def _paintMessage(self, painter):
+ self.initFrame()
- f = self.font()
+ def initFrame(self):
- f.setPixelSize(self.height() / 5)
- painter.setFont(f)
- rect = QtCore.QRect(0, self.height() * 1 / 5,
- self.width(), self.height() * 3 / 10)
- painter.drawText(rect, QtCore.Qt.AlignCenter, self._title)
+ ttl = QtWidgets.QLabel(self._text_title)
+ ttl.setObjectName('title')
+ btn = QtWidgets.QPushButton(self._text_button)
+ btn.setObjectName('button')
+ lbl = QtWidgets.QLabel(self._text_label)
+ lbl.setObjectName('message')
- f.setPixelSize(self.height() / 8)
- painter.setFont(f)
- rect = QtCore.QRect(0, self.height() * 3 / 5,
- self.width(), self.height() * 3 / 10)
- painter.drawText(rect, QtCore.Qt.AlignCenter, self._text)
-
- def paintEvent(self, event):
-
- painter = QtGui.QPainter(self)
- self._paintMessage(painter)
- painter.end()
+ lay = QtWidgets.QVBoxLayout()
+ lay.addWidget(ttl)
+ lay.addWidget(btn)
+ lay.addWidget(lbl)
+ self.setLayout(lay)
class PoseMessage(QtWidgets.QFrame):
@@ -141,35 +137,22 @@ class PoseMessage(QtWidgets.QFrame):
def __init__(self, num_picture, num_x, num_y):
super().__init__()
+ self.setObjectName('PoseMessage')
- self._title = 'Pose!'
if num_x * num_y > 1:
self._text = 'Picture {} of {}...'.format(num_picture,
num_x * num_y)
else:
self._text = 'Taking a photo...'
- def _paintMessage(self, painter):
+ self.initFrame()
- f = self.font()
+ def initFrame(self):
- f.setPixelSize(self.height() / 5)
- painter.setFont(f)
- rect = QtCore.QRect(0, self.height() * 1 / 5,
- self.width(), self.height() * 3 / 10)
- painter.drawText(rect, QtCore.Qt.AlignCenter, self._title)
-
- f.setPixelSize(self.height() / 8)
- painter.setFont(f)
- rect = QtCore.QRect(0, self.height() * 3 / 5,
- self.width(), self.height() * 3 / 10)
- painter.drawText(rect, QtCore.Qt.AlignCenter, self._text)
-
- def paintEvent(self, event):
-
- painter = QtGui.QPainter(self)
- self._paintMessage(painter)
- painter.end()
+ lbl = QtWidgets.QLabel(self._text)
+ lay = QtWidgets.QVBoxLayout()
+ lay.addWidget(lbl)
+ self.setLayout(lay)
class PictureMessage(QtWidgets.QFrame):
@@ -177,6 +160,7 @@ class PictureMessage(QtWidgets.QFrame):
def __init__(self, picture):
super().__init__()
+ self.setObjectName('PictureMessage')
self._picture = picture
@@ -205,10 +189,20 @@ class WaitMessage(QtWidgets.QFrame):
def __init__(self, message):
super().__init__()
+ self.setObjectName('WaitMessage')
- self._message = message
+ self._text = message
self._clock = Widgets.SpinningWaitClock()
+ self.initFrame()
+
+ def initFrame(self):
+
+ lbl = QtWidgets.QLabel(self._text)
+ lay = QtWidgets.QVBoxLayout()
+ lay.addWidget(lbl)
+ self.setLayout(lay)
+
def showEvent(self, event):
self.startTimer(100)
@@ -218,23 +212,12 @@ class WaitMessage(QtWidgets.QFrame):
self._clock.value += 1
self.update()
- def _paintMessage(self, painter):
-
- f = self.font()
- f.setPixelSize(self.height() / 8)
- painter.setFont(f)
-
- rect = QtCore.QRect(0, self.height() * 3 / 5, self.width(),
- self.height() * 3 / 10)
- painter.drawText(rect, QtCore.Qt.AlignCenter, self._message)
-
def paintEvent(self, event):
offset = ((self.width() - self._clock.width()) // 2,
(self.height() - self._clock.height()) // 2)
painter = QtGui.QPainter(self)
- self._paintMessage(painter)
self._clock.render(painter, QtCore.QPoint(*offset),
self._clock.visibleRegion(),
QtWidgets.QWidget.DrawChildren)
@@ -246,6 +229,7 @@ class CountdownMessage(QtWidgets.QFrame):
def __init__(self, time, action):
super().__init__()
+ self.setObjectName('CountdownMessage')
self._step_size = 50
self._value = time * (1000 // self._step_size)
@@ -309,7 +293,8 @@ class CountdownMessage(QtWidgets.QFrame):
if self.picture is not None:
pix = QtGui.QPixmap.fromImage(self.picture)
- pix = pix.scaled(self.size(), QtCore.Qt.KeepAspectRatio,
+ pix = pix.scaled(self.contentsRect().size(),
+ QtCore.Qt.KeepAspectRatio,
QtCore.Qt.FastTransformation)
origin = ((self.width() - pix.width()) // 2,
(self.height() - pix.height()) // 2)
@@ -479,6 +464,10 @@ class Settings(QtWidgets.QFrame):
idx = [x for x, m in enumerate(module_list) if m[0] == current_module]
cb.setCurrentIndex(idx[0] if len(idx) > 0 else -1)
+ # Fix bug in Qt to allow changing the items in a stylesheet
+ delegate = QtWidgets.QStyledItemDelegate()
+ cb.setItemDelegate(delegate)
+
return cb
def createGuiSettings(self):
@@ -645,11 +634,11 @@ class Settings(QtWidgets.QFrame):
layout = QtWidgets.QFormLayout()
layout.addRow('Number of shots per picture:', lay_num)
layout.addRow('Size of assembled picture [px]:', lay_size)
- layout.addRow('Minimum distance between shots in picture [px]:',
+ layout.addRow('Min. distance between shots [px]:',
lay_dist)
- layout.addRow('Output directory (strftime directives possible):',
+ layout.addRow('Output directory (strftime possible):',
lay_file)
- layout.addRow('Basename of files (strftime directives possible):',
+ layout.addRow('Basename of files (strftime possible):',
basename)
widget = QtWidgets.QWidget()
diff --git a/photobooth/gui/Qt5Gui/PyQt5Gui.py b/photobooth/gui/Qt5Gui/PyQt5Gui.py
index 3c513f4..1e17f88 100644
--- a/photobooth/gui/Qt5Gui/PyQt5Gui.py
+++ b/photobooth/gui/Qt5Gui/PyQt5Gui.py
@@ -21,6 +21,7 @@ import logging
import os
from PyQt5 import QtCore
+from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PIL import ImageQt
@@ -91,6 +92,12 @@ class PyQt5Gui(GuiSkeleton):
self._app.setStyleSheet(stylesheet)
self._gui = PyQt5MainWindow(self._cfg, self._handleKeypressEvent)
+ fonts = ['photobooth/gui/Qt5Gui/fonts/AmaticSC-Regular.ttf',
+ 'photobooth/gui/Qt5Gui/fonts/AmaticSC-Bold.ttf']
+ self._fonts = QtGui.QFontDatabase()
+ for font in fonts:
+ self._fonts.addApplicationFont(font)
+
def _initReceiver(self):
self._receiver = Receiver.Receiver([self._conn])
@@ -200,7 +207,7 @@ class PyQt5Gui(GuiSkeleton):
self._disableTrigger()
num_pic = (self._cfg.getInt('Picture', 'num_x'),
- self._cfg.getInt('Picture', 'num_x'))
+ self._cfg.getInt('Picture', 'num_y'))
greeter_time = self._cfg.getInt('Photobooth', 'greeter_time') * 1000
self._setWidget(Frames.GreeterMessage(*num_pic))
@@ -219,7 +226,7 @@ class PyQt5Gui(GuiSkeleton):
def _showPose(self, state):
num_pic = (self._cfg.getInt('Picture', 'num_x'),
- self._cfg.getInt('Picture', 'num_x'))
+ self._cfg.getInt('Picture', 'num_y'))
self._setWidget(Frames.PoseMessage(state.num_picture, *num_pic))
def _showAssemble(self, state):
@@ -267,8 +274,8 @@ class PyQt5MainWindow(QtWidgets.QMainWindow):
if self._cfg.getBool('Gui', 'fullscreen'):
self.showFullScreen()
else:
- self.resize(self._cfg.getInt('Gui', 'width'),
- self._cfg.getInt('Gui', 'height'))
+ self.setFixedSize(self._cfg.getInt('Gui', 'width'),
+ self._cfg.getInt('Gui', 'height'))
self.show()
def closeEvent(self, e):
diff --git a/photobooth/gui/Qt5Gui/__init__.py b/photobooth/gui/Qt5Gui/__init__.py
index c4c6ee5..dd001be 100644
--- a/photobooth/gui/Qt5Gui/__init__.py
+++ b/photobooth/gui/Qt5Gui/__init__.py
@@ -19,6 +19,7 @@
# Available style sheets as tuples of (style name, style file)
styles = (('default', 'stylesheets/default.qss'),
- ('dark', 'stylesheets/dark.qss'))
+ ('dark', 'stylesheets/dark.qss'),
+ ('pastel', 'stylesheets/pastel.qss'))
from .PyQt5Gui import PyQt5Gui # noqa
diff --git a/photobooth/gui/Qt5Gui/fonts/AmaticSC-Bold.ttf b/photobooth/gui/Qt5Gui/fonts/AmaticSC-Bold.ttf
new file mode 100644
index 0000000..96a7ab6
Binary files /dev/null and b/photobooth/gui/Qt5Gui/fonts/AmaticSC-Bold.ttf differ
diff --git a/photobooth/gui/Qt5Gui/fonts/AmaticSC-Regular.ttf b/photobooth/gui/Qt5Gui/fonts/AmaticSC-Regular.ttf
new file mode 100644
index 0000000..fc4c362
Binary files /dev/null and b/photobooth/gui/Qt5Gui/fonts/AmaticSC-Regular.ttf differ
diff --git a/photobooth/gui/Qt5Gui/fonts/OFL.txt b/photobooth/gui/Qt5Gui/fonts/OFL.txt
new file mode 100644
index 0000000..d6d6630
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/fonts/OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2015 The Amatic SC Project Authors (https://github.com/googlefonts/AmaticSC)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/photobooth/gui/Qt5Gui/images/arrow.png b/photobooth/gui/Qt5Gui/images/arrow.png
new file mode 100644
index 0000000..f7d32ac
Binary files /dev/null and b/photobooth/gui/Qt5Gui/images/arrow.png differ
diff --git a/photobooth/gui/Qt5Gui/images/arrow.svg b/photobooth/gui/Qt5Gui/images/arrow.svg
new file mode 100644
index 0000000..f6ebb4c
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/images/arrow.svg
@@ -0,0 +1,134 @@
+
+
+
+
diff --git a/photobooth/gui/Qt5Gui/images/camera.png b/photobooth/gui/Qt5Gui/images/camera.png
new file mode 100644
index 0000000..9ca2139
Binary files /dev/null and b/photobooth/gui/Qt5Gui/images/camera.png differ
diff --git a/photobooth/gui/Qt5Gui/images/camera.svg b/photobooth/gui/Qt5Gui/images/camera.svg
new file mode 100644
index 0000000..81e49a5
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/images/camera.svg
@@ -0,0 +1,82 @@
+
+
+
+
diff --git a/photobooth/gui/Qt5Gui/images/checkmark.png b/photobooth/gui/Qt5Gui/images/checkmark.png
new file mode 100644
index 0000000..44868ff
Binary files /dev/null and b/photobooth/gui/Qt5Gui/images/checkmark.png differ
diff --git a/photobooth/gui/Qt5Gui/images/checkmark.svg b/photobooth/gui/Qt5Gui/images/checkmark.svg
new file mode 100644
index 0000000..634ac28
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/images/checkmark.svg
@@ -0,0 +1,110 @@
+
+
+
+
diff --git a/photobooth/gui/Qt5Gui/images/down.png b/photobooth/gui/Qt5Gui/images/down.png
new file mode 100644
index 0000000..a5012aa
Binary files /dev/null and b/photobooth/gui/Qt5Gui/images/down.png differ
diff --git a/photobooth/gui/Qt5Gui/images/up-down.svg b/photobooth/gui/Qt5Gui/images/up-down.svg
new file mode 100644
index 0000000..318c4d5
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/images/up-down.svg
@@ -0,0 +1,83 @@
+
+
+
+
diff --git a/photobooth/gui/Qt5Gui/images/up.png b/photobooth/gui/Qt5Gui/images/up.png
new file mode 100644
index 0000000..640acf6
Binary files /dev/null and b/photobooth/gui/Qt5Gui/images/up.png differ
diff --git a/photobooth/gui/Qt5Gui/stylesheets/pastel.qss b/photobooth/gui/Qt5Gui/stylesheets/pastel.qss
new file mode 100644
index 0000000..19635cd
--- /dev/null
+++ b/photobooth/gui/Qt5Gui/stylesheets/pastel.qss
@@ -0,0 +1,182 @@
+/* Outer items */
+
+QWidget {
+ background-color: transparent;
+ color: #eeeeee;
+ font-family: AmaticSC, sans-serif;
+ font-size: 50px;
+}
+
+QMainWindow {
+ background: #ffffff qlineargradient(x1:0 y1:1, x2:1, y2:0, stop:0 rgba(255,165,150,255), stop:1 rgba(0,228,255,112));
+ color: #eeeeee;
+}
+
+/* General controls */
+
+QPushButton {
+ background-color: transparent;
+ border-style: outset;
+ border-width: 1px;
+ border-radius: 15px;
+ border-color: #eeeeee;
+ padding: 10px;
+}
+
+QPushButton:pressed {
+ background-color: #66ffffff;
+}
+
+/* Idle Screen */
+
+QFrame#IdleMessage {
+ background-image: url(photobooth/gui/Qt5Gui/images/arrow.png);
+ background-repeat:; no-repeat;
+ padding: 80px 400px 120px 80px;
+}
+
+QFrame#IdleMessage QLabel {
+ font-size: 160px;
+ qproperty-alignment: AlignCenter;
+}
+
+QFrame#IdleMessage QPushButton {
+ border: none;
+ color: rgba(255, 27, 0, 200);
+ font-size: 200px;
+ text-align: center;
+}
+
+QFrame#IdleMessage QPushButton:pressed {
+ background-color: rgba(255, 27, 0, 200);
+ color: #eeeeee;
+}
+
+/* Greeter Screen */
+
+QFrame#GreeterMessage {
+ padding: 50px;
+}
+
+QFrame#GreeterMessage QLabel#title {
+ font-size: 180px;
+ qproperty-alignment: AlignCenter;
+}
+
+QFrame#GreeterMessage QPushButton#button {
+ border: none;
+ font-size: 120px;
+ margin: 60px 0 20px 0;
+ min-height: 160px;
+ padding: 0;
+ text-align: center;
+}
+
+QFrame#GreeterMessage QLabel#message {
+ font-size: 120px;
+ qproperty-alignment: AlignCenter;
+}
+
+/* Countdown Screen */
+
+QFrame#CountdownMessage {
+ margin: 20px;
+ padding: 30px;
+ background-color: #eeeeee;
+}
+
+/* Pose Screen */
+
+QFrame#PoseMessage {
+ background-image: url(photobooth/gui/Qt5Gui/images/camera.png);
+ background-repeat: no-repeat;
+ padding: 380px 80px 80px 80px;
+}
+
+QFrame#PoseMessage QLabel {
+ font-size: 120px;
+ qproperty-alignment: AlignCenter;
+}
+
+/* Wait Screen */
+
+QFrame#WaitMessage {
+ padding: 350px 80px 80px 80px;
+}
+
+QFrame#WaitMessage QLabel {
+ font-size: 110px;
+ qproperty-alignment: AlignCenter;
+}
+
+/* Picture Screen*/
+
+QFrame#PictureMessage {
+ margin: 40px;
+}
+
+/* Customizing settings */
+
+QTabWidget::pane {
+ background-color: #eeeeee;
+ border-style: outset;
+ border-width: 1px;
+ border-radius: 15px;
+ border-color: #eeeeee;
+ color: #333333;
+ padding: 10px;
+}
+
+QTabWidget::tab-bar {
+ alignment: center;
+}
+
+QTabBar::tab {
+ background-color: transparent;
+ 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: #66ffffff;
+}
+
+QTabWidget QWidget {
+ color: #333333;
+}
+
+QCheckBox::indicator {
+ width: 45px;
+ height: 45px;
+ background-color: transparent;
+ border-style: outset;
+ border-width: 2px;
+ border-radius: 5px;
+ border-color: #333333;
+}
+
+QCheckBox::indicator::checked {
+ background-image: url(photobooth/gui/Qt5Gui/images/checkmark.png);
+ background-repeat: no-repeat;
+}
+
+QComboBox, QDateEdit, QLineEdit, QSpinBox, QTimeEdit {
+ background-color: #eeeeee;
+ color: #333333;
+}
+
+QComboBox QAbstractItemView {
+ background-color: #cccccc;
+ color: #333333;
+ selection-background-color: #eeeeee;
+ selection-color: #333333;
+}
+
+QComboBox QAbstractItemView::item {
+ margin: 5px;
+ min-height: 50px;
+}