def user_map(self): """Slot to show user map from bgg to ludopedia""" user_map_dialog = QDialog(self) user_map_dialog.setModal(True) bgg_to_ludo = self.get_bgg_to_ludo_users() user_list = [f'{key} -> {value}' for key, value in bgg_to_ludo.items()] list_widget = QListWidget(user_map_dialog) list_widget.addItems(user_list) list_widget.setResizeMode(QListView.Adjust) list_widget.sortItems() grid_layout = QGridLayout(user_map_dialog) grid_layout.addWidget(list_widget, 1, 1) user_map_dialog.resize(400, 400) user_map_dialog.show()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.textEdit = QTextEdit() self.setCentralWidget(self.textEdit) self.createActions() self.createMenus() self.createToolBars() self.createStatusBar() self.createDockWindows() self.setWindowTitle("Dock Widgets") self.newLetter() def newLetter(self): self.textEdit.clear() cursor = self.textEdit.textCursor() cursor.movePosition(QTextCursor.Start) topFrame = cursor.currentFrame() topFrameFormat = topFrame.frameFormat() topFrameFormat.setPadding(16) topFrame.setFrameFormat(topFrameFormat) textFormat = QTextCharFormat() boldFormat = QTextCharFormat() boldFormat.setFontWeight(QFont.Bold) italicFormat = QTextCharFormat() italicFormat.setFontItalic(True) tableFormat = QTextTableFormat() tableFormat.setBorder(1) tableFormat.setCellPadding(16) tableFormat.setAlignment(Qt.AlignRight) cursor.insertTable(1, 1, tableFormat) cursor.insertText("The Firm", boldFormat) cursor.insertBlock() cursor.insertText("321 City Street", textFormat) cursor.insertBlock() cursor.insertText("Industry Park") cursor.insertBlock() cursor.insertText("Some Country") cursor.setPosition(topFrame.lastPosition()) cursor.insertText(QDate.currentDate().toString("d MMMM yyyy"), textFormat) cursor.insertBlock() cursor.insertBlock() cursor.insertText("Dear ", textFormat) cursor.insertText("NAME", italicFormat) cursor.insertText(",", textFormat) for i in range(3): cursor.insertBlock() cursor.insertText("Yours sincerely,", textFormat) for i in range(3): cursor.insertBlock() cursor.insertText("The Boss", textFormat) cursor.insertBlock() cursor.insertText("ADDRESS", italicFormat) def print_(self): document = self.textEdit.document() printer = QPrinter() dlg = QPrintDialog(printer, self) if dlg.exec_() != QDialog.Accepted: return document.print_(printer) self.statusBar().showMessage("Ready", 2000) def save(self): filename, _ = QFileDialog.getSaveFileName(self, "Choose a file name", '.', "HTML (*.html *.htm)") if not filename: return file = QFile(filename) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning( self, "Dock Widgets", "Cannot write file %s:\n%s." % (filename, file.errorString())) return out = QTextStream(file) QApplication.setOverrideCursor(Qt.WaitCursor) out << self.textEdit.toHtml() QApplication.restoreOverrideCursor() self.statusBar().showMessage("Saved '%s'" % filename, 2000) def undo(self): document = self.textEdit.document() document.undo() def insertCustomer(self, customer): if not customer: return customerList = customer.split(', ') document = self.textEdit.document() cursor = document.find('NAME') if not cursor.isNull(): cursor.beginEditBlock() cursor.insertText(customerList[0]) oldcursor = cursor cursor = document.find('ADDRESS') if not cursor.isNull(): for i in customerList[1:]: cursor.insertBlock() cursor.insertText(i) cursor.endEditBlock() else: oldcursor.endEditBlock() def addParagraph(self, paragraph): if not paragraph: return document = self.textEdit.document() cursor = document.find("Yours sincerely,") if cursor.isNull(): return cursor.beginEditBlock() cursor.movePosition(QTextCursor.PreviousBlock, QTextCursor.MoveAnchor, 2) cursor.insertBlock() cursor.insertText(paragraph) cursor.insertBlock() cursor.endEditBlock() def about(self): QMessageBox.about( self, "About Dock Widgets", "The <b>Dock Widgets</b> example demonstrates how to use " "Qt's dock widgets. You can enter your own text, click a " "customer to add a customer name and address, and click " "standard paragraphs to add them.") def createActions(self): self.newLetterAct = QAction(QIcon.fromTheme('document-new', QIcon(':/images/new.png')), "&New Letter", self, shortcut=QKeySequence.New, statusTip="Create a new form letter", triggered=self.newLetter) self.saveAct = QAction(QIcon.fromTheme('document-save', QIcon(':/images/save.png')), "&Save...", self, shortcut=QKeySequence.Save, statusTip="Save the current form letter", triggered=self.save) self.printAct = QAction(QIcon.fromTheme('document-print', QIcon(':/images/print.png')), "&Print...", self, shortcut=QKeySequence.Print, statusTip="Print the current form letter", triggered=self.print_) self.undoAct = QAction(QIcon.fromTheme('edit-undo', QIcon(':/images/undo.png')), "&Undo", self, shortcut=QKeySequence.Undo, statusTip="Undo the last editing action", triggered=self.undo) self.quitAct = QAction("&Quit", self, shortcut="Ctrl+Q", statusTip="Quit the application", triggered=self.close) self.aboutAct = QAction("&About", self, statusTip="Show the application's About box", triggered=self.about) self.aboutQtAct = QAction("About &Qt", self, statusTip="Show the Qt library's About box", triggered=QApplication.instance().aboutQt) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.newLetterAct) self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.printAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.quitAct) self.editMenu = self.menuBar().addMenu("&Edit") self.editMenu.addAction(self.undoAct) self.viewMenu = self.menuBar().addMenu("&View") self.menuBar().addSeparator() self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.aboutAct) self.helpMenu.addAction(self.aboutQtAct) def createToolBars(self): self.fileToolBar = self.addToolBar("File") self.fileToolBar.addAction(self.newLetterAct) self.fileToolBar.addAction(self.saveAct) self.fileToolBar.addAction(self.printAct) self.editToolBar = self.addToolBar("Edit") self.editToolBar.addAction(self.undoAct) def createStatusBar(self): self.statusBar().showMessage("Ready") def createDockWindows(self): dock = QDockWidget("Customers", self) dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.customerList = QListWidget(dock) self.customerList.addItems( ("John Doe, Harmony Enterprises, 12 Lakeside, Ambleton", "Jane Doe, Memorabilia, 23 Watersedge, Beaton", "Tammy Shea, Tiblanka, 38 Sea Views, Carlton", "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal", "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston", "Sally Hobart, Tiroli Tea, 67 Long River, Fedula")) dock.setWidget(self.customerList) self.addDockWidget(Qt.RightDockWidgetArea, dock) self.viewMenu.addAction(dock.toggleViewAction()) dock = QDockWidget("Paragraphs", self) self.paragraphsList = QListWidget(dock) self.paragraphsList.addItems( ("Thank you for your payment which we have received today.", "Your order has been dispatched and should be with you within " "28 days.", "We have dispatched those items that were in stock. The rest of " "your order will be dispatched once all the remaining items " "have arrived at our warehouse. No additional shipping " "charges will be made.", "You made a small overpayment (less than $5) which we will keep " "on account for you, or return at your request.", "You made a small underpayment (less than $1), but we have sent " "your order anyway. We'll add this underpayment to your next " "bill.", "Unfortunately you did not send enough money. Please remit an " "additional $. Your order will be dispatched as soon as the " "complete amount has been received.", "You made an overpayment (more than $5). Do you wish to buy more " "items, or should we return the excess to you?")) dock.setWidget(self.paragraphsList) self.addDockWidget(Qt.RightDockWidgetArea, dock) self.viewMenu.addAction(dock.toggleViewAction()) self.customerList.currentTextChanged.connect(self.insertCustomer) self.paragraphsList.currentTextChanged.connect(self.addParagraph)
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")