class AddUserFace(QDialog): def __init__(self, image): super(AddUserFace, self).__init__() self.setFixedSize(300, 275) self.setWindowIcon(QIcon('icons/add.png')) self.setWindowTitle('添加') self.rb_select = QRadioButton("选择", self) self.rb_select.setGeometry(70, 20, 50, 26) self.rb_select.toggled.connect(self.toggle) self.rb_new = QRadioButton('新建', self) self.rb_new.setGeometry(120, 20, 50, 26) self.rb_new.toggled.connect(self.toggle) lbl_name = QLabel('名称', self) lbl_name.setGeometry(10, 70, 50, 26) lbl_name.setAlignment(Qt.AlignCenter) users = DbHelper.query_users() self.cb_user = QComboBox(self) self.cb_user.setGeometry(70, 70, 200, 26) self.le_user = QLineEdit(self) self.le_user.setGeometry(70, 70, 200, 26) if users is not None and len(users) > 0: self.rb_select.setChecked(True) for user in users: self.cb_user.addItem(user[1], userData=user) else: self.rb_select.setDisabled(True) self.rb_new.setChecked(True) lbl_face = QLabel('人脸', self) lbl_face.setGeometry(10, 140, 50, 26) lbl_face.setAlignment(Qt.AlignCenter) self.btn_save = QPushButton(self) self.btn_save.setText('保存') self.btn_save.setGeometry(10, 234, 280, 30) self.btn_save.clicked.connect(self.save) self.cache_faces = {} self.face = None faces = HaarcascadeDetective.get_faces(image) index = 0 for face in faces: viewer_face = QPushButton(self) viewer_face.setGeometry(70 * (index + 1), 120, 60, 60) viewer_face.setIconSize(QSize(56, 56)) img = cv2.cvtColor(face, cv2.COLOR_BGR2RGB) image = QImage(img, img.shape[1], img.shape[0], img.shape[1] * 3, QImage.Format_RGB888) pix_map = QPixmap.fromImage(image) viewer_face.setIcon(QIcon(pix_map)) viewer_face.clicked.connect(self.select_face) self.cache_faces[viewer_face] = face if index == 0: self.face = face viewer_face.setStyleSheet( 'border-color: rgb(255, 0, 0);border-style: outset;border-width: 2px;' ) index += 1 if index > 3: break if index == 0: Tool.show_msg_box("未检测到人脸信息") def select_face(self): sender = self.sender() for btn in self.cache_faces: btn.setStyleSheet('border-style: none') sender.setStyleSheet( "border-color: rgb(255, 0, 0);border-style: outset;border-width: 2px;" ) self.face = self.cache_faces[btn] def toggle(self): if self.rb_new.isChecked(): self.cb_user.hide() self.le_user.show() elif self.rb_select.isChecked(): self.le_user.hide() self.cb_user.show() def save(self): if self.face is None: return self.btn_save.setDisabled(True) if self.rb_new.isChecked(): user_name = self.le_user.text().strip(' ') if not user_name.replace(' ', '').encode("utf-8").isalpha(): Tool.show_msg_box('只支持英文字母和空格~') self.le_name.setFocus() return user_id = DbHelper.insert_user(user_name) else: user_id = self.cb_user.currentData()[0] if not os.path.exists("faces"): os.mkdir("faces") if not os.path.exists('faces/{}'.format(user_id)): os.mkdir('faces/{}'.format(user_id)) face = 'faces/{}/{}.png'.format(user_id, time.time()) cv2.imwrite(face, self.face) self.close()
class UserSelect(QWidget): def __init__(self, kernel, parent=None): super(UserSelect, self).__init__(parent) self.kernel = kernel self.parent = parent self.initUI() def initUI(self): self.createElements() self.createLayout() self.createActions() self.hideNewUserForm() self.hideLoginForm() def createElements(self): self.userButtons = [ UserTile(u, self) for u in self.kernel.getAllUsers() ] for b, u in zip(self.userButtons, self.kernel.getAllUsers()): b.setProfilePicture(self.kernel.getUsersDir() + u + '/profile/profile_pic.png') b.createLayout() self.newUserButton = QPushButton('New User') self.nevermindButton = QPushButton("Nevermind") self.newUserNameField = QLineEdit("Username") self.newUserPasswordField = QLineEdit("Password") self.newUserPasswordField.setEchoMode(QLineEdit.Password) self.newUserConfirmPasswordField = QLineEdit("Confirm Password") self.newUserConfirmPasswordField.setEchoMode(QLineEdit.Password) self.submitNewUserButton = QPushButton('submit') self.newUserNameErrorLabel = QLabel('') self.newPasswordErrorLabel = QLabel('') self.existingUserLoginField = QLineEdit('Password') self.existingUserLoginField.setEchoMode(QLineEdit.Password) self.existingUserLoginButton = QPushButton('Login') self.existingUserLoginErrorLabel = QLabel('') self.selectedUser = None def createLayout(self): self.existingUsersLayout = QHBoxLayout() self.existingUsersLayout.addStretch() for ub in self.userButtons: ub.resize(100, 120) self.existingUsersLayout.addWidget(ub) self.existingUsersLayout.addStretch() self.formLayout = QVBoxLayout() self.formLayout.addStretch() self.formLayout.addWidget(self.newUserButton) self.formLayout.addWidget(self.nevermindButton) self.formLayout.addWidget(self.newUserNameField) self.formLayout.addWidget(self.newUserNameErrorLabel) self.formLayout.addWidget(self.newUserPasswordField) self.formLayout.addWidget(self.newUserConfirmPasswordField) self.formLayout.addWidget(self.newPasswordErrorLabel) self.formLayout.addWidget(self.submitNewUserButton) self.formLayout.addWidget(self.existingUserLoginField) self.formLayout.addWidget(self.existingUserLoginErrorLabel) self.formLayout.addWidget(self.existingUserLoginButton) self.formLayout.addStretch() self.lowLayout = QHBoxLayout() self.lowLayout.addStretch() self.lowLayout.addLayout(self.formLayout) self.lowLayout.addStretch() self.layout = QVBoxLayout(self) self.layout.addStretch() self.layout.addLayout(self.existingUsersLayout) self.layout.addLayout(self.lowLayout) self.layout.addStretch() def createActions(self): self.newUserButton.clicked.connect(self.revealNewUserForm) self.nevermindButton.clicked.connect(self.hideNewUserForm) self.submitNewUserButton.clicked.connect(self.submitNewUserRequest) self.existingUserLoginButton.clicked.connect(self.login) for btn in self.userButtons: btn.nameButton.clicked.connect( lambda: self.revealLoginForm(btn.nameButton.text())) def revealNewUserForm(self): self.hideLoginForm() self.newUserButton.hide() self.newUserNameField.show() self.newUserPasswordField.show() self.newUserConfirmPasswordField.show() self.submitNewUserButton.show() self.nevermindButton.show() def hideNewUserForm(self): self.newUserButton.show() self.newUserNameErrorLabel.hide() self.newPasswordErrorLabel.hide() self.newUserNameField.hide() self.newUserPasswordField.hide() self.newUserConfirmPasswordField.hide() self.submitNewUserButton.hide() self.nevermindButton.hide() def revealLoginForm(self, user): self.hideNewUserForm() self.selectedUser = user self.existingUserLoginButton.show() self.existingUserLoginErrorLabel.show() self.existingUserLoginField.show() def hideLoginForm(self): self.selectedUser = None self.existingUserLoginButton.hide() self.existingUserLoginErrorLabel.hide() self.existingUserLoginField.hide() def submitNewUserRequest(self): userName = self.newUserNameField.text() pwd = self.newUserPasswordField.text() conf_pwd = self.newUserConfirmPasswordField.text() err_msg = '' if pwd != conf_pwd: err_msg = 'Error: passwords do not match' self.newPasswordErrorLabel.setText(err_msg) self.newPasswordErrorLabel.show() else: self.newPasswordErrorLabel.hide() if self.kernel.userExists(userName): err_msg = 'Error: Username is already taken. Choose something else' self.newUserNameErrorLabel.setText(err_msg) self.newUserNameErrorLabel.show() else: self.newUserNameErrorLabel.hide() if err_msg != '': return if self.kernel.addUser(userName, pwd): self.parent.loadApplication() else: err = "Error: User Creation failed.\nPlease use your Robinhood Credentials" self.newPasswordErrorLabel.setText(err) self.newPasswordErrorLabel.show() def login(self): assert (self.selectedUser != None) pwd = self.existingUserLoginField.text() if not self.kernel.switchUser(self.selectedUser, pwd): self.existingUserLoginErrorLabel.setText(err) self.existingUserLoginErrorLabel.show() else: self.parent.loadApplication()
class DictWidget(QWidget): def __init__(self, parent=None): super().__init__() self.view = QTableView() self.model = DictModel() self.proxy_model = QSortFilterProxyModel() self.search_bar = QLineEdit() self._show_loading = False self.proxy_model.setSourceModel(self.model) self.view.setModel(self.proxy_model) self.view.setAlternatingRowColors(True) self.view.horizontalHeader().setStretchLastSection(True) self.view.setSelectionMode(QAbstractItemView.SingleSelection) self.view.setSelectionBehavior(QAbstractItemView.SelectRows) self.view.setSortingEnabled(True) self.view.verticalHeader().hide() self.search_bar.textChanged.connect( self.proxy_model.setFilterRegularExpression) self.search_bar.setVisible(False) self._show_search_action = QAction("show search bar") self._show_search_action.setCheckable(True) self._show_search_action.setShortcutContext(Qt.WidgetShortcut) self._show_search_action.setShortcut(QKeySequence.Find) self._show_search_action.triggered.connect(self._on_show_search) self._close_search_action = QAction() self._close_search_action.setShortcut(QKeySequence(Qt.Key_Escape)) self._close_search_action.setShortcutContext(Qt.WidgetShortcut) self._close_search_action.triggered.connect(self._on_close_search) self.view.addAction(self._show_search_action) self.search_bar.addAction(self._close_search_action) _layout = QVBoxLayout() _layout.addWidget(self.view) _layout.addWidget(self.search_bar) _layout.setContentsMargins(0, 0, 0, 0) self.setLayout(_layout) print("init") def set_dict(self, data: dict): self.model.set_dict(data) def _on_show_search(self): self.search_bar.setVisible(True) self.search_bar.setFocus(Qt.ShortcutFocusReason) def _on_close_search(self): self.search_bar.hide() self.search_bar.clear() self.view.setFocus(Qt.ShortcutFocusReason) def set_header_visible(self, visible=True): self.view.horizontalHeader().setVisible(visible) def clear(self): self.model.clear() def paintEvent(self, event: QPaintEvent): if self._show_loading: painter = QPainter(self) painter.drawText(self.rect(), Qt.AlignCenter, self.tr("Loading ...")) else: super().paintEvent(event) def set_loading(self, show=True): self._show_loading = True self.view.setVisible(not show) self.update()
class VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) self.setAttribute(Qt.WA_NoSystemBackground, True) self.setAcceptDrops(True) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback) self.mediaPlayer.mediaStatusChanged.connect(self.printMediaData) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setFixedWidth(70) self.lbl.setUpdatesEnabled(True) self.lbl.setStyleSheet(stylesheet(self)) self.lbl.selectionChanged.connect(lambda: self.lbl.setSelection(0, 0)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setFixedWidth(70) self.elbl.setUpdatesEnabled(True) self.elbl.setStyleSheet(stylesheet(self)) self.elbl.selectionChanged.connect( lambda: self.elbl.setSelection(0, 0)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet(stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) self.clip = QApplication.clipboard() self.process = QProcess(self) self.process.readyRead.connect(self.dataReady) self.process.finished.connect(self.playFromURL) self.myurl = "" controlLayout = QHBoxLayout() controlLayout.setContentsMargins(5, 0, 5, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.lbl) controlLayout.addWidget(self.positionSlider) controlLayout.addWidget(self.elbl) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.videoWidget) layout.addLayout(controlLayout) self.setLayout(layout) self.myinfo = "©2016\nAxel Schneider\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \ "LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \ "SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes" self.widescreen = True #### shortcuts #### self.shortcut = QShortcut(QKeySequence("q"), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence("u"), self) self.shortcut.activated.connect(self.playFromURL) self.shortcut = QShortcut(QKeySequence("y"), self) self.shortcut.activated.connect(self.getYTUrl) self.shortcut = QShortcut(QKeySequence("o"), self) self.shortcut.activated.connect(self.openFile) self.shortcut = QShortcut(QKeySequence(" "), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence("f"), self) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence("i"), self) self.shortcut.activated.connect(self.handleInfo) self.shortcut = QShortcut(QKeySequence("s"), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self) self.shortcut.activated.connect(self.volumeUp) self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self) self.shortcut.activated.connect(self.volumeDown) self.shortcut = QShortcut( QKeySequence(Qt.ShiftModifier + Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider10) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider10) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) print("QT5 Player started") print("press 'o' to open file (see context menu for more)") self.suspend_screensaver() def mouseDoubleClickEvent(self, event): self.handleFullscreen() def playFromURL(self): self.mediaPlayer.pause() self.myurl = self.clip.text() self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() print(self.myurl) def getYTUrl(self): cmd = "youtube-dl -g -f best " + self.clip.text() print("grabbing YouTube URL") self.process.start(cmd) def dataReady(self): self.myurl = str(self.process.readAll(), encoding='utf8').rstrip() ### self.myurl = self.myurl.partition("\n")[0] print(self.myurl) self.clip.setText(self.myurl) self.playFromURL() def suspend_screensaver(self): 'suspend linux screensaver' proc = subprocess.Popen( 'gsettings set org.gnome.desktop.screensaver idle-activation-enabled false', shell=True) proc.wait() def resume_screensaver(self): 'resume linux screensaver' proc = subprocess.Popen( 'gsettings set org.gnome.desktop.screensaver idle-activation-enabled true', shell=True) proc.wait() def openFile(self): fileName, _ = QFileDialog.getOpenFileName( self, "Open Movie", QDir.homePath() + "/Videos", "Media (*.webm *.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v *.3gp *.mp3 *.m4a *.wav *.ogg *.flac *.m3u *.m3u8)" ) if fileName != '': self.loadFilm(fileName) print("File loaded") def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(mtime.toString()) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) print("Error: ", self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() self.resume_screensaver() print("Goodbye ...") app.quit() def contextMenuRequested(self, point): menu = QMenu() actionFile = menu.addAction(QIcon.fromTheme("video-x-generic"), "open File (o)") actionclipboard = menu.addSeparator() actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)") actionclipboard = menu.addSeparator() actionYTurl = menu.addAction(QIcon.fromTheme("youtube"), "URL from YouTube (y)") actionclipboard = menu.addSeparator() actionToggle = menu.addAction(QIcon.fromTheme("next"), "show / hide Slider (s)") actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)") action169 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "16 : 9") action43 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "4 : 3") actionSep = menu.addSeparator() actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "Info (i)") action5 = menu.addSeparator() actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)") actionFile.triggered.connect(self.openFile) actionQuit.triggered.connect(self.handleQuit) actionFull.triggered.connect(self.handleFullscreen) actionInfo.triggered.connect(self.handleInfo) actionToggle.triggered.connect(self.toggleSlider) actionURL.triggered.connect(self.playFromURL) actionYTurl.triggered.connect(self.getYTUrl) action169.triggered.connect(self.screen169) action43.triggered.connect(self.screen43) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self, event): mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mscale = event.angleDelta().y() / 5 if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth + mscale, round((mwidth + mscale) / 1.778)) else: self.setGeometry(mleft, mtop, mwidth + mscale, round((mwidth + mscale) / 1.33)) #elif self.positionSlider.hasFocus(): # self.positionSlider.value = self.positionSlider.value + 5 def screen169(self): self.widescreen = True mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.778 self.setGeometry(mleft, mtop, mwidth, round(mwidth / mratio)) def screen43(self): self.widescreen = False mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.33 self.setGeometry(mleft, mtop, mwidth, round(mwidth / mratio)) def handleFullscreen(self): if self.windowState() & Qt.WindowFullScreen: QApplication.setOverrideCursor(Qt.ArrowCursor) self.showNormal() print("no Fullscreen") else: self.showFullScreen() QApplication.setOverrideCursor(Qt.BlankCursor) print("Fullscreen entered") def handleInfo(self): msg = QMessageBox.about(self, "QT5 Player", self.myinfo) def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.778)) else: self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.33)) def showSlider(self): self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.55)) else: self.setGeometry(mleft, mtop, mwidth, round(mwidth / 1.33)) def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60) def forwardSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000 * 60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60) def backSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000 * 60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def mousePressEvent(self, evt): self.oldPos = evt.globalPos() def mouseMoveEvent(self, evt): delta = QPoint(evt.globalPos() - self.oldPos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.oldPos = evt.globalPos() def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasText(): event.accept() else: event.ignore() def dropEvent(self, event): print("drop") if event.mimeData().hasUrls(): url = event.mimeData().urls()[0].toString() print("url = ", url) self.mediaPlayer.stop() self.mediaPlayer.setMedia(QMediaContent(QUrl(url))) self.playButton.setEnabled(True) self.mediaPlayer.play() elif event.mimeData().hasText(): mydrop = event.mimeData().text() ### YouTube url if "youtube" in mydrop: print("is YouTube", mydrop) self.clip.setText(mydrop) self.getYTUrl() else: ### normal url print("generic url = ", mydrop) self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() def loadFilm(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.mediaPlayer.play() def printMediaData(self): if self.mediaPlayer.mediaStatus() == 6: if self.mediaPlayer.isMetaDataAvailable(): res = str(self.mediaPlayer.metaData("Resolution")).partition( "PyQt5.QtCore.QSize(")[2].replace(", ", "x").replace(")", "") print("%s%s" % ("Video Resolution = ", res)) if int(res.partition("x")[0]) / int( res.partition("x")[2]) < 1.5: self.screen43() else: self.screen169() else: print("no metaData available") def openFileAtStart(self, filelist): matching = [s for s in filelist if ".myformat" in s] if len(matching) > 0: self.loadFilm(matching)
class QtOpticalflowInterfaceCloud(QWidget): PREVIEW = [ "no preview", "print fps", "image (default)", "image+fps", "print+image+fps", "print+image" ] MODE = [ "stream", "video", ] ESTIMATION = [ "no computing estimation", "simple estimate", "complete estimation (video mode only)", ] os.chdir("../modules") VISION_MODULES = glob.glob("*.py") os.chdir("../solutions") def __init__(self): QWidget.__init__(self) self.salutation_lbl = QLabel( 'Welcome to Opticalflow utilise Graphic interface', self) self.compute_location_text = QLabel("compute location:", self) self.compute_location = QComboBox(self) self.setMinimumSize(400, 400) self.setWindowTitle('GUI opticalflow utilities') self.ip_text = QLabel("ip:", self) self.ip = QLineEdit(self) self.port_text = QLabel("port:", self) self.port = QLineEdit(self) self.width_text = QLabel("width:", self) self.width = QLineEdit(self) self.height_text = QLabel("height:", self) self.height = QLineEdit(self) self.save_text = QLabel("save:", self) self.save = QCheckBox(self) self.save_extension = QLabel("", self) self.name_save = QLineEdit(self) self.fps_text = QLabel("fps:", self) self.fps = QLineEdit(self) self.preview_text = QLabel("preview:", self) self.preview = QComboBox(self) self.mode_text = QLabel("mode:", self) self.mode = QComboBox(self) self.video_file = QLineEdit(self) self.estimation_text = QLabel("estimation:", self) self.estimation = QComboBox(self) self.module_vision_text = QLabel("vision module:", self) self.module_vision = QComboBox(self) self.validation_button = QPushButton(self) self.set_buttons() def set_buttons(self): self.salutation_lbl.move(50, 5) # offset the first control 5px self.compute_location_text.move(5, 35) self.compute_location.move(120, 30) self.compute_location.addItems(["local", "cloud"]) self.compute_location.currentIndexChanged.connect(self.cloud_ip) self.ip_text.move(5, 70) self.ip.setText("localhost") self.ip.move(110, 70) self.ip.hide() self.ip_text.hide() self.port_text.move(5, 105) self.port.setText("10000") self.port.move(110, 105) self.port.hide() self.port_text.hide() self.width_text.move(5, 140) self.width.setText("320") self.width.move(110, 140) self.height_text.move(5, 175) self.height.setText("240") self.height.move(110, 175) self.save_text.move(5, 205) self.save.move(110, 205) self.save.clicked.connect(self.fps_show) self.name_save.move(130, 200) self.name_save.setText("file") self.name_save.hide() self.save_extension.move(260, 205) self.save_extension.hide() self.fps_text.move(5, 240) self.fps.move(110, 240) self.fps.setText("20") self.fps_text.hide() self.fps.hide() self.preview.addItems(self.PREVIEW) self.preview.move(110, 275) self.preview_text.move(5, 275) self.mode.addItems(self.MODE) self.mode.move(110, 310) self.mode_text.move(5, 310) self.mode.currentIndexChanged.connect(self.video_mode) self.video_file.move(190, 310) self.video_file.setText("videos_to_computed_videos/video_list_example") self.video_file.hide() self.estimation.addItems(self.ESTIMATION) self.estimation.move(110, 345) self.estimation_text.move(5, 345) self.module_vision.addItems(self.VISION_MODULES) self.module_vision.move(110, 375) self.module_vision_text.move(5, 375) self.validation_button.move(5, 400) self.validation_button.setText("clicked") self.validation_button.clicked.connect(self.reset_window) def get_value(self): return self def reset_window(self): copyfile("../modules/" + self.module_vision.currentText(), "./realtime/vision_module.py") if self.compute_location.currentText() == "cloud": self.streaming = Streaming(FieldValue(self)) elif self.mode.currentIndex() == 0: self.streaming = OpticalRealtime(FieldValue(self)) elif self.mode.currentIndex() == 1: self.streaming = VideoList(FieldValue(self)) self.streaming.run() def fps_show(self): if self.save.isChecked(): self.fps_text.show() self.fps.show() self.name_save.show() self.save_extension.show() else: self.fps_text.hide() self.fps.hide() self.name_save.hide() self.save_extension.hide() def cloud_ip(self): if self.compute_location.currentText() == "local": self.ip.hide() self.ip_text.hide() self.port.hide() self.port_text.hide() else: self.ip.show() self.ip_text.show() self.port.show() self.port_text.show() def video_mode(self): if self.mode.currentText() == "video": self.video_file.show() else: self.video_file.hide() def __delete__(self): pass
class ParametersWindow(QWidget): """ Créer la fenêtre des paramètres """ def __init__(self, settings): QWidget.__init__(self) self.settings = settings self.setWindowTitle('PARAMETERS') self.setFixedSize(360, 500) self.main_layout = QGridLayout() self.main_layout.setAlignment(Qt.AlignTop) self.setLayout(self.main_layout) calculous_parameters_label = QLabel('CALCULOUS PARAMETERS') calculous_parameters_label.setAlignment(Qt.AlignCenter) calculous_parameters_label.setFixedHeight(58) calculous_parameters_label.setStyleSheet( 'font-family: Calibri; font-size : 10pt; color: #2C3E50;') self.main_layout.addWidget(calculous_parameters_label, 0, 0, 1, 2) object_mass_label = QLabel('Object mass (kg)') object_mass_label.setStyleSheet( 'font-family: Calibri; font-size : 10pt; color: #2C3E50;') object_mass_label.setFixedHeight(32) self.main_layout.addWidget(object_mass_label, 1, 0, 1, 1) self.object_mass_input = QLineEdit() self.object_mass_input.setAlignment(Qt.AlignRight) self.object_mass_input.setText(str(self.settings.object_mass)) self.object_mass_input.textChanged.connect(self.updateObjectMass) self.main_layout.addWidget(self.object_mass_input, 1, 1, 1, 1) dichotomy_precision_label = QLabel('Dichotomy precision') dichotomy_precision_label.setFixedHeight(32) dichotomy_precision_label.setStyleSheet( 'font-family: Calibri; font-size : 10pt; color: #2C3E50;') self.main_layout.addWidget(dichotomy_precision_label, 2, 0, 1, 1) self.dichotomy_precision_input = QLineEdit() self.dichotomy_precision_input.setAlignment(Qt.AlignRight) self.dichotomy_precision_input.setText( str(self.settings.dichotomy_precision)) self.dichotomy_precision_input.textChanged.connect( self.updateDichotomyPrecision) self.main_layout.addWidget(self.dichotomy_precision_input, 2, 1, 1, 1) fluid_density_label = QLabel('Fluid density (kg/m3)') fluid_density_label.setFixedHeight(32) fluid_density_label.setStyleSheet( 'font-family: Calibri; font-size : 10pt; color: #2C3E50;') self.main_layout.addWidget(fluid_density_label, 3, 0, 1, 1) self.fluid_density_options = QComboBox() if self.settings.fluid_density == SALTWATER_DENSITY: self.fluid_density_options.addItem('saltwater (' + str(SALTWATER_DENSITY) + ' kg/m3)') self.fluid_density_options.addItem('freshwater (' + str(FRESHWATER_DENSITY) + ' kg/m3)') else: self.fluid_density_options.addItem('freshwater (' + str(FRESHWATER_DENSITY) + ' kg/m3)') self.fluid_density_options.addItem('saltwater (' + str(SALTWATER_DENSITY) + ' kg/m3)') self.fluid_density_options.addItem('Other') self.fluid_density_options.activated.connect( self.updateFluidDensityWithOption) self.main_layout.addWidget(self.fluid_density_options, 3, 1, 1, 1) self.fluid_density_input = QLineEdit() self.fluid_density_input.setAlignment(Qt.AlignRight) self.fluid_density_input.textChanged.connect( self.updateFluidDensityWithInput) if self.settings.fluid_density in [ FRESHWATER_DENSITY, SALTWATER_DENSITY ]: self.fluid_density_input.hide() else: self.fluid_density_input.setText(str(self.settings.fluid_density)) self.main_layout.addWidget(self.fluid_density_input, 4, 1, 1, 1) display_parameters_label = QLabel('DISPLAY PARAMETERS') display_parameters_label.setAlignment(Qt.AlignCenter) display_parameters_label.setFixedHeight(58) display_parameters_label.setStyleSheet( 'font-family: Calibri; font-size : 10pt; color: #2C3E50;') self.main_layout.addWidget(display_parameters_label, 5, 0, 1, 2) show_draught_label = QLabel('Show draught') show_draught_label.setFixedHeight(32) show_draught_label.setStyleSheet( 'font-family: Calibri; font-size : 10pt; color: #2C3E50;') self.main_layout.addWidget(show_draught_label, 6, 0, 1, 1) self.show_draught_checkbox = QCheckBox() self.show_draught_checkbox.stateChanged.connect(self.updateShowDraught) self.show_draught_checkbox.setCheckState( Qt.CheckState.Checked if self.settings.show_draught else Qt. CheckState.Unchecked) self.main_layout.addWidget(self.show_draught_checkbox, 6, 1, 1, 1) self.show() def updateObjectMass(self): """ Mettre à jour la masse entrée par l'utilisateur """ try: if float(self.object_mass_input.text() ) != self.settings.object_mass: self.settings.object_mass = float( self.object_mass_input.text()) self.lockSimulationButtons() self.settings.term.addSuccessMessage( 'The mass you entered is in a valid format') except Exception: self.settings.term.addErrorMessage( 'The mass you entered is not in a valid format') finally: pass def updateDichotomyPrecision(self): """ Mettre à jour la précision entrée par l'utilisateur """ try: if float(self.dichotomy_precision_input.text() ) != self.settings.dichotomy_precision: self.settings.dichotomy_precision = float( self.dichotomy_precision_input.text()) self.lockSimulationButtons() self.settings.term.addSuccessMessage( 'The dichotomy_precision you entered is in a valid format') except Exception: self.settings.term.addErrorMessage( 'The dichotomy_precision you entered is not in a valid format') finally: pass def updateFluidDensityWithOption(self): """ Mettre à jour la densité sélectionnée par l'utilisateur """ option = self.fluid_density_options.currentText() if option == 'Other': self.fluid_density_input.show() else: self.fluid_density_input.hide() if option == 'freshwater (' + str(FRESHWATER_DENSITY) + ' kg/m3)': if self.settings.fluid_density != FRESHWATER_DENSITY: self.settings.fluid_density = FRESHWATER_DENSITY self.lockSimulationButtons() else: if self.settings.fluid_density != SALTWATER_DENSITY: self.settings.fluid_density = SALTWATER_DENSITY self.lockSimulationButtons() self.settings.term.addSuccessMessage( 'The density of the fluid has correctly been changed') def updateFluidDensityWithInput(self): """ Permettre à l'utilisateur d'entrer une densité de lui-même """ try: if float(self.fluid_density_input.text() ) != self.settings.fluid_density: self.settings.fluid_density = float( self.fluid_density_input.text()) self.lockSimulationButtons() self.settings.term.addSuccessMessage( 'The fluid density you entered is in a valid format') except Exception: self.settings.term.addErrorMessage( 'The fluid density entered is not in a valid format') finally: pass def updateShowDraught(self): """ Afficher le tirant d'eau si l'utilisateur le désire """ if self.show_draught_checkbox.isChecked( ) != self.settings.show_draught: self.settings.show_draught = self.show_draught_checkbox.isChecked() self.lockSimulationButtons() if self.settings.show_draught: self.settings.draught_legend.show() else: self.settings.draught_legend.hide() self.settings.term.addSuccessMessage( 'Show draught has correctly changed') self.settings.updatePreview(self.settings.show_draught) def lockSimulationButtons(self): """ Désactiver certains boutons lors de la modification des paramètres """ for i in range(3, 7): self.settings.buttons[i].setDisabled(True) self.settings.buttons[2].setDisabled(False)
class MainWindow(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle('MASK标注工具') self.setFixedSize(1000, 650) self.move_to_center() # self.mask_img_size = QSize(512, 512) self.brush_color = QColor(255, 255, 0) self.eraser_color = QColor(0, 0, 0) self.label_img = ImageLabel(self, self.mask_img_size, self.brush_color, self.eraser_color) self.label_img.setAlignment(Qt.AlignCenter) self.label_img.setText('没有选择任何图片') self.label_img.setFixedWidth(700) self.label_img.setFixedHeight(600) # self.btn_select_dir = QPushButton(self) self.btn_select_dir.setText('选择目录...') self.btn_select_dir.clicked.connect(self.on_btn_select_dir) self.btn_prev_img = QPushButton(self) self.btn_prev_img.setText('上一张') self.btn_prev_img.clicked.connect(self.on_btn_prev_img) self.connect(QShortcut(QKeySequence(Qt.Key_Left), self), QtCore.SIGNAL('activated()'), self.btn_prev_img.click) self.btn_next_img = QPushButton(self) self.btn_next_img.setText('下一张') self.btn_next_img.clicked.connect(self.on_btn_next_img) self.connect(QShortcut(QKeySequence(Qt.Key_Right), self), QtCore.SIGNAL('activated()'), self.btn_next_img.click) self.btn_select_brush_color = QPushButton(self) self.btn_select_brush_color.setText('修改画笔颜色') self.btn_select_brush_color.clicked.connect( self.on_btn_select_brush_color) self.label_brush_color = QLabel(self) self.label_brush_color.setFixedWidth(50) pe = QPalette() pe.setColor(QPalette.Window, self.brush_color) self.label_brush_color.setPalette(pe) self.label_brush_color.setAutoFillBackground(True) self.defalut_brush_pixle_size = 5 self.min_brush_pixle_size = 1 self.max_brush_pixle_size = 50 self.label_brush_pixle_size = QLabel('画笔像素大小:') self.label_brush_pixle_size.setFixedWidth(110) self.edit_brush_pixle_size_validator = QIntValidator() self.edit_brush_pixle_size_validator.setRange( self.min_brush_pixle_size, self.max_brush_pixle_size) self.edit_brush_pixle_size = QLineEdit(self) self.edit_brush_pixle_size.setText(f'{self.defalut_brush_pixle_size}') self.edit_brush_pixle_size.setValidator( self.edit_brush_pixle_size_validator) self.edit_brush_pixle_size.textChanged.connect( self.on_edit_brush_pixle_size_change) self.label_img.update_brush_pixle_size(self.defalut_brush_pixle_size) self.defalut_eraser_pixle_size = 50 self.min_eraser_pixle_size = 5 self.max_eraser_pixle_size = 50 self.label_eraser_pixle_size = QLabel('橡皮擦像素大小:') self.label_eraser_pixle_size.setFixedWidth(110) self.edit_eraser_pixle_size_validator = QIntValidator() self.edit_eraser_pixle_size_validator.setRange( self.min_eraser_pixle_size, self.max_eraser_pixle_size) self.edit_eraser_pixle_size = QLineEdit(self) self.edit_eraser_pixle_size.setText( f'{self.defalut_eraser_pixle_size}') self.edit_eraser_pixle_size.setValidator( self.edit_eraser_pixle_size_validator) self.edit_eraser_pixle_size.textChanged.connect( self.on_edit_eraser_pixle_size_change) self.label_img.update_eraser_pixle_size(self.defalut_eraser_pixle_size) self.btn_clear_mask = QPushButton(self) self.btn_clear_mask.setText('全部擦除') self.btn_clear_mask.clicked.connect(self.on_btn_clear_mask) self.btn_roate = QPushButton(self) self.btn_roate.setText('旋转') self.btn_roate.clicked.connect(self.on_btn_roate) self.btn_roate_img = QPushButton(self) self.btn_roate_img.setText('旋转原图') self.btn_roate_img.clicked.connect(self.on_btn_roate_img) self.connect(QShortcut(QKeySequence(Qt.Key_Up), self), QtCore.SIGNAL('activated()'), self.btn_roate_img.click) self.btn_roate_mask = QPushButton(self) self.btn_roate_mask.setText('旋转标注图') self.btn_roate_mask.clicked.connect(self.on_btn_roate_mask) self.label_lable_docs = QLabel(self) self.label_lable_docs.setAlignment(Qt.AlignLeft) self.label_lable_docs.setText(r''' - 鼠标左键拖动,绘制标注内容 - ALT+鼠标左键拖动,擦除标注内容 - CTRL+鼠标滚轮,调整画笔像素大小 - ALT+鼠标滚轮,调整橡皮擦像素大小 - 键盘左方向键切换到上一张图片 - 键盘右方向键切换到下一张图片 - 输入张数加回车跳转到指定张数 ''') self.label_status_running1 = QLabel(self) self.label_status_running1.setAlignment(Qt.AlignLeft) self.label_status_running1.setText('请选择需要标注的目录') self.label_status_page_number_validator = QIntValidator() self.label_status_page_number = QLineEdit(self) self.label_status_page_number.setMaximumWidth(50) self.label_status_page_number.setValidator( self.label_status_page_number_validator) self.label_status_page_number.hide() self.label_status_page_number.returnPressed.connect(self.on_page_jump) self.label_status_running2 = QLabel(self) self.label_status_running2.setAlignment(Qt.AlignLeft) self.label_status_running2.setText('张') self.label_status_running2.hide() # 布局 layout_root = QVBoxLayout() layout_root2 = QHBoxLayout() layout_col1 = QVBoxLayout() layout_col2 = QVBoxLayout() layout_root2.addLayout(layout_col1) layout_root2.addLayout(layout_col2) layout_root_row2 = QHBoxLayout() layout_root.addLayout(layout_root2) layout_root.addLayout(layout_root_row2) layout_root_row2.addWidget(self.label_status_running1) layout_root_row2.addWidget(self.label_status_page_number) layout_root_row2.addWidget(self.label_status_running2) layout_col1.addWidget(self.label_img) layout_col2_row1 = QHBoxLayout() layout_col2_row1.addWidget(self.btn_select_dir) layout_col2_row2 = QHBoxLayout() layout_col2_row2.addWidget(self.btn_prev_img) layout_col2_row2.addWidget(self.btn_next_img) layout_col2_row3 = QHBoxLayout() layout_col2_row3.addWidget(self.label_brush_pixle_size) layout_col2_row3.addWidget(self.edit_brush_pixle_size) layout_col2_row4 = QHBoxLayout() layout_col2_row4.addWidget(self.label_eraser_pixle_size) layout_col2_row4.addWidget(self.edit_eraser_pixle_size) layout_col2_row5 = QHBoxLayout() layout_col2_row5.addWidget(self.btn_select_brush_color) layout_col2_row5.addWidget(self.label_brush_color) layout_col2.addLayout(layout_col2_row1) layout_col2.addLayout(layout_col2_row2) layout_col2.addLayout(layout_col2_row5) layout_col2.addLayout(layout_col2_row3) layout_col2.addLayout(layout_col2_row4) layout_col2.addWidget(self.btn_clear_mask) layout_col2.addWidget(self.btn_roate) layout_col2.addWidget(self.btn_roate_img) layout_col2.addWidget(self.btn_roate_mask) layout_col2.addWidget(self.label_lable_docs) layout_col2.addStretch() self.setLayout(layout_root) # 其他数据 self.directory = None self.all_img_file = [] self.all_img_file_index = 0 self.update_btn_status() def move_to_center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def on_btn_select_dir(self): try: self.directory = QFileDialog.getExistingDirectory(self, '选择图片目录') all_img_file = sorted([ x for x in Path(self.directory).iterdir() if x.is_file() and x.suffix.upper() in ['.JPG', '.JPEG', '.BMP', '.PNG'] ]) if len(all_img_file) <= 0: QMessageBox.information(self, '<提示>', f'{self.directory}\n目录下没有找到图片文件', QMessageBox.Ok) return self.setWindowTitle(f'MASK标注工具: {self.directory}') self.all_img_file = all_img_file self.all_img_file_index = 0 self.show_label_img() finally: self.update_btn_status() def on_btn_next_img(self): try: self.all_img_file_index += 1 self.show_label_img() finally: self.update_btn_status() def on_btn_prev_img(self): try: self.all_img_file_index -= 1 self.show_label_img() finally: self.update_btn_status() def on_btn_select_brush_color(self): self.brush_color = QColorDialog.getColor() self.label_img.update_brush_color(self.brush_color) pe = QPalette() pe.setColor(QPalette.Window, self.brush_color) self.label_brush_color.setPalette(pe) self.label_brush_color.setAutoFillBackground(True) def on_btn_clear_mask(self): self.show_label_img(do_clear=True) def on_btn_roate(self): self.show_label_img(do_roate=True) def on_btn_roate_img(self): self.show_label_img(do_roate_img=True) def on_btn_roate_mask(self): self.show_label_img(do_roate_mask=True) def on_page_jump(self): try: page_num = int(self.label_status_page_number.text()) if page_num >= 1 and page_num <= len(self.all_img_file): self.all_img_file_index = page_num - 1 self.show_label_img() self.setFocus() finally: self.update_btn_status() def wheelEvent(self, event): if QApplication.keyboardModifiers() == QtCore.Qt.ControlModifier: brush_pixle_size = int(self.edit_brush_pixle_size.text()) delta = event.delta() if delta > 0: brush_pixle_size += 1 elif delta < 0: brush_pixle_size -= 1 if brush_pixle_size >= self.min_brush_pixle_size and brush_pixle_size <= self.max_brush_pixle_size: self.edit_brush_pixle_size.setText(f'{brush_pixle_size}') elif QApplication.keyboardModifiers() == QtCore.Qt.AltModifier: eraser_pixle_size = int(self.edit_eraser_pixle_size.text()) delta = event.delta() if delta > 0: eraser_pixle_size += 1 elif delta < 0: eraser_pixle_size -= 1 if eraser_pixle_size >= self.min_eraser_pixle_size and eraser_pixle_size <= self.max_eraser_pixle_size: self.edit_eraser_pixle_size.setText(f'{eraser_pixle_size}') def on_edit_brush_pixle_size_change(self): if self.edit_brush_pixle_size.text(): brush_pixle_size = int(self.edit_brush_pixle_size.text()) self.label_img.update_brush_pixle_size(brush_pixle_size) def on_edit_eraser_pixle_size_change(self): if self.edit_eraser_pixle_size.text(): eraser_pixle_size = int(self.edit_eraser_pixle_size.text()) self.label_img.update_eraser_pixle_size(eraser_pixle_size) def update_btn_status(self): try: self.btn_next_img.setEnabled(False) self.btn_prev_img.setEnabled(False) self.btn_roate.setEnabled(False) self.btn_roate_img.setEnabled(False) self.btn_roate_mask.setEnabled(False) self.btn_clear_mask.setEnabled(False) if not self.all_img_file: self.label_status_running1.setText('请选择需要标注的目录') self.label_status_page_number.hide() self.label_status_running2.hide() else: img_name = self.all_img_file[self.all_img_file_index] # self.label_status_page_number.show() # self.label_status_running2.show() self.label_status_page_number_validator.setRange( 1, len(self.all_img_file)) self.label_status_page_number.setText( f'{self.all_img_file_index+1}') self.label_status_running1.setText( f'当前图片: {img_name} ({self.all_img_file_index + 1}/{len(self.all_img_file)}) 跳转到' ) self.label_status_running2.setText(f'张') if self.all_img_file_index == 0: self.btn_prev_img.setEnabled(False) else: self.btn_prev_img.setEnabled(True) if self.all_img_file_index == len(self.all_img_file) - 1: self.btn_next_img.setEnabled(False) else: self.btn_next_img.setEnabled(True) self.btn_roate.setEnabled(True) self.btn_roate_img.setEnabled(True) self.btn_roate_mask.setEnabled(True) self.btn_clear_mask.setEnabled(True) except: logging.exception('update_btn_status exception') def show_label_img(self, do_roate=False, do_roate_img=False, do_roate_mask=False, do_clear=False): if not self.all_img_file: return img_path = self.all_img_file[self.all_img_file_index] img = QPixmap(str(img_path)) img_mask_path = img_path.parent.joinpath(f'mask/{img_path.stem}.bmp') img_mask_path.parent.mkdir(parents=True, exist_ok=True) if img_mask_path.is_dir(): QMessageBox.warning( self, '<致命错误>', f'标注文件<{img_mask_path}>是一个目录, 请把它拷贝到别的地方, 然后重新打开标注工具!!!', QMessageBox.Ok) sys.exit(-1) if img_mask_path.exists(): img_mask = QPixmap(str(img_mask_path)) if img_mask.size() != self.mask_img_size: os.remove(str(img_mask_path)) if not img_mask_path.exists() or do_clear: img_mask = QPixmap(self.mask_img_size) img_mask.fill(QColor(0, 0, 0)) img_mask.save(str(img_mask_path)) if do_roate: rm = QMatrix() rm.rotate(90) img = img.transformed(rm) img.save(str(img_path)) img_mask = img_mask.transformed(rm) img_mask.save(str(img_mask_path)) if do_roate_img: rm = QMatrix() rm.rotate(90) img = img.transformed(rm) img.save(str(img_path)) if do_roate_mask: rm = QMatrix() rm.rotate(90) img_mask = img_mask.transformed(rm) img_mask.save(str(img_mask_path)) self.label_img.update_label_img(img, img_mask, str(img_mask_path))