class AvatarWidget(QWizardPage): def __init__(self, parent=None): super().__init__(parent) self.setSubTitle(self.tr("<h2>Create Your Avatar</h2>")) vlayout = QVBoxLayout(self) labelLayout = QHBoxLayout() labelImage = QLabel() labelImage.setPixmap(QPixmap(":/data/images/preferences-desktop-personal.png")) labelImage.setMaximumSize(64, 64) labelLayout.addWidget(labelImage) label = QLabel(self) label.setWordWrap(True) label.setText(self.tr("<p>This screen helps you set your <strong>user picture</strong>. You can either choose an image from a \ file or you can capture an image from your camera. Select an option from the <strong>options</strong> menu.</p>")) labelLayout.addWidget(label) vlayout.addLayout(labelLayout) vlayout.addItem(QSpacerItem(20, 40, QSizePolicy.Preferred, QSizePolicy.Preferred)) centerLayout = QHBoxLayout() centerLayout.addItem(QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) groupBox = QGroupBox() groupBox.setMaximumWidth(500) vlayout2 = QVBoxLayout(groupBox) hlayout = QHBoxLayout() comboBox = QComboBox() comboBox.setMinimumWidth(250) comboBox.addItems([self.tr("Options"), self.tr("Choose an image...")]) #Camera control self.cameraInfo = None self.camera = None self.cameraImageCapture = None cameras = QCameraInfo.availableCameras() if len(cameras): self.cameraInfo = cameras[0] comboBox.addItem(self.tr("Camera ") + self.cameraInfo.deviceName()) self.camera = QCamera(self.cameraInfo) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.cameraImageCapture = QCameraImageCapture(self.camera) self.imageProcessing = self.camera.imageProcessing() self.imageProcessing.setWhiteBalanceMode(QCameraImageProcessing.WhiteBalanceSunlight) self.imageProcessing.setContrast(1) self.imageProcessing.setSaturation(1) self.imageProcessing.setSharpeningLevel(1) self.imageProcessing.setDenoisingLevel(1) #self.imageProcessing.setColorFilter(QCameraImageProcessing.ColorFilterWhiteboard) #FIXME Qt5.5 self.cameraImageCapture.imageCaptured.connect(self.imageCapture) self.buttonCam = QPushButton() self.buttonCam.setText(self.tr("Capture")) self.buttonCam.setIcon(QIcon(":/data/images/webcamreceive.png")) self.buttonCam.setVisible(False) self.buttonReplay = QPushButton() self.buttonReplay.setText(self.tr("Recapture")) self.buttonReplay.setIcon(QIcon(":/data/images/view-refresh.png")) self.buttonReplay.setVisible(False) hlayout.addWidget(comboBox) hlayout.addItem(QSpacerItem(300, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) hlayout.addWidget(self.buttonCam) hlayout.addWidget(self.buttonReplay) vlayout2.addLayout(hlayout) hlayout2 = QHBoxLayout() hlayout2.addItem(QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) self.cameraLabel = QLabel() self.cameraLabel.setScaledContents(True) self.cameraLabel.setStyleSheet("background-color: black;") self.cameraLabel.setMinimumSize(320, 240) self.cameraLabel.setMaximumSize(320, 240) self.cameraView = QCameraViewfinder() self.cameraView.setMaximumSize(320,240) self.cameraView.setMinimumSize(320,240) self.cameraView.hide() hlayout2.addWidget(self.cameraLabel) hlayout2.addWidget(self.cameraView) hlayout2.addItem(QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) vlayout2.addLayout(hlayout2) centerLayout.addWidget(groupBox) centerLayout.addItem(QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) vlayout.addLayout(centerLayout) vlayout.addItem(QSpacerItem(20, 40, QSizePolicy.Preferred, QSizePolicy.Preferred)) comboBox.currentIndexChanged.connect(self.avatarSelect) self.buttonCam.clicked.connect(self.buttonCamChanged) self.buttonReplay.clicked.connect(self.buttonReplayChanged) self.userAvatar = None def avatarSelect(self, index): if index == 0: if self.camera != None: self.camera.stop() self.buttonReplay.hide() self.buttonCam.hide() self.cameraView.hide() self.cameraLabel.show() elif index == 1: if self.camera != None: self.camera.stop() self.userAvatar = None self.buttonReplay.hide() self.buttonCam.hide() self.cameraView.hide() self.cameraLabel.show() file_url, file_type = QFileDialog.getOpenFileName(self, self.tr("Choose Avatar"), QDir.homePath(), "Image (*.png *.jpg)") if file_url != "": p = QPixmap(file_url) self.cameraLabel.setPixmap(p) self.userAvatar = file_url elif index == 2: self.userAvatar = None self.cameraLabel.hide() self.cameraView.show() self.camera.setViewfinder(self.cameraView) self.camera.start() self.buttonCam.setVisible(True) self.buttonReplay.hide() def buttonCamChanged(self): self.buttonCam.hide() self.buttonReplay.show() self.camera.searchAndLock() self.cameraImageCapture.capture("/tmp/avatar.png") self.camera.unlock() self.userAvatar = "/tmp/avatar.png" def buttonReplayChanged(self): self.userAvatar = None self.buttonReplay.hide() self.buttonCam.show() self.camera.start() self.cameraLabel.hide() self.cameraView.show() def imageCapture(self, id, preview): pixmap = QPixmap.fromImage(preview) self.camera.stop() self.cameraView.hide() self.cameraLabel.show() self.cameraLabel.setPixmap(pixmap) def execute(self): if self.userAvatar: if os.path.exists(os.path.join(os.environ["HOME"], ".face.icon")): os.remove(os.path.join(os.environ["HOME"], ".face.icon")) shutil.copy(self.userAvatar, os.path.join(os.environ["HOME"], ".face.icon"))
class AvatarWidget(QWizardPage): def __init__(self, parent=None): super().__init__(parent) self.setSubTitle(self.tr("<h2>Create Your Avatar</h2>")) vlayout = QVBoxLayout(self) labelLayout = QHBoxLayout() labelImage = QLabel() labelImage.setPixmap( QPixmap(":/data/images/preferences-desktop-personal.png")) labelImage.setMaximumSize(64, 64) labelLayout.addWidget(labelImage) label = QLabel(self) label.setWordWrap(True) label.setText( self. tr("<p>This screen helps you set your <strong>user picture</strong>. You can either choose an image from a \ file or you can capture an image from your camera. Select an option from the <strong>options</strong> menu.</p>" )) labelLayout.addWidget(label) vlayout.addLayout(labelLayout) vlayout.addItem( QSpacerItem(20, 40, QSizePolicy.Preferred, QSizePolicy.Preferred)) centerLayout = QHBoxLayout() centerLayout.addItem( QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) groupBox = QGroupBox() groupBox.setMaximumWidth(500) vlayout2 = QVBoxLayout(groupBox) hlayout = QHBoxLayout() comboBox = QComboBox() comboBox.setMinimumWidth(250) comboBox.addItems([self.tr("Options"), self.tr("Choose an image...")]) #Camera control self.cameraInfo = None self.camera = None self.cameraImageCapture = None cameras = QCameraInfo.availableCameras() if len(cameras): self.cameraInfo = cameras[0] comboBox.addItem(self.tr("Camera ") + self.cameraInfo.deviceName()) self.camera = QCamera(self.cameraInfo) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.cameraImageCapture = QCameraImageCapture(self.camera) self.imageProcessing = self.camera.imageProcessing() self.imageProcessing.setWhiteBalanceMode( QCameraImageProcessing.WhiteBalanceSunlight) self.imageProcessing.setContrast(1) self.imageProcessing.setSaturation(1) self.imageProcessing.setSharpeningLevel(1) self.imageProcessing.setDenoisingLevel(1) #self.imageProcessing.setColorFilter(QCameraImageProcessing.ColorFilterWhiteboard) #FIXME Qt5.5 self.cameraImageCapture.imageCaptured.connect(self.imageCapture) self.buttonCam = QPushButton() self.buttonCam.setText(self.tr("Capture")) self.buttonCam.setIcon(QIcon(":/data/images/webcamreceive.png")) self.buttonCam.setVisible(False) self.buttonReplay = QPushButton() self.buttonReplay.setText(self.tr("Recapture")) self.buttonReplay.setIcon(QIcon(":/data/images/view-refresh.png")) self.buttonReplay.setVisible(False) hlayout.addWidget(comboBox) hlayout.addItem( QSpacerItem(300, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) hlayout.addWidget(self.buttonCam) hlayout.addWidget(self.buttonReplay) vlayout2.addLayout(hlayout) hlayout2 = QHBoxLayout() hlayout2.addItem( QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) self.cameraLabel = QLabel() self.cameraLabel.setScaledContents(True) self.cameraLabel.setStyleSheet("background-color: black;") self.cameraLabel.setMinimumSize(320, 240) self.cameraLabel.setMaximumSize(320, 240) self.cameraView = QCameraViewfinder() self.cameraView.setMaximumSize(320, 240) self.cameraView.setMinimumSize(320, 240) self.cameraView.hide() hlayout2.addWidget(self.cameraLabel) hlayout2.addWidget(self.cameraView) hlayout2.addItem( QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) vlayout2.addLayout(hlayout2) centerLayout.addWidget(groupBox) centerLayout.addItem( QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Preferred)) vlayout.addLayout(centerLayout) vlayout.addItem( QSpacerItem(20, 40, QSizePolicy.Preferred, QSizePolicy.Preferred)) comboBox.currentIndexChanged.connect(self.avatarSelect) self.buttonCam.clicked.connect(self.buttonCamChanged) self.buttonReplay.clicked.connect(self.buttonReplayChanged) self.userAvatar = None def avatarSelect(self, index): if index == 0: if self.camera != None: self.camera.stop() self.buttonReplay.hide() self.buttonCam.hide() self.cameraView.hide() self.cameraLabel.show() elif index == 1: if self.camera != None: self.camera.stop() self.userAvatar = None self.buttonReplay.hide() self.buttonCam.hide() self.cameraView.hide() self.cameraLabel.show() file_url, file_type = QFileDialog.getOpenFileName( self, self.tr("Choose Avatar"), QDir.homePath(), "Image (*.png *.jpg)") if file_url != "": p = QPixmap(file_url) self.cameraLabel.setPixmap(p) self.userAvatar = file_url elif index == 2: self.userAvatar = None self.cameraLabel.hide() self.cameraView.show() self.camera.setViewfinder(self.cameraView) self.camera.start() self.buttonCam.setVisible(True) self.buttonReplay.hide() def buttonCamChanged(self): self.buttonCam.hide() self.buttonReplay.show() self.camera.searchAndLock() self.cameraImageCapture.capture("/tmp/avatar.png") self.camera.unlock() self.userAvatar = "/tmp/avatar.png" def buttonReplayChanged(self): self.userAvatar = None self.buttonReplay.hide() self.buttonCam.show() self.camera.start() self.cameraLabel.hide() self.cameraView.show() def imageCapture(self, id, preview): pixmap = QPixmap.fromImage(preview) self.camera.stop() self.cameraView.hide() self.cameraLabel.show() self.cameraLabel.setPixmap(pixmap) def execute(self): if self.userAvatar: if os.path.exists(os.path.join(os.environ["HOME"], ".face.icon")): os.remove(os.path.join(os.environ["HOME"], ".face.icon")) shutil.copy(self.userAvatar, os.path.join(os.environ["HOME"], ".face.icon"))
class UserWidget(QWidget): host_name = None full_name = None user_name = None passwd = None repasswd = None rpasswd = None rrepasswd = None def __init__(self, parent=None): super().__init__() self.parent = parent self.setWindowTitle(self.tr("User Creation")) self.setStyleSheet("QToolButton {border: none;}") self.setLayout(QHBoxLayout()) left_layout = QVBoxLayout() self.layout().addLayout(left_layout) name_label = QLabel() name_label.setText(self.tr("What is your name?")) left_layout.addWidget(name_label) name_layout = QHBoxLayout() left_layout.addLayout(name_layout) self.name_line = QLineEdit() self.name_line.setPlaceholderText(self.tr("Fullname")) self.name_line.setFixedWidth(450) name_layout.addWidget(self.name_line) self.name_icon = QLabel() self.name_icon.setFixedSize(24, 24) self.name_icon.setScaledContents(True) name_layout.addWidget(self.name_icon) user_label = QLabel() user_label.setText(self.tr("Username to sign in?")) left_layout.addWidget(user_label) user_layout = QHBoxLayout() left_layout.addLayout(user_layout) self.user_line = QLineEdit() self.user_line.setPlaceholderText(self.tr("Username")) user_layout.addWidget(self.user_line) self.user_icon = QLabel() self.user_icon.setScaledContents(True) self.user_icon.setFixedSize(24, 24) user_layout.addWidget(self.user_icon) host_label = QLabel() host_label.setText(self.tr("What should this computer be named?")) left_layout.addWidget(host_label) host_layout = QHBoxLayout() left_layout.addLayout(host_layout) self.host_line = QLineEdit() self.host_line.setPlaceholderText(self.tr("Hostname")) host_layout.addWidget(self.host_line) self.host_icon = QLabel() self.host_icon.setFixedSize(24, 24) self.host_icon.setScaledContents(True) host_layout.addWidget(self.host_icon) pass_label = QLabel() pass_label.setText(self.tr("Enter your user password.")) left_layout.addWidget(pass_label) pass_layout = QHBoxLayout() left_layout.addLayout(pass_layout) self.pass_line = QLineEdit() self.pass_line.setEchoMode(QLineEdit.Password) self.pass_line.setPlaceholderText(self.tr("Password")) pass_layout.addWidget(self.pass_line) self.pass_icon = QLabel() self.pass_icon.setScaledContents(True) self.pass_icon.setFixedSize(24, 24) pass_layout.addWidget(self.pass_icon) repass_layout = QHBoxLayout() left_layout.addLayout(repass_layout) self.repass_line = QLineEdit() self.repass_line.setEchoMode(QLineEdit.Password) self.repass_line.setPlaceholderText(self.tr("Repassword")) repass_layout.addWidget(self.repass_line) self.repass_icon = QLabel() self.repass_icon.setScaledContents(True) self.repass_icon.setFixedSize(24, 24) repass_layout.addWidget(self.repass_icon) self.auto_box = QCheckBox() self.auto_box.setChecked(True) self.auto_box.setText(self.tr("Sign in without password.")) left_layout.addWidget(self.auto_box) self.root_box = QCheckBox() self.root_box.setChecked(True) self.root_box.setText( self. tr("Should the administrator and the user use the same password?")) left_layout.addWidget(self.root_box) rpass_layout = QHBoxLayout() left_layout.addLayout(rpass_layout) self.spacer = QSpacerItem(0, 40, QSizePolicy.Maximum, QSizePolicy.Expanding) rpass_layout.addSpacerItem(self.spacer) self.rpass_line = QLineEdit() self.rpass_line.hide() self.rpass_line.setEchoMode(QLineEdit.Password) self.rpass_line.setPlaceholderText(self.tr("Root Password")) rpass_layout.addWidget(self.rpass_line) self.rpass_icon = QLabel() self.rpass_icon.hide() self.rpass_icon.setScaledContents(True) self.rpass_icon.setFixedSize(24, 24) rpass_layout.addWidget(self.rpass_icon) rrepass_layout = QHBoxLayout() left_layout.addLayout(rrepass_layout) self.rrepass_line = QLineEdit() self.rrepass_line.hide() self.rrepass_line.setEchoMode(QLineEdit.Password) self.rrepass_line.setPlaceholderText(self.tr("Root Repassword")) rrepass_layout.addWidget(self.rrepass_line) self.rrepass_icon = QLabel() self.rrepass_icon.hide() self.rrepass_icon.setScaledContents(True) self.rrepass_icon.setFixedSize(24, 24) rrepass_layout.addWidget(self.rrepass_icon) self.layout().addSpacerItem( QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Expanding)) right_layout = QVBoxLayout() self.layout().addLayout(right_layout) ######## Camera self.cameras = QCameraInfo.availableCameras() print(self.cameras) self.photo_label = QLabel() self.photo_label.setFixedSize(192, 192) self.photo_label.setScaledContents(True) self.photo_label.setPixmap(QPixmap(":/images/user-avatar.svg")) self.parent.lilii_settings["avatar"] = None right_layout.addWidget(self.photo_label) if len(self.cameras): self.photo_label.hide() self.photo_widget = QCameraViewfinder() self.photo_widget.setFixedSize(192 / 4 * 5, 192) right_layout.addWidget(self.photo_widget) self.camera = QCamera(self.cameras[0]) self.camera.setViewfinder(self.photo_widget) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.image_capture = QCameraImageCapture(self.camera) self.image_capture.imageSaved.connect(self.imageCapture) button_layout = QHBoxLayout() right_layout.addLayout(button_layout) self.take_photo = CustomToolButton() self.take_photo.setEnabled(len(self.cameras)) self.take_photo.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.take_photo.setText(self.tr("Take Photo")) self.take_photo.setIconSize(QSize(32, 32)) self.take_photo.setIcon(QIcon(":/images/camera.svg")) self.take_photo.setEnterIcon(QIcon(":/images/camera-red.svg")) self.take_photo.setLeaveIcon(QIcon(":/images/camera.svg")) button_layout.addWidget(self.take_photo) self.retake_photo = CustomToolButton() self.retake_photo.hide() self.retake_photo.setEnabled(len(self.cameras)) self.retake_photo.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.retake_photo.setText(self.tr("Retake Photo")) self.retake_photo.setIconSize(QSize(32, 32)) self.retake_photo.setIcon(QIcon(":/images/camera.svg")) self.retake_photo.setEnterIcon(QIcon(":/images/camera-red.svg")) self.retake_photo.setLeaveIcon(QIcon(":/images/camera.svg")) button_layout.addWidget(self.retake_photo) select_photo = CustomToolButton() select_photo.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) select_photo.setText(self.tr("Select Photo")) select_photo.setIconSize(QSize(32, 32)) select_photo.setIcon(QIcon(":/images/users.svg")) select_photo.setLeaveIcon(QIcon(":/images/users.svg")) select_photo.setEnterIcon(QIcon(":/images/users-red.svg")) button_layout.addWidget(select_photo) self.layout().addSpacerItem( QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Expanding)) self.parent.lilii_settings["auto_login"] = self.auto_box.isChecked() self.parent.lilii_settings["root_user"] = self.root_box.isChecked() self.auto_box.toggled.connect(self.autoControl) self.root_box.toggled.connect(self.rootControl) self.host_line.textChanged.connect(self.hostnameControl) self.name_line.textChanged.connect(self.fullnameControl) self.name_line.textChanged.connect(self.fullnameToUsername) self.user_line.textChanged.connect(self.usernameControl) self.pass_line.textChanged.connect(self.passwordControl) self.repass_line.textChanged.connect(self.repasswordControl) self.rpass_line.textChanged.connect(self.rpasswordControl) self.rrepass_line.textChanged.connect(self.rrepasswordControl) self.root_box.toggled.connect(self.lineEditsControl) self.host_line.textChanged.connect(self.lineEditsControl) self.name_line.textChanged.connect(self.lineEditsControl) self.user_line.textChanged.connect(self.lineEditsControl) self.pass_line.textChanged.connect(self.lineEditsControl) self.repass_line.textChanged.connect(self.lineEditsControl) self.rpass_line.textChanged.connect(self.lineEditsControl) self.rrepass_line.textChanged.connect(self.lineEditsControl) select_photo.clicked.connect(self.selectPhoto) self.take_photo.clicked.connect(self.takePhoto) self.retake_photo.clicked.connect(self.retakePhoto) def showEvent(self, event): self.lineEditsControl() if len(self.cameras): self.retakePhoto() def autoControl(self): self.parent.lilii_settings["auto_login"] = self.auto_box.isChecked() def rootControl(self): self.parent.lilii_settings["root_user"] = self.root_box.isChecked() if not self.root_box.isChecked(): self.rpass_line.show() self.rpass_icon.show() self.rrepass_line.show() self.rrepass_icon.show() else: self.rpass_line.hide() self.rpass_icon.hide() self.rrepass_line.hide() self.rrepass_icon.hide() def hostnameControl(self, hostname): if hostname.isalnum() and len(hostname) > 3: self.host_name = True self.host_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.host_name = False self.host_icon.setPixmap(QPixmap(":/images/xxx.svg")) def fullnameControl(self, fullname): if len(fullname) > 2: self.full_name = True self.name_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.full_name = False self.name_icon.setPixmap(QPixmap(":/images/xxx.svg")) def usernameControl(self, username): if username.isalnum() and len(username) > 3: self.user_name = True self.user_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.user_name = False self.user_icon.setPixmap(QPixmap(":/images/xxx.svg")) def fullnameToUsername(self, text): self.user_line.setText(text.lower().replace(" ", "")) def passwordControl(self, passwd): if len(passwd) > 5: self.passwd = True self.pass_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.passwd = False self.pass_icon.setPixmap(QPixmap(":/images/xxx.svg")) if passwd == self.repass_line.text(): self.repasswd = True self.repass_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.repasswd = False self.repass_icon.setPixmap(QPixmap(":/images/xxx.svg")) def repasswordControl(self, repasswd): if repasswd == self.pass_line.text(): self.repasswd = True self.repass_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.repasswd = False self.repass_icon.setPixmap(QPixmap(":/images/xxx.svg")) def rpasswordControl(self, passwd): if len(passwd) > 5: self.rpasswd = True self.rpass_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.rpasswd = False self.rpass_icon.setPixmap(QPixmap(":/images/xxx.svg")) if passwd == self.rrepass_line.text(): self.rrepasswd = True self.rrepass_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.rrepasswd = False self.rrepass_icon.setPixmap(QPixmap(":/images/xxx.svg")) def rrepasswordControl(self, repasswd): if repasswd == self.rpass_line.text(): self.rrepasswd = True self.rrepass_icon.setPixmap(QPixmap(":/images/apply.svg")) else: self.rrepasswd = False self.rrepass_icon.setPixmap(QPixmap(":/images/xxx.svg")) applyPage = pyqtSignal(bool) def lineEditsControl(self): if not self.root_box.isChecked(): if self.host_name and self.full_name and self.user_name and self.passwd and self.repasswd and self.rpasswd \ and self.rrepasswd: self.parent.lilii_settings["root_pass"] = self.rpass_line.text( ) self.applyPage.emit(True) self.parent.lilii_settings["fullname"] = self.name_line.text() self.parent.lilii_settings["username"] = self.user_line.text() self.parent.lilii_settings["password"] = self.pass_line.text() self.parent.lilii_settings["hostname"] = self.host_line.text() else: self.applyPage.emit(False) elif self.host_name and self.full_name and self.user_name and self.passwd and self.repasswd: self.parent.lilii_settings["fullname"] = self.name_line.text() self.parent.lilii_settings["username"] = self.user_line.text() self.parent.lilii_settings["password"] = self.pass_line.text() self.parent.lilii_settings["hostname"] = self.host_line.text() self.applyPage.emit(True) else: self.applyPage.emit(False) def selectPhoto(self): avatar_path = QDir.homePath() + "/.face.icon" file_path = QFileDialog.getOpenFileName(self, self.tr("Choose a user icon"), QDir.homePath(), "Image (*.png *.jpg)") if file_path[0]: image = Image.open(file_path[0]) crop_image = image.crop(imageCrop(image)) new_image = avatarCreate(crop_image) new_image.save(avatar_path, "PNG") self.photo_label.setPixmap(QPixmap(avatar_path)) self.parent.lilii_settings["avatar"] = True def takePhoto(self): self.take_photo.hide() self.retake_photo.show() self.image_capture.capture("/tmp/image") self.camera.stop() self.photo_label.show() self.photo_widget.hide() def retakePhoto(self): self.retake_photo.hide() self.take_photo.show() self.camera.start() self.photo_widget.show() self.photo_label.hide() def imageCapture(self, id, image_file): path = QDir.homePath() + "/.face.icon" im = Image.open(image_file) crop_image = im.crop(imageCrop(im)) new_image = avatarCreate(crop_image) new_image.save(path, "PNG") self.photo_label.setPixmap(QPixmap(path)) self.parent.lilii_settings["avatar"] = True
class UiMainWindow(QWidget): """Main UI window of the application. Attributes: ---------- window_width: int Width of the window window_height: int Height of the window button_width: int Width of buttons button_height: int Height of buttons dist: int Distance to the edge of Widgets(Window/Button/Label...) model_selected: bool Shows whether a model is selected or not """ window_height = 650 window_width = 800 button_width = 180 button_height = 50 dist = 30 model_selected = False textbox_height = 25 small_button_width = 100 small_button_height = 30 debug_height = 200 debug_mode = False accepted_download = False current_city = "" def __init__(self, parent) -> None: super().__init__(parent) main_window.setObjectName("main_window") main_window.resize(self.window_width, self.window_height) self.centralwidget = QWidget(main_window) self.centralwidget.setObjectName("centralwidget") self.detector = Detection() self.Box_Stadt = QComboBox(self.centralwidget) self.Box_Stadt.setGeometry( QRect(self.dist, self.dist, self.button_width, self.button_height)) self.Box_Stadt.setObjectName("Box_Stadt") self.Box_Stadt.activated.connect(self.on_dropdown_selected) # dynamic city updates supported_cities_updater = Thread(target=update_dropdown, daemon=True, args=(self.Box_Stadt, )) supported_cities_updater.start() self.Text_City = QLineEdit(self.centralwidget) self.Text_City.setGeometry( QRect(self.dist + self.dist + self.button_width, self.dist + 10, self.button_width, self.textbox_height)) self.Text_City.setObjectName("Text_City") self.Text_City.setToolTip( 'Enter a city you wish to detect sights in that you cannot find in the dropdown on the left after updating.' ) self.Button_City = QPushButton(self.centralwidget) self.Button_City.setGeometry( QRect( int(2.3 * self.dist) + self.button_width + self.button_width, self.dist + 8, self.small_button_width, self.small_button_height)) self.Button_City.setObjectName("Button_City") self.Button_City.clicked.connect(self.request_city) self.Button_Detection = QPushButton(self.centralwidget) self.Button_Detection.setGeometry( QRect( self.window_width - (self.dist + self.button_width), self.window_height - (self.dist + self.button_height + 20), self.button_width, self.button_height, )) self.Button_Detection.setObjectName("Button_Detection") self.Button_Detection.clicked.connect(self.detect_sights) self.Button_Bild = QPushButton(self.centralwidget) self.Button_Bild.setGeometry( QRect( self.dist, self.window_height - (self.dist + self.button_height + 20), self.button_width, self.button_height, )) self.Button_Bild.setObjectName("Button_Bild") self.Button_Bild.clicked.connect(lambda: self.camera_viewfinder.hide()) self.Button_Bild.clicked.connect( lambda: self.Box_Camera_selector.setCurrentIndex(0)) self.Button_Bild.clicked.connect( lambda: self.stacked_widget.setCurrentIndex(0)) self.Button_Bild.clicked.connect(lambda: self.Label_Bild.show()) self.Button_Bild.clicked.connect(self.dragdrop) self.available_cameras = QCameraInfo.availableCameras() self.Box_Camera_selector = QComboBox(self.centralwidget) self.Box_Camera_selector.setGeometry( QRect( self.window_width - (self.dist + self.button_width), self.dist, self.button_width, self.button_height, )) self.Box_Camera_selector.setObjectName("Box_Camera_selector") self.Box_Camera_selector.addItem("") # self.Box_Camera_selector.addItems([camera.description() for camera in self.available_cameras]) self.Box_Camera_selector.addItems([ "Camera " + str(i) + ": " + str(self.available_cameras[i].description()) for i in range(len(self.available_cameras)) ]) self.Box_Camera_selector.currentIndexChanged.connect( self.select_camera) self.stacked_widget = QStackedWidget(self.centralwidget) label_height = (self.window_height - self.dist - self.button_height - self.dist) - (self.dist + self.button_height + self.dist) label_start_y = self.dist + self.button_height + self.dist self.stacked_widget.setGeometry( QRect( self.dist, label_start_y, self.window_width - (self.dist * 2), label_height, )) self.camera_viewfinder = QCameraViewfinder() self.Label_Bild = ImageLabel(self) self.Label_Bild.setGeometry( QRect(0, 0, self.window_width - (self.dist * 2), label_height)) self.checkBoxImprove = QCheckBox( "Help improving SightScan's detection quality", self.centralwidget) self.checkBoxImprove.setObjectName(u"improvement") self.checkBoxImprove.setGeometry(QRect(self.dist, 5, 350, 20)) self.checkBoxImprove.setChecked(False) self.checkBoxImprove.stateChanged.connect(self.set_improve_quality_var) self.checkBox = QCheckBox("Debug", self.centralwidget) self.checkBox.setObjectName(u"checkBox") self.checkBox.setGeometry( QRect(self.window_width - (self.dist + 50), self.window_height - (self.dist + 20), 70, 20)) self.checkBox.setChecked(False) self.checkBox.stateChanged.connect(self.debug_click) # Setup logging fn = "logs/" + datetime.now().strftime( '%d_%m_%Y__%H_%M_%S') + 'log.log' if not os.path.exists("logs"): os.mkdir("logs") f = '%(asctime)s :: %(levelname)s :: %(filename)s :: %(funcName)s :: %(lineno)d :: %(message)s' self.textDebug = QTextEditLogger(self.centralwidget) self.textDebug.setFormatter(logging.Formatter(f)) logging.basicConfig(filename=fn, format=f, level=logging.DEBUG) logging.getLogger().addHandler(self.textDebug) # Log Text Box in GUI self.textDebug.widget.setObjectName(u"textEdit") self.textDebug.widget.setEnabled(False) self.textDebug.widget.setGeometry( QRect(self.dist, self.window_height, self.window_width - 2 * self.dist, self.debug_height - self.dist)) size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.textDebug.widget.sizePolicy().hasHeightForWidth()) self.textDebug.widget.setSizePolicy(size_policy) self.textDebug.widget.setReadOnly(True) self.stacked_widget.addWidget(self.Label_Bild) self.stacked_widget.addWidget(self.camera_viewfinder) main_window.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(main_window) self.menubar.setGeometry(QRect(0, 0, 678, 21)) self.menubar.setObjectName("menubar") main_window.setMenuBar(self.menubar) self.statusbar = QStatusBar(main_window) self.statusbar.setObjectName("statusbar") main_window.setStatusBar(self.statusbar) main_window.setWindowIcon(QIcon(logo_without_text)) self.retranslateUi(main_window) QMetaObject.connectSlotsByName(main_window) def set_improve_quality_var(self): self.improve_checkbox_enabled = self.checkBoxImprove.isChecked() def retranslateUi(self, main_window: QMainWindow) -> None: """Set the text initially for all items. Parameters ---------- main_window: QMainWindow The instance of the prepared application window """ _translate = QCoreApplication.translate main_window.setWindowTitle(_translate(WINDOW, "SightScan")) self.Box_Stadt.addItems(['Choose City'] + initialize_cities()) self.Box_Camera_selector.setItemText( 0, _translate(WINDOW, "Choose Webcam")) self.Button_Detection.setText(_translate(WINDOW, START)) self.Button_Bild.setText(_translate(WINDOW, ENABLE)) self.Button_City.setText(_translate(WINDOW, "Add City")) def on_dropdown_selected(self) -> None: """Shows a pop-up for confirming the download of the selected city.""" city_pretty_print = self.Box_Stadt.currentText() city = self.Box_Stadt.currentText().replace(' ', '_').upper() if city != "CHOOSE_CITY": self.current_city = self.Box_Stadt.currentText() # if no connection to dos if get_supported_cities() == []: latest_version = "couldn't get the latest version" downloaded_version = "couldn't get the downloaded version" print('no connection to dos') # if connection to dos else: downloaded_version = -1 # initialization Path("weights").mkdir(mode=0o700, exist_ok=True) if not os.path.exists("weights/versions.txt"): with open('weights/versions.txt', 'w'): # creating a version file pass with open("weights/versions.txt", "r") as file: for line in file: elements = line.split("=") if elements[0].upper() == city: downloaded_version = int(elements[1]) break latest_version = get_dwh_model_version(city) if downloaded_version == -1: msg = QMessageBox() msg.setWindowTitle("Download City") msg.setWindowIcon(QIcon(logo_without_text)) msg.setText("Do you want to download " + city_pretty_print + "?") msg.setIcon(QMessageBox.Question) msg.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok) msg.setDefaultButton(QMessageBox.Ok) msg.setInformativeText("When downloaded, sights of " + city_pretty_print + " can be detected.") msg.buttonClicked.connect(self.handover_city) msg.exec_() elif latest_version > downloaded_version: update_msg = QMessageBox() update_msg.setWindowTitle("Update available") update_msg.setWindowIcon(QIcon(logo_without_text)) update_msg.setText( "Do you want to download an update for " + city + "?") update_msg.setIcon(QMessageBox.Question) update_msg.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok) update_msg.setDefaultButton(QMessageBox.Ok) update_msg.setInformativeText( "Updated cities can detect sights faster and more accurately. If you choose not to download, the " + "detection will still work.") update_msg.buttonClicked.connect(self.handover_city) update_msg.exec_() if self.accepted_download is True or latest_version == downloaded_version: self.accepted_download = False self.show_download_result() self.model_selected = True else: self.model_selected = False def handover_city(self, button) -> None: """Starts the download of the pre-trained model of the selected city. Parameters ---------- button: Pushed button inside the popup. """ if "OK" in button.text().upper(): city = self.Box_Stadt.currentText().replace(' ', '_').upper() self.model_selected = True model = get_downloaded_model(city) if model is not None: with open("weights/" + city + ".pt", "wb+") as file: file.write(model) self.accepted_download = True elif "CANCEL" in button.text().upper(): self.Box_Stadt.setCurrentIndex(0) def detect_sights(self) -> None: """Starts detection for the dropped image or shown webcam video with the downloaded model and displays the results in the label.""" city = self.Box_Stadt.currentText().replace(' ', '_').upper() print("Detection Status: " + str(self.detector.detection)) if self.model_selected is False: self.show_missing_model_popup() else: # start drag&drop image detection if self.stacked_widget.currentIndex() == 0 and self.Button_Bild.text() == DISABLE and \ self.Label_Bild.image != logo_with_text: print(f"Starting detection of {self.Label_Bild.image}") wipe_prediction_input_images(INPUT_PREDICTION_DIR) shutil.copy2(self.Label_Bild.image, INPUT_PREDICTION_DIR) self.detector.enable_detection() self.detector.detect(self, weights='weights/' + city + '.pt', debug=self.debug_mode) # stop video detection elif self.stacked_widget.currentIndex( ) == 0 and self.Button_Detection.text() == STOP: self.stop_video_detection() time.sleep(2) self.reactivate_cam() # if webcam activated elif self.stacked_widget.currentIndex() == 1: if self.Button_Detection.text() == START: self.Button_Detection.setText( QCoreApplication.translate(WINDOW, STOP)) self.Label_Bild.setStyleSheet(""" """) print("Video Detection Started") self.prep_video_detection() source = self.Box_Camera_selector.currentIndex() self.detector.enable_detection() self.detection_thread = Thread(target=self.detector.detect, args=(self, ), kwargs={ 'weights': 'weights/' + city + '.pt', 'source': str(source - 1), 'image_size': 704, 'debug': self.debug_mode }) self.detection_thread.start() else: print("Drop a File or select a Webcam!") def show_missing_model_popup(self) -> None: # Show Pop Up to choose a city emsg = QMessageBox() emsg.setWindowTitle("No city chosen") emsg.setWindowIcon(QIcon(logo_without_text)) emsg.setText( "You need to choose a city before the detection can start.") emsg.setIcon(QMessageBox.Warning) emsg.setStandardButtons(QMessageBox.Ok) emsg.setDefaultButton(QMessageBox.Ok) emsg.exec_() def show_download_result(self) -> None: # city_pretty_print = self.Box_Stadt.currentText() self.model_selected = True newest_vers_msg = QMessageBox() newest_vers_msg.setWindowTitle("Ready for Detection!") newest_vers_msg.setWindowIcon(QIcon(logo_without_text)) newest_vers_msg.setText("You can start detecting sights in " + self.current_city + "!") newest_vers_msg.setStandardButtons(QMessageBox.Ok) newest_vers_msg.setDefaultButton(QMessageBox.Ok) newest_vers_msg.exec_() def request_city(self) -> None: # Send entered city to dwh and show confirmation popup if the city name is known city_input = self.Text_City.text() city_request = city_input.upper() if len(filter_city(city_input)) == 1: send_city_request(city_request) cmsg = QMessageBox() cmsg.setWindowTitle("Request confirmed") cmsg.setWindowIcon(QIcon(logo_without_text)) cmsg.setText("Your request to add support for " + city_input + " has been sent to our backend.") cmsg.setStandardButtons(QMessageBox.Ok) cmsg.setDefaultButton(QMessageBox.Ok) cmsg.exec_() else: cmsg = QMessageBox() cmsg.setWindowTitle("Unknown city name") cmsg.setWindowIcon(QIcon(logo_without_text)) cmsg.setText( "The typed city name is not known. Please check the spelling.") cmsg.setIcon(QMessageBox.Warning) cmsg.setStandardButtons(QMessageBox.Ok) cmsg.setDefaultButton(QMessageBox.Ok) cmsg.exec_() def dragdrop(self) -> None: """Enables / disables Drag&Drop of images.""" if self.Button_Bild.text() == ENABLE: # stop video detection if active if self.Button_Detection.text() == STOP: self.Button_Detection.setText( QCoreApplication.translate(WINDOW, START)) self.detector.disable_detection() self.Label_Bild.setAcceptDrops(True) self.Label_Bild.setText("\n\n Drop Image here \n\n") self.Label_Bild.setStyleSheet(""" QLabel{ border: 4px dashed #aaa } """) self.Button_Bild.setText( QCoreApplication.translate(WINDOW, DISABLE)) elif self.Button_Bild.text() == DISABLE: self.Label_Bild.setAcceptDrops(False) self.Label_Bild.setText("") self.Label_Bild.setStyleSheet("") self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.Button_Bild.setText(QCoreApplication.translate( WINDOW, ENABLE)) def select_camera(self, i): """Starts the selected camera. If "Choose webcam" is selected, it stops the camera. Parameters ---------- i: Index of the chosen camera. """ self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) if i == 0: self.camera.stop() self.detector.disable_detection() self.Button_Detection.setText( QCoreApplication.translate(WINDOW, START)) self.stacked_widget.setCurrentIndex(0) self.camera_viewfinder.hide() self.Label_Bild.show() time.sleep(2) self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.Label_Bild.setStyleSheet(""" """) else: self.camera_viewfinder.show() self.stacked_widget.setCurrentIndex(1) self.Label_Bild.hide() self.camera = QCamera(self.available_cameras[i - 1]) self.camera.setViewfinder(self.camera_viewfinder) self.camera.error.connect( lambda: self.alert(self.camera.errorString())) self.camera.start() self.Button_Bild.setText(QCoreApplication.translate( WINDOW, ENABLE)) def prep_video_detection(self) -> None: self.camera.stop() self.camera_viewfinder.hide() self.stacked_widget.setCurrentIndex(0) self.Label_Bild.image = loading_image self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.Label_Bild.show() def stop_video_detection(self) -> None: self.Button_Detection.setText(QCoreApplication.translate( WINDOW, START)) self.detector.disable_detection() self.stacked_widget.setCurrentIndex(1) self.Label_Bild.hide() self.camera_viewfinder.show() def debug_click(self, state): self.debug_mode = bool(state) if state: main_window.resize(self.window_width, self.window_height + self.debug_height) self.textDebug.widget.setEnabled(True) else: main_window.resize(self.window_width, self.window_height) self.textDebug.widget.setEnabled(False) def reactivate_cam(self) -> None: self.Label_Bild.image = logo_with_text self.Label_Bild.setPixmap(QPixmap(self.Label_Bild.image)) self.camera.start() def close_all(self) -> None: if self.Button_Detection.text() == STOP: self.detector.disable_detection() self.stop_video_detection()