class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__() layout = QVBoxLayout() self.progress = QProgressBar() button = QPushButton("START IT UP") button.pressed.connect(self.execute) layout.addWidget(self.progress) layout.addWidget(button) w = QWidget() w.setLayout(layout) self.setCentralWidget(w) self.show() self.threadpool = QThreadPool() print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount()) def execute(self): worker = Worker() worker.signals.progress.connect(self.update_progress) # Execute self.threadpool.start(worker) def update_progress(self, progress): self.progress.setValue(progress)
class WorkerProgress(QWidget): def __init__(self, worker_name, *args): super().__init__(*args) self.setLayout(QVBoxLayout()) self.layout().setAlignment(Qt.AlignTop) self.label = QLabel(self) self.label.setText(worker_name.replace("\\", "/").split("/")[-1] + ":") self.progress = QProgressBar(self) self.layout().addWidget(self.label) self.layout().addWidget(self.progress) self.progress.setValue(0)
class MyClass(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.resize(300, 200) # 载入进度条控件 self.verticalLayout = QVBoxLayout() self.pgb = QProgressBar(self) self.verticalLayout.addWidget(self.pgb, 0, 0, 1, 1) #self.pgb.move(50, 50) #self.pgb.resize(250, 20) # 配置一个值表示进度条的当前进度 self.pv = 0 # 申明一个时钟控件 self.timer1 = QBasicTimer() # 设置进度条的范围 self.pgb.setMinimum(0) self.pgb.setMaximum(100) self.pgb.setValue(self.pv) # 载入按钮 self.btn = QPushButton("开始", self) self.btn.move(50, 100) self.btn.clicked.connect(self.myTimerState) self.show() def myTimerState(self): if self.pv == 100: self.close() if self.timer1.isActive(): self.timer1.stop() self.btn.setText("开始") else: self.timer1.start(100, self) self.btn.setText("停止") def timerEvent(self, e): if self.pv == 100: self.timer1.stop() self.btn.setText("完成") else: self.pv += 1 self.pgb.setValue(self.pv)
class Window(QWidget): """The main application Window.""" def __init__(self): super().__init__() self.setWindowTitle("Example") self.layout = QGridLayout() self.layout.setContentsMargins(6, 6, 6, 6) self.layout.addWidget(QTableWidget(), 0, 0, 1, 3) self.loading_bar = QProgressBar() self.loading_bar.setTextVisible(False) self.loading_bar.setValue(25) self.layout.addWidget(self.loading_bar, 1, 0, 1, 1) self.refresh_btn = FixedWindowsButton("Refresh") self.layout.addWidget(self.refresh_btn, 1, 1, 1, 1) self.execute_btn = FixedWindowsButton("Execute") self.layout.addWidget(self.execute_btn, 1, 2, 1, 1) self.setLayout(self.layout)
class Window(QWidget): """The main application Window.""" def __init__(self): super().__init__() self.setWindowTitle("Example") self.layout = QHBoxLayout() self.layout.setContentsMargins(6, 6, 6, 6) self.loading_bar = QProgressBar() self.loading_bar.setTextVisible(False) self.loading_bar.setFixedHeight(25) self.layout.addWidget(self.loading_bar) self.quit_btn = FixedWindowsButton("Quit") self.quit_btn.setFixedHeight(25) self.quit_btn.clicked.connect(self.onQuitBtnClicked) self.layout.addWidget(self.quit_btn) self.run_btn = FixedWindowsButton("Run") self.run_btn.setFixedHeight(25) self.run_btn.clicked.connect(self.onRunBtnClicked) self.layout.addWidget(self.run_btn) self.setLayout(self.layout) def onRunBtnClicked(self): self.run_btn.setText("Loading...") self.run_btn.setEnabled(False) self.quit_btn.setEnabled(False) self.quit_btn.setHidden(True) self.calc = LongRunningProcess() self.calc.progress_changed.connect(self.onProgressChanged) self.calc.finished.connect(self.onProgressFinished) self.calc.start() def onQuitBtnClicked(self): self.close() def onProgressChanged(self, value): self.loading_bar.setValue(value) def onProgressFinished(self): self.quit_btn.setHidden(False) self.quit_btn.setEnabled(True) self.run_btn.setEnabled(True) self.run_btn.setText("Run") self.loading_bar.setValue(0)
class ProgressExample(QWidget): """The main ui components""" def __init__(self, parent=None): super(ProgressExample, self).__init__(parent) self.setupUi() def setupUi(self): self.setWindowTitle('QProgressBar Example') self.btn = QPushButton('Click Me!') self.btn.clicked.connect(self.btnFunc) self.pBar = QProgressBar() self.pBar.setValue(0) self.resize(300, 100) self.vbox = QVBoxLayout() self.vbox.addWidget(self.pBar) self.vbox.addWidget(self.btn) self.setLayout(self.vbox) self.show() def btnFunc(self): self.thread = Thread() self.thread._signal.connect(self.signal_accept) self.thread.start() self.btn.setEnabled(False) def signal_accept(self, msg): self.pBar.setValue(int(msg)) if self.pBar.value() == 99: self.pBar.setValue(0) self.btn.setEnabled(True)
class Progress(QtWidgets.QWidget): pbar: QProgressBar index: int len: int def __init__(self, curr_op: Type[Op] = Shell, len: int = 1, ix=0, parent: Any | None = None): super().__init__(parent) self.index = ix self.lblh = self.toplabel() self.lblh = QLabel(self) self.lblo = self.oplabel() self.opmsg = QLabel("", self) self.pbar = QProgressBar(self) self.pbar.setValue(0) self.len = len self.setupUi() # @pyqtSlot(Type[Op]) def upd(self, op_type: Type[Op]) -> None: self.curr_op = op_type if self.index < self.len: self.lblh = self.toplabel() self.lblo = self.oplabel() else: self.lblh.setText( f"All {self.len} operations completed successfully.") self.close() @Slot(str) def set_opmsg(self, msg: str) -> None: self.opmsg.setText(msg) def toplabel(self) -> QLabel: return QLabel( "Running operations... " + str(self.index + 1) + "of" + str(self.len + 1) + ", self", self) def oplabel(self) -> QLabel: return QLabel("Operation {str(self.curr_op)} in progress", self) def set_optype(self, ot: Type[Op]): self.curr_op = ot @Slot(int) def progress(self, val: int): self.pbar.setValue(val) self.lblh = self.toplabel() self.lblo = self.oplabel() @Slot(Status) def handle_status( self, st: Status, ): if st == Status.Canceled: self.lblh.setText("Canceled") self.lblo.setText(f"{self.curr_op} was canceled by the user.") elif st == Status.Done: self.lblh.setText("Finished") self.lblo.setText(f"{self.curr_op} is complete.") elif st == Status.Failed: self.lblh.setText("Failed") self.lblo.setText(f"{self.curr_op} failed.") elif st == Status.InProgress: self.lblh = self.toplabel() self.lblo = self.oplabel() def setupUi(self): layout = QVBoxLayout() self.timer = QBasicTimer() self.pbar = QProgressBar(self) self.setWindowTitle("isutils: Executing op (1/1)...") self.resize(400, 250) layout.addWidget(self.lblh) layout.addWidget(self.lblo) layout.addWidget(self.pbar) self.setLayout(layout) def timerEvent(self, e: QTimerEvent): if self.timer.isActive() or self.pbar.value() >= 100: self.timer.stop() self.lblh.setText("finished") return self.index += 1 self.set(self.index) @Slot() def start(self): self.timer.start(100, self) @Slot() def finish(self): self.lblh.setText("Finished") self.lblo.setText(f"{self.curr_op} is complete.") def set(self, amt: int | float): self.pbar.setValue(int(amt))
class MainWindow(QMainWindow): def __init__(self): super().__init__() layout = QVBoxLayout() self.progress = QProgressBar() button = QPushButton("START IT UP") button.pressed.connect(self.execute) self.status = QLabel("0 workers") layout.addWidget(self.progress) layout.addWidget(button) layout.addWidget(self.status) w = QWidget() w.setLayout(layout) # Dictionary holds the progress of current workers. self.worker_progress = {} self.setCentralWidget(w) self.show() self.threadpool = QThreadPool() print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount()) self.timer = QTimer() self.timer.setInterval(100) self.timer.timeout.connect(self.refresh_progress) self.timer.start() def execute(self): worker = Worker() worker.signals.progress.connect(self.update_progress) worker.signals.finished.connect(self.cleanup) # 任务完成后清除对应进度 # Execute self.threadpool.start(worker) def cleanup(self, job_id): if job_id in self.worker_progress: del self.worker_progress[job_id] # 对完成的任务,删除 # Update the progress bar if we've removed a value. self.refresh_progress() def update_progress(self, job_id, progress): self.worker_progress[job_id] = progress def calculate_progress(self): if not self.worker_progress: return 0 return sum(v for v in self.worker_progress.values()) / len( self.worker_progress) def refresh_progress(self): # Calculate total progress. progress = self.calculate_progress() print(self.worker_progress) self.progress.setValue(progress) self.status.setText("%d workers" % len(self.worker_progress))
class MyWidget(QWidget): def __init__(self): super().__init__() # 设置属性 self.resize(400, 300) self.setWindowTitle("测试Qt进度条和aria2的联合") # 注册组件 self.labelUrl = QLabel("下载链接") self.lineEditorUrl = QLineEdit( "https://download.cnki.net/CAJViewer-x86_64-buildubuntu1604-210401.AppImage" ) self.labelProgress = QLabel("下载进度") self.downloadProgress = QProgressBar() self.textResult = QTextBrowser() self.buttonStart = QPushButton("开始") self.buttonPause = QPushButton("暂停") self.buttonUnpause = QPushButton("继续") self.buttonRemove = QPushButton("移除") self.buttonDebug = QPushButton("Debug") # 设置组件 self.lineEditorUrl.setClearButtonEnabled(True) self.buttonStart.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.buttonPause.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) self.buttonUnpause.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.buttonRemove.setIcon(self.style().standardIcon( QStyle.SP_MediaStop)) # self.buttonPause.setDisabled(True) # self.buttonStop.setDisabled(True) # 添加组件 self.layout = QGridLayout(self) self.layout.addWidget(self.labelUrl, 0, 0, 1, 1) self.layout.addWidget(self.lineEditorUrl, 0, 1, 1, 5) self.layout.addWidget(self.labelProgress, 1, 0, 1, 1) self.layout.addWidget(self.downloadProgress, 1, 1, 1, 5) self.layout.addWidget(self.textResult, 2, 0, 2, 5) self.layout.addWidget(self.buttonStart, 4, 0, 1, 1) self.layout.addWidget(self.buttonPause, 4, 1, 1, 1) self.layout.addWidget(self.buttonUnpause, 4, 2, 1, 1) self.layout.addWidget(self.buttonRemove, 4, 3, 1, 1) self.layout.addWidget(self.buttonDebug, 4, 4, 1, 1) # 添加组件功能 # class函数 @Slot(str) def updateProgress(self, value): self.downloadProgress.setMaximum(int(value['totalLength'])) self.downloadProgress.setValue( int(value['files'][0]['completedLength'])) if value["status"] == "complete": self.downloadProgress.setValue(int(value['totalLength'])) shutdown_aria2 = Signal() @Slot() def clearProgress(self): self.downloadProgress.setValue(0) def closeEvent(self, event): if QMessageBox.question(self, "退出程序", "确定退出吗?") == QMessageBox.No: event.ignore() else: event.accept() self.shutdown_aria2.emit()
painter.drawPixmap(0, 0, pixmap) if __name__ == '__main__': app = QApplication() progressbar_value = 30 path_to_gif = 'loading_gifs/1.gif' splash = MovieSplashScreen(path_to_gif) progressbar = QProgressBar(splash) progressbar.setMaximum(progressbar_value) progressbar.setTextVisible(False) progressbar.setGeometry(0, splash.my_size.height() - 50, splash.my_size.width(), 20) splash.show() for i in range(progressbar_value): progressbar.setValue(i) t = time.time() while time.time() < t + 0.1: app.processEvents() time.sleep(1) window = MainWindow() window.show() splash.finish(window) sys.exit(app.exec_())
class ProgressBar(QWidget): # Incoming progress updates set_progress = Signal(int) def __init__(self, show_time=True): """Opens a progress bar widget :type show_time: bool :param show_time: If the time should be shown below the progress bar""" super().__init__() # Setup parameters self._show_time: bool = show_time self._timer_start: float = 0 # General layout self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) self._layout = QVBoxLayout() self.setLayout(self._layout) # The progress bar itself self._progress_bar = QProgressBar(self) self._progress_bar.setMaximum(100) self._progress_bar.setGeometry(0, 0, 350, 25) self._progress_bar.setValue(0) self._layout.addWidget(self._progress_bar) # Setup time display self._time_wrapper = QHBoxLayout() self._time_expired_label = QLabel("") self._time_expired_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) self._time_left_label = QLabel("") self._time_left_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) self._time_wrapper.addWidget(self._time_expired_label) self._time_wrapper.addWidget(self._time_left_label) self._layout.addLayout(self._time_wrapper) # Set Size self.resize(500, 80) # Register progress update handler # noinspection PyUnresolvedReferences self.set_progress.connect(self._set_progress) def startTimer(self): """Start the internal timer""" self._timer_start = timeit.default_timer() def _set_progress(self, percentage_done): """Handle incoming progress updates :type percentage_done: int :param percentage_done: The progress to set, from 0 to 100 """ self._progress_bar.setValue(percentage_done) if self._show_time: time_elapsed, time_remaining = self._get_progress_times(percentage_done) self._time_expired_label.setText("Time elapsed: " + str(time_elapsed) + "s") self._time_left_label.setText("Time remaining: " + str(time_remaining) + "s") def _get_progress_times(self, percentage_done): """Get the elapsed and remaining time :type percentage_done: float :param percentage_done: How much progress has been made :return float, float: Time elapsed, Time remaining""" time_elapsed = math.floor(timeit.default_timer() - self._timer_start) if 0 == percentage_done: percentage_done = 1 time_remaining = math.floor(time_elapsed * (100 / percentage_done)) - time_elapsed return time_elapsed, time_remaining def close_with_delay(self): """Close the progress bar widget with a short delay""" sleep(0.8) self.close()
class RenameFilesGUI(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setMinimumSize(600, 250) self.setWindowTitle("Change File Names GUI") self.directory = "" self.cb_value = "" self.setupWidgets() self.show() def setupWidgets(self): """ Set up the widgets and layouts for interface. """ dir_label = QLabel("Choose Directory:") self.dir_line_edit = QLineEdit() dir_button = QPushButton('...') dir_button.setToolTip("Select file directory.") dir_button.clicked.connect(self.setDirectory) self.change_name_edit = QLineEdit() self.change_name_edit.setToolTip( "Files will be appended with numerical values.For example: filename <b> 01 </b >.jpg") self.change_name_edit.setPlaceholderText("Change file names to...") rename_button = QPushButton("Rename Files") rename_button.setToolTip("Begin renaming files in directory.") rename_button.clicked.connect(self.renameFiles) file_exts = [".jpg", ".jpeg", ".png", ".gif", ".txt"] # Create combo box for selecting file extensions. ext_cb = QComboBox() self.cb_value = file_exts[0] ext_cb.setToolTip("Only files with this extension will be changed.") ext_cb.addItems(file_exts) ext_cb.currentTextChanged.connect(self.updateCbValue) # Text edit is for displaying the file names as they are updated. self.display_files_edit = QTextEdit() self.display_files_edit.setReadOnly(True) self.progress_bar = QProgressBar() self.progress_bar.setValue(0) # Set layout and widgets. grid = QGridLayout() grid.addWidget(dir_label, 0, 0) grid.addWidget(self.dir_line_edit, 1, 0, 1, 2) grid.addWidget(dir_button, 1, 2) grid.addWidget(self.change_name_edit, 2, 0) grid.addWidget(ext_cb, 2, 1) grid.addWidget(rename_button, 2, 2) grid.addWidget(self.display_files_edit, 3, 0, 1, 3) grid.addWidget(self.progress_bar, 4, 0, 1, 3) self.setLayout(grid) def setDirectory(self): """ Choose the directory. """ file_dialog = QFileDialog(self) file_dialog.setFileMode(QFileDialog.Directory) self.directory = file_dialog.getExistingDirectory(self, "Open Directory", "", QFileDialog.ShowDirsOnly) if self.directory: self.dir_line_edit.setText(self.directory) # Set the max value of progress bar equal to max number of files in the directory. num_of_files = len([name for name in os.listdir(self.directory)]) self.progress_bar.setRange(0, num_of_files) def updateCbValue(self, text): """ Change the combo box value. Values represent the different file extensions. """ self.cb_value = text def renameFiles(self): """ Create instance of worker thread to handle the file renaming process. """ prefix_text = self.change_name_edit.text() if self.directory != "" and prefix_text != "": self.worker = Worker(self.directory, self.cb_value, prefix_text) self.worker.updateValueSignal.connect(self.updateProgressBar) self.worker.updateTextEditSignal.connect(self.updateTextEdit) self.worker.start() else: pass def updateProgressBar(self, value): self.progress_bar.setValue(value) def updateTextEdit(self, old_text, new_text): self.display_files_edit.append("[INFO] {} changed to{}.".format(old_text, new_text))
class GUI: class Window: statistics = 1 options = 2 app = QApplication([]) statisticsWindow = QWidget(f=Qt.FramelessWindowHint) optionsWindow = QWidget(f=Qt.FramelessWindowHint) defaultSizeX = 800 defaultSizeY = 600 newSizeX = None newSizeY = None hypixelAPILoad = 0 minecraftAPILoad = 0 overlayLoad = 0 currentWindow = Window.statistics def __init__(self, winx: int, winy: int, version: str, statisticsTypes: list, statistics: dict): self.newSizeX = winx self.newSizeY = winy self.version = version self.stats = statistics self.statTypes = statisticsTypes self.buildStatistics() def buildWindow(self, window: QWidget): window.resize(self.newSizeX, self.newSizeY) font = QFont() font.setBold(False) font.setUnderline(False) font.setKerning(False) font.setWeight(QFont.Weight.Normal) window.setFont(font) window.setObjectName(u"background") window.setStyleSheet("QWidget#background {background-color: gray}") def buildOptions(self): self.buildWindow() QLabel("Options", self.optionsWindow) def buildStatistics(self): self.buildWindow(self.window()) self.statTableMain = QTableView(self.window()) self.statTableMain.setObjectName(u"statTableMain") statTableHeader = QHeaderView(Qt.Orientation.Vertical) # self.statTableMain.commitData() # https://doc.qt.io/qt-5/sql-model.html self.statTableMain.setVerticalHeader(statTableHeader) self.statTableMain.setGeometry(self.winw(5), self.winh(10), self.winw(90), self.winh(80)) hypixelAPILabel = QLabel("Hypixel API Load:", self.window()) hypixelAPILabel.setGeometry(self.winw(5), self.winh(90), self.winw(15), self.winh(5)) minecraftAPILabel = QLabel("Minecraft API Load:", self.window()) minecraftAPILabel.setGeometry(self.winw(20), self.winh(90), self.winw(15), self.winh(5)) overlayProgressLabel = QLabel("Overlay Load:", self.window()) overlayProgressLabel.setGeometry(self.winw(35), self.winh(90), self.winw(15), self.winh(5)) self.hypixelProgressBar = QProgressBar(self.window()) self.hypixelProgressBar.setValue(self.hypixelAPILoad) self.hypixelProgressBar.setGeometry(self.winw(5), self.winh(95), self.winw(15), self.winh(3)) self.minecraftProgressBar = QProgressBar(self.window()) self.minecraftProgressBar.setValue(self.minecraftAPILoad) self.minecraftProgressBar.setGeometry(self.winw(20), self.winh(95), self.winw(15), self.winh(3)) self.overlayProgressBar = QProgressBar(self.window()) self.overlayProgressBar.setValue(self.overlayLoad) self.overlayProgressBar.setGeometry(self.winw(35), self.winh(95), self.winw(15), self.winh(3)) self.statisticsButton = QPushButton("&Stats", self.window()) self.statisticsButton.setGeometry(self.winw(5), self.winh(4), self.winw(10), self.winh(4)) self.statisticsButton.setObjectName(u"menuButton") self.optionsButton = QPushButton("&Options", self.window()) self.optionsButton.setGeometry(self.winw(16), self.winh(4), self.winw(10), self.winh(4)) self.optionsButton.setObjectName(u"menuButton") self.exitButton = QPushButton("&Exit", self.window()) self.exitButton.setGeometry(self.winw(85), self.winh(4), self.winw(10), self.winh(4)) self.exitButton.setObjectName(u"menuButton") self.statisticsButton.clicked.connect( lambda: self.statisticsButtonClick()) self.optionsButton.clicked.connect(lambda: self.optionsButtonClick()) self.exitButton.clicked.connect(lambda: self.exitButtonClick()) def updateButtons(self): self.statisticsButton.setDisabled( self.currentWindow == self.Window.statistics) self.optionsButton.setDisabled( self.currentWindow == self.Window.options) def statisticsButtonClick(self): self.currentWindow = self.Window.statistics def optionsButtonClick(self): self.currentWindow = self.Window.options def exitButtonClick(self): self.app.exit() def winw(self, percent: int): return percent / 100 * self.defaultSizeX def winh(self, percent: int): return percent / 100 * self.defaultSizeY def scale(self, normal: int, dir="both"): size = self.window().size() xscale = size.width() / self.defaultSizeX yscale = size.height() / self.defaultSizeY normal *= xscale if dir == "both" or dir == "hor" else 1 normal *= yscale if dir == "both" or dir == "ver" else 1 return normal def window(self): if self.currentWindow == self.Window.statistics: return self.statisticsWindow else: return self.optionsWindow def run(self): self.window().show() self.app.exec_()
class TableClothGenerator(QMainWindow): def __init__(self, parent=None): super().__init__(parent) # Main UI settings self.setWindowTitle('Tablecloth Generator') self.setWindowIcon(QIcon('icon.ico')) self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) self.resize(350, 350) self.center() self._createMenuBar() self.MainUI() def MainUI(self): # Obtain the configs fp_config = open(THISDIR + "\\config\\config.json", "r", encoding="utf-8") self.config = json.loads(fp_config.read()) fp_config.close() # Obtain and List the teams fp_teams = open(THISDIR + "\\config\\teams.json", "r", encoding="utf-8") conf_teams = json.loads(fp_teams.read()) fp_teams.close() self.teams = conf_teams["teams"] self.players = conf_teams["players"] # Obtain all images needed to create the tablecloth self.background = Image.open(THISDIR + "\\images\\mat.png") self.table_border = Image.open(THISDIR + "\\images\\table_border.png") self.tech_lines = Image.open(THISDIR + "\\images\\technical_lines.png") # Check if there's no configuration set up # and prompt to create/import one if self.config["total_teams"] == 0: self.no_config = QMessageBox.question(self, "No configuration", "No configuration has been found. Do you wish to set up a new one?", QMessageBox.Yes | QMessageBox.No) if self.no_config == QMessageBox.Yes: self.CreateTeamsWindow() self.bg_image = self.config["image_route"] self.players_combobox = QComboBox() self.UpdatePlayersList() self.players_combobox.setEditable(True) self.players_combobox.completer()\ .setCompletionMode(QCompleter.PopupCompletion) self.players_combobox.setInsertPolicy(QComboBox.NoInsert) # Set up the GUI self.statusBar().showMessage("Remember: Rig responsibly.") # Bottom (EAST) self.label_east = QLabel(self) self.label_east.setText("<h1>East Seat</h1>") self.label_east.setAlignment(QtCore.Qt.AlignCenter) self.image_east = QLabel(self) self.image_east.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_east.setAlignment(QtCore.Qt.AlignCenter) self.search_east = QLineEdit() self.search_east.setAlignment(QtCore.Qt.AlignCenter) self.search_east.editingFinished.connect( lambda: self.searchPlayer(self.search_east.text(), self.cloth_east)) self.cloth_east = QComboBox() self.cloth_east.setModel(self.players_combobox.model()) self.cloth_east.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_east, self.image_east)) # Right (SOUTH) self.label_south = QLabel(self) self.label_south.setText("<h1>South Seat</h1>") self.label_south.setAlignment(QtCore.Qt.AlignCenter) self.image_south = QLabel(self) self.image_south.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_south.setAlignment(QtCore.Qt.AlignCenter) self.image_south.show() self.search_south = QLineEdit() self.search_south.setAlignment(QtCore.Qt.AlignCenter) self.search_south.editingFinished.connect( lambda: self.searchPlayer(self.search_south.text(), self.cloth_south)) self.cloth_south = QComboBox() self.cloth_south.setModel(self.players_combobox.model()) self.cloth_south.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_south, self.image_south)) # Top (WEST) self.label_west = QLabel(self) self.label_west.setText("<h1>West Seat</h1>") self.label_west.setAlignment(QtCore.Qt.AlignCenter) self.image_west = QLabel(self) self.image_west.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_west.setAlignment(QtCore.Qt.AlignCenter) self.image_west.show() self.cloth_west = QComboBox() self.search_west = QLineEdit() self.search_west.setAlignment(QtCore.Qt.AlignCenter) self.search_west.editingFinished.connect( lambda: self.searchPlayer(self.search_west.text(), self.cloth_west)) self.cloth_west.setModel(self.players_combobox.model()) self.cloth_west.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_west, self.image_west)) # Left (NORTH) self.label_north = QLabel(self) self.label_north.setText("<h1>North Seat</h1>") self.label_north.setAlignment(QtCore.Qt.AlignCenter) self.image_north = QLabel(self) self.image_north.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.image_north.setAlignment(QtCore.Qt.AlignCenter) self.image_north.show() self.cloth_north = QComboBox() self.search_north = QLineEdit() self.search_north.setAlignment(QtCore.Qt.AlignCenter) self.search_north.editingFinished.connect( lambda: self.searchPlayer(self.search_north.text(), self.cloth_north)) self.cloth_north.setModel(self.players_combobox.model()) self.cloth_north.currentIndexChanged.connect( lambda: self.SwitchImage(self.cloth_north, self.image_north)) # Technical lines self.technical_lines = QCheckBox("Show Technical lines", self) # Generate button self.generate = QPushButton(self) self.generate.setText("Generate Tablecloth") self.generate.clicked.connect(self.GeneratePreview) # Add custom mat self.custom_mat = QPushButton(self) self.custom_mat.setText("Add Mat") self.custom_mat.clicked.connect(self.MatDialog) # Create the layout grid_layout = QGridLayout() grid_layout.setAlignment(QtCore.Qt.AlignCenter) grid_layout.setAlignment(QtCore.Qt.AlignTop) # Labels East, West grid_layout.addWidget(self.label_east, 1, 1) grid_layout.addWidget(self.label_west, 1, 2) # Image preview East, West grid_layout.addWidget(self.image_east, 2, 1) grid_layout.addWidget(self.image_west, 2, 2) # Search player East, West grid_layout.addWidget(self.search_east, 3, 1) grid_layout.addWidget(self.search_west, 3, 2) # Player combobox East, West grid_layout.addWidget(self.cloth_east, 4, 1) grid_layout.addWidget(self.cloth_west, 4, 2) # Labes South, North grid_layout.addWidget(self.label_south, 5, 1) grid_layout.addWidget(self.label_north, 5, 2) # Image preview South, North grid_layout.addWidget(self.image_south, 6, 1) grid_layout.addWidget(self.image_north, 6, 2) # Search player South, North grid_layout.addWidget(self.search_south, 7, 1) grid_layout.addWidget(self.search_north, 7, 2) # Player combobox South, North grid_layout.addWidget(self.cloth_south, 8, 1) grid_layout.addWidget(self.cloth_north, 8, 2) # Technical lines grid_layout.addWidget(self.technical_lines, 9, 1) # Custom mat/bg grid_layout.addWidget(self.custom_mat, 10, 1) # Generate grid_layout.addWidget(self.generate, 10, 2) self.centralWidget.setLayout(grid_layout) # Create the window self.show() def _createMenuBar(self): # Settings and stuff for the toolbar menubar = QMenuBar(self) file_menu = QMenu("&File", self) file_menu.addAction("Create Team(s)", self.CreateTeamsWindow) file_menu.addAction("Edit Team(s)", self.EditTeamsWindow) file_menu.addAction("Exit", self.close) settings_menu = QMenu("&Settings", self) settings_menu.addAction("Version", self.SeeVersion) settings_menu.addAction("Help", self.GetHelp) menubar.addMenu(file_menu) menubar.addMenu(settings_menu) self.setMenuBar(menubar) def _createProgressBar(self): self.progress_bar = QProgressBar() self.progress_bar.minimum = 0 self.progress_bar.maximum = 100 self.progress_bar.setValue(0) self.progress_bar.setTextVisible(False) self.progress_bar.setGeometry(50, 50, 10, 10) self.progress_bar.setAlignment(QtCore.Qt.AlignRight) self.progress_bar.adjustSize() self.statusBar().addPermanentWidget(self.progress_bar) self.ChangeAppStatus(False) def SwitchImage(self, cloth, image): # It shows you the team logo. No way you can miss those, right? team_id = self.SearchTeamID(cloth, True) image.setPixmap(QPixmap( "images/logos/team%d.png" % team_id).scaled(100,100)) def searchPlayer(self, text, combobox): # It even searches the player for you. What more could you want? search_index = combobox.findText(text, QtCore.Qt.MatchContains) if search_index == -1: QMessageBox.warning(self, "Error", "No player found") else: combobox.setCurrentIndex(search_index) def CreateTeamsWindow(self): self.teamcreation_wid = EditionWidget() self.teamcreation_wid.resize(400, 200) self.teamcreation_wid.setWindowTitle("Teams configuration") self.new_config = {} id_label = QLabel(self) id_label.setText("Team ID: ") self.num_id = QLabel(self) current_id = str(self.config["total_teams"] + 1) self.num_id.setText(current_id) name_label = QLabel(self) name_label.setText("Team Name:") name_label.setFocus() self.name_input = QLineEdit(self) members_label = QLabel(self) members_label.setText("Members (write and press enter):") members_input = QLineEdit(self) members_input.editingFinished.connect( lambda: self.AddMember(members_input)) self.members_list = QListWidget(self) import_image = QPushButton(self) import_image.setText("Import Team Image") import_image.clicked.connect(self.ImportTeamImage) add_team = QPushButton(self) add_team.setText("Add Team") add_team.clicked.connect( lambda: self.addTeamFunction(self.name_input.text(), self.members_list)) import_config = QPushButton(self) import_config.setText("Import configuration") import_config.clicked.connect(self.importTeamFunction) config_lay = QGridLayout() config_lay.addWidget(id_label, 1, 0) config_lay.addWidget(self.num_id, 1, 1) config_lay.addWidget(name_label, 2, 0) config_lay.addWidget(self.name_input, 2, 1) config_lay.addWidget(members_label, 3, 0) config_lay.addWidget(members_input, 3, 1) config_lay.addWidget(self.members_list, 4, 0, 2, 2) config_lay.addWidget(add_team, 6, 0) config_lay.addWidget(import_image, 6, 1) config_lay.addWidget(import_config, 7, 0, 1, 2) self.teamcreation_wid.setLayout(config_lay) self.teamcreation_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.teamcreation_wid.activateWindow() self.teamcreation_wid.raise_() self.teamcreation_wid.show() def addTeamFunction(self, name, members): fp_teams = open(THISDIR + "\\config\\teams.json", "r", encoding="utf-8") current_teams = json.loads(fp_teams.read()) fp_teams.close() team = {} current_teams["teams"].append(name) current_teams["players"][name] = [str(self.members_list.item(i).text())\ for i in range(self.members_list.count())] new_team = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") add_config = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") self.teams = current_teams["teams"] self.players = current_teams["players"] self.config["total_teams"] += 1 new_id = self.config["total_teams"] + 1 self.num_id.setText(str(new_id)) add_config.write(json.dumps(self.config, indent=4)) new_team.write(json.dumps(current_teams, indent=4)) new_team.close() self.name_input.clear() self.members_list.clear() self.UpdatePlayersList() def ImportTeamImage(self): image_dialog = QFileDialog(self) image_dialog = QFileDialog.getOpenFileName(filter="Images (*.png)", selectedFilter="Images (*.png)") if image_dialog[0] != "": new_team_logo = Image.open(image_dialog[0]).convert("RGBA") if new_team_logo.size != (250, 250): new_team_logo.resize((250, 250)) new_team_logo.save(THISDIR+"\\images\\logos\\team%s.png"\ % self.num_id.text()) QMessageBox.information(self, "Team Image", "Team image added.") def importTeamFunction(self): file_dialog = QFileDialog(self) file_dialog = QFileDialog.getOpenFileName( filter="Team Files (*.json *.zip)", selectedFilter="Team Files (*.json *.zip)") if file_dialog[0] != "": if is_zipfile(file_dialog[0]): with ZipFile(file_dialog[0]) as zip_import: list_of_files = zip_import.namelist() for fimp in list_of_files: if fimp.startswith('logos'): zip_import.extract(fimp, path=THISDIR+'\\images\\') imported_teams = zip_import.read('teams.json') imported_teams = imported_teams.decode('utf-8') else: imported_teams = open(file_dialog[0], "r", encoding="utf-8").read() json_teams = json.loads(imported_teams) self.teams = json_teams["teams"] self.players = json_teams["players"] new_teams = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") new_teams.write(json.dumps(json_teams, indent=4)) new_teams.close() old_config = open(THISDIR + "\\config\\config.json", "r", encoding="utf-8").read() old_config = json.loads(old_config) old_config["total_teams"] = len(json_teams["teams"]) self.config = old_config new_config = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") new_config.write(json.dumps(self.config, indent=4)) new_config.close() self.UpdatePlayersList() self.image_east.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_east.setModel(self.players_combobox.model()) self.image_south.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_south.setModel(self.players_combobox.model()) self.image_west.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_west.setModel(self.players_combobox.model()) self.image_north.setPixmap(QPixmap("images/logos/team1.png")\ .scaled(100,100)) self.cloth_north.setModel(self.players_combobox.model()) self.statusBar().showMessage("Teams imported successfully.") self.teamcreation_wid.close() def AddMember(self, member): self.members_list.addItem(member.text()) member.clear() def EditTeamsWindow(self): self.teamedit_wid = EditionWidget() self.teamedit_wid.resize(400, 320) self.teamedit_wid.setWindowTitle("Edit Teams") self.teams_list = QComboBox(self) self.teams_list.addItem("--- Select a team ---") for team in self.teams: self.teams_list.addItem(team) self.teams_list.currentIndexChanged.connect(self.UpdateTeamInfo) team_id_label = QLabel(self) team_id_label.setText("Team ID: ") self.config_team_id = QLabel(self) team_name_label = QLabel(self) team_name_label.setText("Team name: ") self.config_team_name = QLabel(self) team_members_label = QLabel(self) team_members_label.setText("Team members: ") self.config_team_members = QListWidget(self) add_member_label = QLabel(self) add_member_label.setText("Add new member: ") add_member_input = QLineEdit(self) add_member_input.editingFinished.connect(self.AddNewMember) delete_member = QPushButton(self) delete_member.setText("Delete member") delete_member.clicked.connect(self.DeleteMember) delete_team = QPushButton(self) delete_team.setText("Delete Team") delete_team.clicked.connect(self.DeleteTeam) save_changes = QPushButton(self) save_changes.setText("Save changes") save_changes.clicked.connect(self.SaveEdits) export_config = QPushButton(self) export_config.setText("Export Configuration") export_config.clicked.connect(self.ExportTeams) config_lay = QGridLayout() config_lay.addWidget(self.teams_list, 1, 0) config_lay.addWidget(team_id_label, 2, 0) config_lay.addWidget(self.config_team_id, 2, 1) config_lay.addWidget(team_name_label, 3, 0) config_lay.addWidget(self.config_team_name, 3, 1, 1, 2) config_lay.addWidget(team_members_label, 4, 0) config_lay.addWidget(self.config_team_members, 5, 0) config_lay.addWidget(add_member_label, 6, 0) config_lay.addWidget(add_member_input, 6, 1, 1, 2) config_lay.addWidget(delete_member, 7, 0) config_lay.addWidget(delete_team, 7, 1) config_lay.addWidget(save_changes, 8, 0) config_lay.addWidget(export_config, 8, 1) self.teamedit_wid.setLayout(config_lay) self.teamedit_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.teamedit_wid.activateWindow() self.teamedit_wid.raise_() self.teamedit_wid.show() def UpdateTeamInfo(self): sender = self.sender() if sender.currentIndex() > 0: team_id = sender.currentIndex() self.config_team_id.setText(str(team_id)) self.config_team_name.setText(sender.currentText()) if self.config_team_members.count() > 0: self.config_team_members.clear() self.config_team_members.addItems( self.players[sender.currentText()]) def AddNewMember(self): sender = self.sender() self.config_team_members.addItem(sender.text()) sender.clear() def DeleteMember(self): list_members = self.config_team_members.selectedItems() if len(list_members) == 0: QMessageBox.warning(self, "Error", "No player selected") else: for member in list_members: self.config_team_members.takeItem( self.config_team_members.row(member)) def DeleteTeam(self): team_id = int(self.config_team_id.text()) is_last_item = self.teams[self.teams.index( self.config_team_name.text())] == (self.teams[len(self.teams)-1]) self.teams.pop(self.teams.index(self.config_team_name.text())) self.players.pop(self.config_team_name.text()) new_teamlist = {} new_teamlist["teams"] = self.teams new_teamlist["players"] = self.players current_teams = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") current_teams.write(json.dumps(new_teamlist, indent=4)) current_teams.close() if is_last_item == True: self.teams_list.setCurrentIndex(1) else: self.teams_list.setCurrentIndex(team_id+1) self.teams_list.removeItem(team_id) self.UpdatePlayersList() self.cloth_east.setModel(self.players_combobox.model()) self.cloth_south.setModel(self.players_combobox.model()) self.cloth_west.setModel(self.players_combobox.model()) self.cloth_north.setModel(self.players_combobox.model()) def ExportTeams(self): export_dir = self.config["save_route"] if self.config["save_route"] \ is not None else THISDIR exported_file = QFileDialog.getSaveFileName(self, "Save File", export_dir, "Save files (*.zip)") if exported_file[0] != "": export_filename = exported_file[0] if export_filename.endswith(".zip") is False: export_filename += ".zip" files_to_export = [] files_to_export.append("config\\teams.json") for root, directories, files in os.walk(THISDIR+"\\images\\logos"): for filename in files: filepath = os.path.join(root, filename) files_to_export.append(filepath) with ZipFile(export_filename, "w") as export_zip: for exp_file in files_to_export: export_name = exp_file if exp_file.endswith(".json"): split_name = exp_file.split("\\") export_name = split_name[-1] if exp_file.endswith(".png"): split_name = exp_file.split("\\") export_name = "\\logos\\" + split_name[-1] export_zip.write(exp_file, arcname=export_name) export_zip.close() if os.path.exists(export_filename): QMessageBox.information(self, "Export", "The export was successful") def SaveEdits(self): list_members = [str(self.config_team_members.item(i).text()) for i in \ range(self.config_team_members.count())] self.players[self.config_team_name.text()] = list_members new_teamlist = {} new_teamlist["teams"] = self.teams new_teamlist["players"] = self.players current_teams = open(THISDIR + "\\config\\teams.json", "w+", encoding="utf-8") current_teams.write(json.dumps(new_teamlist, indent=4)) current_teams.close() self.teamedit_wid.close() self.statusBar().showMessage("Settings saved.") def MatDialog(self): mat_dialog = QFileDialog(self) mat_dialog = QFileDialog.getOpenFileName(filter="Images (*.png *.jpg)", selectedFilter="Images (*.png *.jpg)") if mat_dialog[0] != "": self.GenerateMat(mat_dialog[0]) def GenerateMat(self, image): self.background = image background = Image.open(self.background).resize((2048,2048))\ .convert("RGBA") self.mat_thread = QThread() east_id = self.SearchTeamID(self.cloth_east, True) south_id = self.SearchTeamID(self.cloth_south, True) west_id = self.SearchTeamID(self.cloth_west, True) north_id = self.SearchTeamID(self.cloth_north, True) if self.config["save_route"] is None: save_to_route = THISDIR else: save_to_route = self.config["save_route"] self._createProgressBar() self.mat_worker = GenerateImageThread(background, self.table_border, east_id, south_id, west_id, north_id, self.technical_lines.isChecked(), save_to_route, self.bg_image, True) self.mat_worker.moveToThread(self.mat_thread) self.mat_thread.started.connect(self.mat_worker.run) self.mat_worker.update_progress.connect(self.UpdateStatus) self.mat_worker.finished.connect(self.mat_thread.quit) self.mat_worker.finished.connect(self.mat_worker.deleteLater) self.mat_thread.finished.connect(self.mat_thread.deleteLater) self.mat_thread.finished.connect(self.MatPreviewWindow) self.mat_thread.start() def MatPreviewWindow(self): self.statusBar().showMessage('Mat preview generated.') self.statusBar().removeWidget(self.progress_bar) # Now you can go back to rigging self.ChangeAppStatus(True) self.mat_wid = QWidget() self.mat_wid.resize(600, 600) self.mat_wid.setWindowTitle("Background preview") mat_preview_title = QLabel(self) mat_preview_title.setText("Selected image (1/4 scale)") mat_preview = QLabel(self) mat_preview.setPixmap(QPixmap(tempfile.gettempdir()+"\\Table_Dif.jpg")\ .scaled(512,512)) confirm = QPushButton(self) confirm.setText("Confirm") confirm.clicked.connect( lambda: self.ChangeMatImage(self.background)) vbox = QVBoxLayout() vbox.setAlignment(QtCore.Qt.AlignCenter) vbox.addWidget(mat_preview_title) vbox.addWidget(mat_preview) vbox.addWidget(confirm) self.mat_wid.setLayout(vbox) self.mat_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.mat_wid.activateWindow() self.mat_wid.raise_() self.mat_wid.show() def ChangeMatImage(self, image): new_bg = Image.open(image) if new_bg.size != (2048, 2048): new_bg = new_bg.resize((2048, 2048)) if new_bg.mode != "RGBA": new_bg = new_bg.convert("RGBA") if self.config["save_route"] is not None: new_bg.save(self.config["save_route"]+"\\images\\mat.png") self.bg_image = self.config["save_route"]+"\\images\\mat.png" else: new_bg.save(THISDIR+"\\images\\mat.png") self.bg_image = THISDIR+"\\images\\mat.png" self.background = new_bg self.config["image_route"] = self.bg_image new_file = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") new_file.write(json.dumps(self.config, indent=4)) new_file.close() self.statusBar().showMessage('New background added.') self.statusBar().removeWidget(self.progress_bar) self.ChangeAppStatus(True) self.mat_wid.close() def GeneratePreview(self): self.preview_thread = QThread() east_id = self.SearchTeamID(self.cloth_east, True) south_id = self.SearchTeamID(self.cloth_south, True) west_id = self.SearchTeamID(self.cloth_west, True) north_id = self.SearchTeamID(self.cloth_north, True) if self.config["save_route"] is None: save_to_route = THISDIR else: save_to_route = self.config["save_route"] self._createProgressBar() self.preview_worker = GenerateImageThread(self.background, self.table_border, east_id, south_id, west_id, north_id, self.technical_lines.isChecked(), save_to_route, self.bg_image, True) self.preview_worker.moveToThread(self.preview_thread) self.preview_thread.started.connect(self.preview_worker.run) self.preview_worker.update_progress.connect(self.UpdateStatus) self.preview_worker.finished.connect(self.preview_thread.quit) self.preview_worker.finished.connect(self.preview_worker.deleteLater) self.preview_thread.finished.connect(self.preview_thread.deleteLater) self.preview_thread.finished.connect(self.PreviewWindow) self.preview_thread.start() def PreviewWindow(self): self.statusBar().showMessage('Tablecloth preview generated.') self.statusBar().removeWidget(self.progress_bar) # Now you can go back to rigging self.ChangeAppStatus(True) self.preview_wid = QWidget() self.preview_wid.resize(600, 600) self.preview_wid.setWindowTitle("Tablecloth preview") tablecloth = QPixmap(tempfile.gettempdir()+"\\Table_Dif.jpg") tablecloth_preview_title = QLabel(self) tablecloth_preview_title.setText("Tablecloth preview (1/4 scale)") tablecloth_preview = QLabel(self) tablecloth_preview.setPixmap(tablecloth.scaled(512,512)) confirm = QPushButton(self) confirm.setText("Confirm") confirm.clicked.connect(self.GenerateImage) confirm.clicked.connect(self.preview_wid.close) vbox = QVBoxLayout() vbox.setAlignment(QtCore.Qt.AlignCenter) vbox.addWidget(tablecloth_preview_title) vbox.addWidget(tablecloth_preview) vbox.addWidget(confirm) self.preview_wid.setLayout(vbox) self.preview_wid.setWindowModality(QtCore.Qt.ApplicationModal) self.preview_wid.activateWindow() self.preview_wid.raise_() self.preview_wid.show() def GeneratedDialog(self): self.statusBar().showMessage('Tablecloth generated. Happy rigging!') self.statusBar().removeWidget(self.progress_bar) # Now you can go back to rigging self.ChangeAppStatus(True) mbox = QMessageBox() mbox.setWindowTitle("Tablecloth Generator") mbox.setText("Tablecloth Generated!") mbox.setStandardButtons(QMessageBox.Ok) mbox.exec() def UpdateStatus(self, status): self.progress_bar.setValue(status) def GenerateImage(self): self.statusBar().showMessage('Generating image...') self._createProgressBar() if self.config["save_route"] is None: self.config["save_route"] = THISDIR save_to_route = QFileDialog.getExistingDirectory(self, "Where to save the image", self.config["save_route"], QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if self.config["save_route"] != save_to_route: temp_file = open(THISDIR + "\\config\\config.json", "r", encoding="utf-8") fp_teams = json.loads(temp_file.read()) fp_teams["save_route"] = save_to_route fp_teams["image_route"] = self.bg_image new_file = open(THISDIR + "\\config\\config.json", "w+", encoding="utf-8") new_file.write(json.dumps(fp_teams, indent=4)) new_file.close() self.background = Image.open(THISDIR + "\\images\\mat.png") self.table_border = Image.open(THISDIR + "\\images\\table_border.png") self.tech_lines = Image.open(THISDIR + "\\images\\technical_lines.png") self.thread = QThread() east_id = self.SearchTeamID(self.cloth_east, True) south_id = self.SearchTeamID(self.cloth_south, True) west_id = self.SearchTeamID(self.cloth_west, True) north_id = self.SearchTeamID(self.cloth_north, True) self.worker = GenerateImageThread(self.background, self.table_border, east_id, south_id, west_id, north_id, self.technical_lines.isChecked(), save_to_route, self.bg_image) self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.worker.update_progress.connect(self.UpdateStatus) self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.worker.deleteLater) self.thread.finished.connect(self.thread.deleteLater) self.thread.finished.connect(self.GeneratedDialog) self.thread.start() def ChangeAppStatus(self, status): # True for enable, False for disable. self.cloth_east.setEnabled(status) self.search_east.setEnabled(status) self.cloth_south.setEnabled(status) self.search_south.setEnabled(status) self.cloth_west.setEnabled(status) self.search_west.setEnabled(status) self.cloth_north.setEnabled(status) self.search_north.setEnabled(status) self.generate.setEnabled(status) def SearchTeamID(self, cloth, plus_one=False): team_id = self.teams.index(cloth.itemData(cloth.currentIndex())) if plus_one: team_id += 1 return team_id def UpdatePlayersList(self): for team, members in self.players.items(): for member in members: self.players_combobox.addItem(member, team) def center(self): qr = self.frameGeometry() cp = QScreen().availableGeometry().center() qr.moveCenter(cp) def SeeVersion(self): git_url = "https://raw.githubusercontent.com/vg-mjg/tablecloth-" git_url += "generator/main/version.txt" with urllib.request.urlopen(git_url) as response: url_version = response.read().decode("utf-8") version = "Your version is up to date!" if url_version != VERSION: version = "Your version is outdated." version += "Please check the <a href='https://github.com/vg-mjg/" version += "tablecloth-generator/releases'>Github page</a>" version +=" for updates." version_message = QMessageBox(self) version_message.setWindowTitle("Checking version") version_message.setText("""<h1>Tablecloth generator</h1> <br> <b>Current Version:</b> %s<br> <b>Your Version:</b> %s<br> <i>%s</i> """ % (url_version, VERSION, version)) version_message.exec() def GetHelp(self): webbrowser.open("https://github.com/vg-mjg/tablecloth-generator/wiki")
class Ui_MainWindow(object): def setupUi(self, MainWindow): if not MainWindow.objectName(): MainWindow.setObjectName(u"MainWindow") MainWindow.resize(534, 188) self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName(u"centralwidget") self.verticalLayout = QVBoxLayout(self.centralwidget) self.verticalLayout.setObjectName(u"verticalLayout") self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName(u"horizontalLayout") self.line_source = QLineEdit(self.centralwidget) self.line_source.setObjectName(u"line_source") self.line_source.setEnabled(True) self.line_source.setReadOnly(True) self.horizontalLayout.addWidget(self.line_source) self.button_source = QPushButton(self.centralwidget) self.button_source.setObjectName(u"button_source") self.horizontalLayout.addWidget(self.button_source) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") self.line_target = QLineEdit(self.centralwidget) self.line_target.setObjectName(u"line_target") self.line_target.setEnabled(True) self.line_target.setReadOnly(True) self.horizontalLayout_2.addWidget(self.line_target) self.button_target = QPushButton(self.centralwidget) self.button_target.setObjectName(u"button_target") self.horizontalLayout_2.addWidget(self.button_target) self.verticalLayout.addLayout(self.horizontalLayout_2) self.line = QFrame(self.centralwidget) self.line.setObjectName(u"line") self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line) self.horizontalLayout_3 = QHBoxLayout() self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") self.label_2 = QLabel(self.centralwidget) self.label_2.setObjectName(u"label_2") self.horizontalLayout_3.addWidget(self.label_2) self.spin_memory = QSpinBox(self.centralwidget) self.spin_memory.setObjectName(u"spin_memory") self.horizontalLayout_3.addWidget(self.spin_memory) self.label_3 = QLabel(self.centralwidget) self.label_3.setObjectName(u"label_3") self.horizontalLayout_3.addWidget(self.label_3) self.spin_blur = QSpinBox(self.centralwidget) self.spin_blur.setObjectName(u"spin_blur") self.spin_blur.setValue(9) self.horizontalLayout_3.addWidget(self.spin_blur) self.label_5 = QLabel(self.centralwidget) self.label_5.setObjectName(u"label_5") self.horizontalLayout_3.addWidget(self.label_5) self.double_spin_threshold = QDoubleSpinBox(self.centralwidget) self.double_spin_threshold.setObjectName(u"double_spin_threshold") self.double_spin_threshold.setMaximum(1.000000000000000) self.double_spin_threshold.setSingleStep(0.050000000000000) self.double_spin_threshold.setValue(0.300000000000000) self.horizontalLayout_3.addWidget(self.double_spin_threshold) self.label_6 = QLabel(self.centralwidget) self.label_6.setObjectName(u"label_6") self.horizontalLayout_3.addWidget(self.label_6) self.double_spin_roimulti = QDoubleSpinBox(self.centralwidget) self.double_spin_roimulti.setObjectName(u"double_spin_roimulti") self.double_spin_roimulti.setMinimum(0.800000000000000) self.double_spin_roimulti.setMaximum(10.000000000000000) self.double_spin_roimulti.setSingleStep(0.050000000000000) self.double_spin_roimulti.setValue(1.000000000000000) self.horizontalLayout_3.addWidget(self.double_spin_roimulti) self.verticalLayout.addLayout(self.horizontalLayout_3) self.line_2 = QFrame(self.centralwidget) self.line_2.setObjectName(u"line_2") self.line_2.setFrameShape(QFrame.HLine) self.line_2.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line_2) self.horizontalLayout_4 = QHBoxLayout() self.horizontalLayout_4.setObjectName(u"horizontalLayout_4") self.label = QLabel(self.centralwidget) self.label.setObjectName(u"label") self.horizontalLayout_4.addWidget(self.label) self.combo_box_weights = QComboBox(self.centralwidget) self.combo_box_weights.setObjectName(u"combo_box_weights") self.horizontalLayout_4.addWidget(self.combo_box_weights) self.label_4 = QLabel(self.centralwidget) self.label_4.setObjectName(u"label_4") self.horizontalLayout_4.addWidget(self.label_4) self.combo_box_scale = QComboBox(self.centralwidget) self.combo_box_scale.addItem("") self.combo_box_scale.addItem("") self.combo_box_scale.addItem("") self.combo_box_scale.setObjectName(u"combo_box_scale") self.horizontalLayout_4.addWidget(self.combo_box_scale) self.label_7 = QLabel(self.centralwidget) self.label_7.setObjectName(u"label_7") self.horizontalLayout_4.addWidget(self.label_7) self.spin_quality = QSpinBox(self.centralwidget) self.spin_quality.setObjectName(u"spin_quality") self.spin_quality.setMaximum(10) self.spin_quality.setValue(5) self.horizontalLayout_4.addWidget(self.spin_quality) self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_4.addItem(self.horizontalSpacer) self.verticalLayout.addLayout(self.horizontalLayout_4) self.line_3 = QFrame(self.centralwidget) self.line_3.setObjectName(u"line_3") self.line_3.setFrameShape(QFrame.HLine) self.line_3.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line_3) self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setObjectName(u"horizontalLayout_5") self.progress = QProgressBar(self.centralwidget) self.progress.setObjectName(u"progress") self.progress.setEnabled(True) self.progress.setValue(0) self.horizontalLayout_5.addWidget(self.progress) self.button_start = QPushButton(self.centralwidget) self.button_start.setObjectName(u"button_start") self.horizontalLayout_5.addWidget(self.button_start) self.button_abort = QPushButton(self.centralwidget) self.button_abort.setObjectName(u"button_abort") self.button_abort.setEnabled(False) self.horizontalLayout_5.addWidget(self.button_abort) self.verticalLayout.addLayout(self.horizontalLayout_5) MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) # setupUi def retranslateUi(self, MainWindow): MainWindow.setWindowTitle( QCoreApplication.translate("MainWindow", u"DashcamCleaner", None)) self.button_source.setText( QCoreApplication.translate("MainWindow", u"Select video", None)) self.button_target.setText( QCoreApplication.translate("MainWindow", u"Select target", None)) self.label_2.setText( QCoreApplication.translate("MainWindow", u"Frame memory:", None)) self.label_3.setText( QCoreApplication.translate("MainWindow", u"Blur size:", None)) self.label_5.setText( QCoreApplication.translate("MainWindow", u"Detection threshold:", None)) self.label_6.setText( QCoreApplication.translate("MainWindow", u"ROI enlargement", None)) self.label.setText( QCoreApplication.translate("MainWindow", u"Weights", None)) self.label_4.setText( QCoreApplication.translate("MainWindow", u"Inference size", None)) self.combo_box_scale.setItemText( 0, QCoreApplication.translate("MainWindow", u"360p", None)) self.combo_box_scale.setItemText( 1, QCoreApplication.translate("MainWindow", u"720p", None)) self.combo_box_scale.setItemText( 2, QCoreApplication.translate("MainWindow", u"1080p", None)) self.combo_box_scale.setCurrentText( QCoreApplication.translate("MainWindow", u"360p", None)) self.label_7.setText( QCoreApplication.translate("MainWindow", u"Output Quality", None)) self.button_start.setText( QCoreApplication.translate("MainWindow", u"Start", None)) self.button_abort.setText( QCoreApplication.translate("MainWindow", u"Abort", None))
class SetQuotaDiskWidget(QWidget): Sg_view_changed = Signal() def __init__(self, model: SettingsModel, parent=None): super(SetQuotaDiskWidget, self).__init__(parent) self._model = model self.setAccessibleName("InfoBox") self.title = QLabel() self.title.setText("Spazio di archiviazione") self.title.setAccessibleName("Title2") self.sottotitolo = QLabel() self.sottotitolo.setAccessibleName('Sottotitolo') self.sottotitolo.setText( "Cambia lo spazio di archiviazione destinato alla cartella sincronizzata" ) # Barra riempimento disco self.progress_label = QLabel() self.progress_label.setText("Spazio occupato:") self.disk_progress = QProgressBar() self.disk_progress.setFormat("") self.disk_quota = QLabel() # Modifica spazio dedicato self.spaceLabel = QLabel(" ") self.dedicated_space = QLineEdit() self.dedicated_space.setValidator(QDoubleValidator()) self.sizes_box = QComboBox() self.sizes_box.wheelEvent = lambda event: None _path_size = bitmath.parse_string(model.convert_size(model.get_size())) _disk_free = bitmath.parse_string( model.convert_size(model.get_free_disk())) self.populate_size_box(_path_size, _disk_free) self.change_quota_button = QPushButton("Cambia quota disco") self.change_quota_button.setMaximumWidth(150) self.change_quota_button.clicked.connect( self.Sl_dedicated_space_changed) self.dedicated_space.returnPressed.connect( self.Sl_dedicated_space_changed) self.buttonLayout = QHBoxLayout() self.buttonLayout.addWidget(self.spaceLabel) self.buttonLayout.addWidget(self.change_quota_button) self.buttonLayout.addWidget(self.spaceLabel) set_space_layout = QHBoxLayout() set_space_layout.addWidget(self.dedicated_space) set_space_layout.addWidget(self.sizes_box) quota_layout = QHBoxLayout() quota_layout.setAlignment(Qt.AlignLeft) quota_layout.addWidget(self.progress_label) quota_layout.addWidget(self.disk_quota) # layout disk_layout = QVBoxLayout() disk_layout.setAlignment(Qt.AlignLeft) disk_layout.addWidget(self.title) disk_layout.addWidget(self.sottotitolo) disk_layout.addWidget(self.spaceLabel) disk_layout.addLayout(quota_layout) disk_layout.addWidget(self.disk_progress) disk_layout.addWidget(self.spaceLabel) disk_layout.addLayout(set_space_layout) disk_layout.addLayout(self.buttonLayout) self.setLayout(disk_layout) self.Sl_model_changed() @Slot() def Sl_dedicated_space_changed(self): self.Sg_view_changed.emit() @Slot() def Sl_model_changed(self): """ Slot collegato ai segnali del model, aggiorna la vista con i nuovi valori :return: None """ # Prendo quota disco con unità e il peso della cartella senza unità (Byte default) new_max_quota = self._model.get_quota_disco() _folder_size = self._model.get_size() # Converto ad oggetto bitmath il peso della cartella e la quota disco folder_size_parsed = bitmath.parse_string( self._model.convert_size(_folder_size)) quota_disco_parsed = bitmath.parse_string(new_max_quota) # Imposto la textbox che mi dice quanto peso ho occupato su quello disponibile self.disk_quota.setText( f"{folder_size_parsed} su {new_max_quota} in uso") free_disk_parsed = bitmath.parse_string( self._model.convert_size(self._model.get_free_disk())) # Imposto la textbox che richiede input if not self.dedicated_space.hasFocus(): self.dedicated_space.setText(str(quota_disco_parsed.value)) # Creo i nuovi valori della combobox if not self.sizes_box.hasFocus(): self.populate_size_box(folder_size_parsed, free_disk_parsed) # Imposto l'item in focus della combobox self.sizes_box.setCurrentText(quota_disco_parsed.unit) # Prendo dimensione corrente della sync folder e della quota disco # e metto in proporzione con quotadisco:100=syncfolder:x _progress_bar_max_value = 100 _tmp = folder_size_parsed.to_Byte().value * _progress_bar_max_value _progress_bar_current_percentage = _tmp / quota_disco_parsed.to_Byte( ).value # Inserisco nuovi valori nella progress bar self.disk_progress.setRange(0, _progress_bar_max_value) self.disk_progress.setValue(_progress_bar_current_percentage) # Se la cartella occupa più spazio di quanto voluto allora la porto a quanto occupa if quota_disco_parsed < folder_size_parsed and not self.dedicated_space.hasFocus( ): self.dedicated_space.setText(str(folder_size_parsed.value)) self.sizes_box.setCurrentText(folder_size_parsed.unit) self.Sg_view_changed.emit() def populate_size_box( self, _min: str, _max: str, ) -> None: """ This method populates the size box with only the available units ex hdd has only <1gb so gb will not be used, the current folder is heavier than 1mb so kb will not be used. :param _min: minimum value with unit ex 10 KiB or just 'KiB' :param _max: maximum value with unit ex 10 KiB or just 'KiB' :return: None """ _sizes = "Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" # Converto in ogni caso a string, in caso in cui venga passato un oggetto # tipo bitmath _min = str(_min) _max = str(_max) # Rimuovo eventuali numeri e caratteri extra, tengo solo l'unità di misura _min = ''.join(i for i in _min if not i.isdigit() and i != '.') _max = ''.join(i for i in _max if not i.isdigit() and i != '.') # Rimuovo possibili spazi ad inizio e fine stringa _min = _min.strip() _max = _max.strip() # Rimuovo dal vettore di possibili unità di misura tutte le unità sotto il lower bound lower_bound = _sizes[_sizes.index(_min):] # Rimuovo dal vettore di possibili unità di misura tutte le unità sopra l'upper bound upper_bound = lower_bound[:lower_bound.index(_max) + 1] # Pulisco il vecchio combo box self.sizes_box.clear() # Inserisco nuovi valori self.sizes_box.addItems(upper_bound)