class Ui_MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowIcon(QIcon(resource_path('icon.ico'))) self.setFixedSize(540, 470) def setupUi(self): self.centralwidget = QWidget(self) with open(resource_path('style.css'), 'r') as file: self.centralwidget.setStyleSheet(file.read()) self.appswidget = QWidget(self.centralwidget) self.appswidget.setGeometry(50, 0, 490, 470) self.appswidget.setProperty('class', 'appswidget') self.sidebar = QFrame(self.centralwidget) self.sidebar.setFrameShape(QFrame.StyledPanel) self.sidebar.setGeometry(0, 0, 50, 470) self.sidebar.setProperty('class', 'sidebar') self.refresh_btn = QPushButton(self.sidebar) self.refresh_btn.setGeometry(QRect(0, 0, 51, 51)) self.refresh_btn.setProperty('class', 'sidebar_btns') self.refresh_btn.setIcon(QIcon(':/icon/refresh_icon.png')) self.refresh_btn.setIconSize(QSize(24, 24)) self.refresh_bind = QShortcut(QKeySequence('Ctrl+R'), self) self.store_btn = QPushButton(self.sidebar) self.store_btn.setGeometry(QRect(0, 51, 51, 51)) self.store_btn.setProperty('class', 'sidebar_btns') self.store_btn.setIcon(QIcon(':/icon/store_icon.png')) self.store_btn.setIconSize(QSize(24, 24)) self.store_bind = QShortcut(QKeySequence('Ctrl+S'), self) self.homepage_btn = QPushButton(self.sidebar) self.homepage_btn.setGeometry(QRect(0, 102, 51, 51)) self.homepage_btn.setProperty('class', 'sidebar_btns') self.homepage_btn.setIcon(QIcon(':/icon/github_icon.png')) self.homepage_btn.setIconSize(QSize(24, 24)) self.homepage_bind = QShortcut(QKeySequence('Ctrl+G'), self) self.about_btn = QPushButton(self.sidebar) self.about_btn.setGeometry(QRect(0, 153, 51, 51)) self.about_btn.setProperty('class', 'sidebar_btns') self.about_btn.setIcon(QIcon(':/icon/about_icon.png')) self.about_btn.setIconSize(QSize(24, 24)) self.about_bind = QShortcut(QKeySequence('Ctrl+A'), self) self.quit_btn = QPushButton(self.sidebar) self.quit_btn.setGeometry(QRect(0, 420, 51, 51)) self.quit_btn.setProperty('class', 'sidebar_btns_quit') self.quit_btn.setIcon(QIcon(':/icon/quit_icon.png')) self.quit_btn.setIconSize(QSize(24, 24)) self.quit_bind = QShortcut(QKeySequence('Ctrl+Q'), self) self.font = QFont() self.font.setPointSize(8) self.font.setStyleStrategy(QFont.PreferAntialias) self.label_refresh = QLabel(self.appswidget) self.label_refresh.setFont(self.font) self.label_refresh.setGeometry(QRect(20, 10, 441, 15)) self.label_info = QLabel(self.appswidget) self.label_info.setFont(self.font) self.label_info.setGeometry(QRect(20, 10, 441, 30)) self.progressbar = QProgressBar(self.appswidget) self.progressbar.setGeometry(QRect(20, 30, 441, 20)) self.layout_widget_checkboxes = QWidget(self.appswidget) self.layout_widget_checkboxes.setGeometry(QRect(20, 55, 155, 311)) self.layout_checkboxes = QVBoxLayout(self.layout_widget_checkboxes) self.layout_checkboxes.setContentsMargins(0, 0, 0, 0) self.layout_widget_checkboxes_2 = QWidget(self.appswidget) self.layout_widget_checkboxes_2.setGeometry(QRect(175, 55, 155, 311)) self.layout_checkboxes_2 = QVBoxLayout(self.layout_widget_checkboxes_2) self.layout_checkboxes_2.setContentsMargins(0, 0, 0, 0) self.layout_widget_checkboxes_3 = QWidget(self.appswidget) self.layout_widget_checkboxes_3.setGeometry(QRect(330, 55, 155, 311)) self.layout_checkboxes_3 = QVBoxLayout(self.layout_widget_checkboxes_3) self.layout_checkboxes_3.setContentsMargins(0, 0, 0, 0) self.layout_widget_labels = QWidget(self.appswidget) self.layout_widget_labels.setGeometry(QRect(20, 390, 350, 16)) self.layout_labels = QHBoxLayout(self.layout_widget_labels) self.layout_labels.setContentsMargins(0, 0, 0, 0) self.label_space = QLabel(self.appswidget) self.label_space.setFont(self.font) self.layout_labels.addWidget(self.label_space) self.label_size = QLabel(self.appswidget) self.label_size.setFont(self.font) self.layout_labels.addWidget(self.label_size) self.layout_widget_buttons = QWidget(self.appswidget) self.layout_widget_buttons.setGeometry(QRect(20, 420, 454, 31)) self.layout_buttons = QHBoxLayout(self.layout_widget_buttons) self.layout_buttons.setContentsMargins(0, 0, 0, 0) self.button_select_all = QPushButton(self.layout_widget_buttons) self.button_select_all.setIcon(QIcon(':/icon/check_icon.png')) self.button_select_all.setIconSize(QSize(18, 18)) self.button_select_all.setLayoutDirection(Qt.RightToLeft) self.layout_buttons.addWidget(self.button_select_all) self.button_select_all.setMinimumSize(100, 30) self.button_select_all.setProperty('class', 'Aqua') self.button_deselect_all = QPushButton(self.layout_widget_buttons) self.button_deselect_all.setIcon(QIcon(':/icon/cancel_icon.png')) self.button_deselect_all.setIconSize(QSize(18, 18)) self.button_deselect_all.setLayoutDirection(Qt.RightToLeft) self.layout_buttons.addWidget(self.button_deselect_all) self.button_deselect_all.setMinimumSize(100, 30) self.button_deselect_all.setProperty('class', 'Aqua') self.layout_buttons.addStretch() self.button_uninstall = QPushButton(self.layout_widget_buttons) self.button_uninstall.setIcon(QIcon(':/icon/trash_icon.png')) self.button_uninstall.setIconSize(QSize(18, 18)) self.button_uninstall.setLayoutDirection(Qt.RightToLeft) self.layout_buttons.addWidget(self.button_uninstall) self.button_uninstall.setMinimumSize(100, 30) self.button_uninstall.setProperty('class', 'Grapefruit') self.setCentralWidget(self.centralwidget) self.retranslateUi() QMetaObject.connectSlotsByName(self) def retranslateUi(self): QToolTip.setFont(self.font) self.setWindowTitle(QCoreApplication.translate("Title", "PyDebloatX")) self.label_info.setText(QCoreApplication.translate("Label", "")) self.app_name_list = list( ( # Convert tuple to list, because lupdate ignores initial lists QCoreApplication.translate("AppName", "3D Builder"), QCoreApplication.translate("AppName", "3D Viewer"), QCoreApplication.translate("AppName", "Alarms and Clock"), QCoreApplication.translate("AppName", "Calculator"), QCoreApplication.translate("AppName", "Calendar and Mail"), QCoreApplication.translate("AppName", "Camera"), QCoreApplication.translate("AppName", "Feedback Hub"), QCoreApplication.translate("AppName", "Get Help"), QCoreApplication.translate("AppName", "Groove Music"), QCoreApplication.translate("AppName", "Maps"), QCoreApplication.translate("AppName", "Messaging"), QCoreApplication.translate("AppName", "Mixed Reality Portal"), QCoreApplication.translate("AppName", "Mobile Plans"), QCoreApplication.translate("AppName", "Money"), QCoreApplication.translate("AppName", "Movies && TV"), QCoreApplication.translate("AppName", "News"), QCoreApplication.translate("AppName", "Office"), QCoreApplication.translate("AppName", "OneNote"), QCoreApplication.translate("AppName", "Paint 3D"), QCoreApplication.translate("AppName", "People"), QCoreApplication.translate("AppName", "Photos"), QCoreApplication.translate("AppName", "Print 3D"), QCoreApplication.translate("AppName", "Skype"), QCoreApplication.translate("AppName", "Snip && Sketch"), QCoreApplication.translate("AppName", "Solitaire"), QCoreApplication.translate("AppName", "Sports"), QCoreApplication.translate("AppName", "Spotify"), QCoreApplication.translate("AppName", "Sticky Notes"), QCoreApplication.translate("AppName", "Tips"), QCoreApplication.translate("AppName", "Translator"), QCoreApplication.translate("AppName", "Voice Recorder"), QCoreApplication.translate("AppName", "Weather"), QCoreApplication.translate("AppName", "Xbox"), QCoreApplication.translate("AppName", "Xbox Game Bar"), QCoreApplication.translate("AppName", "Your Phone"))) self.tooltip_list = list(( QCoreApplication.translate( "ToolTip", "View, create, and personalize 3D objects."), QCoreApplication.translate( "ToolTip", "View 3D models and animations in real-time."), QCoreApplication.translate( "ToolTip", "A combination of alarm clock, world clock, timer, and stopwatch." ), QCoreApplication.translate( "ToolTip", "A calculator that includes standard, scientific, and programmer modes, as well as a unit converter." ), QCoreApplication.translate( "ToolTip", "Stay up to date with email and schedule managing."), QCoreApplication.translate( "ToolTip", "Point and shoot to take pictures on Windows 10."), QCoreApplication.translate( "ToolTip", "Provide feedback about Windows and apps by sharing suggestions or problems." ), QCoreApplication.translate( "ToolTip", "Provide a way to ask a question and get recommended solutions or contact assisted support." ), QCoreApplication.translate( "ToolTip", "Listen to music on Windows, iOS, and Android devices."), QCoreApplication.translate( "ToolTip", "Search for places to get directions, business info, and reviews." ), QCoreApplication.translate( "ToolTip", "Quick, reliable SMS, MMS and RCS messaging from your phone."), QCoreApplication.translate( "ToolTip", "Discover Windows Mixed Reality and dive into more than 3,000 games and VR experiences from Steam VR and Microsoft Store." ), QCoreApplication.translate( "ToolTip", "Sign up for a data plan and connect with mobile operators in your area. You will need a supported SIM card." ), QCoreApplication.translate( "ToolTip", "Finance calculators, currency exchange rates and commodity prices from around the world." ), QCoreApplication.translate( "ToolTip", "All your movies and TV shows, all in one place, on all your devices." ), QCoreApplication.translate( "ToolTip", "Deliver breaking news and trusted, in-depth reporting from the world\'s best journalists." ), QCoreApplication.translate( "ToolTip", "Find all your Office apps and files in one place."), QCoreApplication.translate( "ToolTip", "Digital notebook for capturing and organizing everything across your devices." ), QCoreApplication.translate( "ToolTip", "Make 2D masterpieces or 3D models that you can play with from all angles." ), QCoreApplication.translate( "ToolTip", "Connect with all your friends, family, colleagues, and acquaintances in one place." ), QCoreApplication.translate( "ToolTip", "View and edit your photos and videos, make movies, and create albums." ), QCoreApplication.translate( "ToolTip", "Quickly and easily prepare objects for 3D printing on your PC." ), QCoreApplication.translate( "ToolTip", "Instant message, voice or video call application."), QCoreApplication.translate( "ToolTip", "Quickly annotate screenshots, photos and other images and save, paste or share with other apps." ), QCoreApplication.translate( "ToolTip", "Solitaire is one of the most played computer card games of all time." ), QCoreApplication.translate( "ToolTip", "Live scores and in-depth game experiences for more than 150 leagues." ), QCoreApplication.translate( "ToolTip", "Play your favorite songs and albums free on Windows 10 with Spotify." ), QCoreApplication.translate( "ToolTip", "Create notes, type, ink or add a picture, add text formatting, or stick them to the desktop." ), QCoreApplication.translate( "ToolTip", "Provide users with information and tips about operating system features." ), QCoreApplication.translate( "ToolTip", "Translate text and speech, have translated conversations, and even download AI-powered language packs to use offline." ), QCoreApplication.translate( "ToolTip", "Record sounds, lectures, interviews, and other events."), QCoreApplication.translate( "ToolTip", "Latest weather conditions, accurate 10-day and hourly forecasts." ), QCoreApplication.translate( "ToolTip", "Browse the catalogue, view recommendations, and discover PC games with Xbox Game Pass." ), QCoreApplication.translate( "ToolTip", "Instant access to widgets for screen capture and sharing, and chatting with Xbox friends." ), QCoreApplication.translate( "ToolTip", "Link your Android phone and PC to view and reply to text messages, access mobile apps, and receive notifications." ))) self.app_data_list = [{ "name": "*Microsoft.3DBuilder*", "link": "/?PFN=Microsoft.3DBuilder_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.Microsoft3DViewer*", "link": "/?PFN=Microsoft.Microsoft3DViewer_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.WindowsAlarms*", "link": "/?PFN=Microsoft.WindowsAlarms_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.WindowsCalculator*", "link": "/?PFN=Microsoft.WindowsCalculator_8wekyb3d8bbwe", "size": 0 }, { "name": "*microsoft.windowscommunicationsapps*", "link": "/?PFN=Microsoft.windowscommunicationsapps_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.WindowsCamera*", "link": "/?PFN=Microsoft.WindowsCamera_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.WindowsFeedbackHub*", "link": "/?PFN=Microsoft.WindowsFeedbackHub_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.GetHelp*", "link": "/?PFN=Microsoft.Gethelp_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.ZuneMusic*", "link": "/?PFN=Microsoft.ZuneMusic_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.WindowsMaps*", "link": "/?PFN=Microsoft.WindowsMaps_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.Messaging*", "link": "/?PFN=Microsoft.Messaging_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.MixedReality.Portal*", "link": "/?PFN=Microsoft.MixedReality.Portal_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.OneConnect*", "link": "/?PFN=Microsoft.OneConnect_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.BingFinance*", "link": "/?PFN=Microsoft.BingFinance_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.ZuneVideo*", "link": "/?PFN=Microsoft.ZuneVideo_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.BingNews*", "link": "/?PFN=Microsoft.BingNews_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.MicrosoftOfficeHub*", "link": "/?PFN=Microsoft.MicrosoftOfficeHub_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.Office.OneNote*", "link": "/?PFN=Microsoft.Office.OneNote_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.MSPaint*", "link": "/?PFN=Microsoft.MSPaint_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.People*", "link": "/?PFN=Microsoft.People_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.Windows.Photos*", "link": "/?PFN=Microsoft.Windows.Photos_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.Print3D*", "link": "/?PFN=Microsoft.Print3D_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.SkypeApp*", "link": "/?PFN=Microsoft.SkypeApp_kzf8qxf38zg5c", "size": 0 }, { "name": "*Microsoft.ScreenSketch*", "link": "/?PFN=Microsoft.ScreenSketch_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.MicrosoftSolitaireCollection*", "link": "/?PFN=Microsoft.MicrosoftSolitaireCollection_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.BingSports*", "link": "/?PFN=Microsoft.BingSports_8wekyb3d8bbwe", "size": 0 }, { "name": "*SpotifyAB.SpotifyMusic*", "link": "/?PFN=SpotifyAB.SpotifyMusic_zpdnekdrzrea0", "size": 0 }, { "name": "*Microsoft.MicrosoftStickyNotes*", "link": "/?PFN=Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.Getstarted*", "link": "/?PFN=Microsoft.Getstarted_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.BingTranslator*", "link": "/?PFN=Microsoft.BingTranslator_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.WindowsSoundRecorder*", "link": "/?PFN=Microsoft.WindowsSoundRecorder_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.BingWeather*", "link": "/?PFN=Microsoft.BingWeather_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.GamingApp*", "link": "/?PFN=Microsoft.GamingApp_8wekyb3d8bbwe", "size": 0 }, { "name": "*Xbox*", "link": "/?PFN=Microsoft.XboxGameOverlay_8wekyb3d8bbwe", "size": 0 }, { "name": "*Microsoft.YourPhone*", "link": "/?PFN=Microsoft.YourPhone_8wekyb3d8bbwe", "size": 0 }] if version.parse(platform.version()) >= version.parse("10.0.19041"): insort(self.app_name_list, QCoreApplication.translate("AppName", "Cortana")) cortana_index = self.app_name_list.index("Cortana") self.tooltip_list.insert( cortana_index, QCoreApplication.translate("ToolTip", "Personal intelligence assistant.")) self.app_data_list.insert( cortana_index, { "name": "*Microsoft.549981C3F5F10*", "link": "/?PFN=Microsoft.549981C3F5F10_8wekyb3d8bbwe", "size": 0 }) self.checkbox_list = [] for i, _ in enumerate(self.app_name_list): self.checkbox_list.append(QCheckBox()) if i % 3 == 2: self.layout_checkboxes_3.addWidget(self.checkbox_list[i]) elif i % 3 == 1: self.layout_checkboxes_2.addWidget(self.checkbox_list[i]) else: self.layout_checkboxes.addWidget(self.checkbox_list[i]) self.apps_dict = {} for i, checkbox in enumerate(self.checkbox_list): checkbox.setText(self.app_name_list[i]) checkbox.setToolTip(self.tooltip_list[i]) checkbox.setFont(self.font) self.apps_dict[checkbox] = self.app_data_list[i] self.label_space.setText( QCoreApplication.translate("Label", "Total amount of disk space:")) self.label_size.setText(QCoreApplication.translate("Label", "0 MB")) self.button_select_all.setText( QCoreApplication.translate("Button", "Select All")) self.button_deselect_all.setText( QCoreApplication.translate("Button", "Deselect All")) self.button_uninstall.setText( QCoreApplication.translate("Button", "Uninstall"))
pixmap = self.movie.currentPixmap() pixmap = pixmap.scaled(self.my_size) 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)
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 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 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")