class AreasBrowserDialog(BaseDialog): def __init__(self, parent, area_name, areas): super().__init__(parent, _("Select the area you mean"), _("&Select"), _("&Close")) self._areas = list(areas.items()) for id, (parent_name, data) in self._areas: self._areas_list.addItem( _("{area_name}, {parent_name}").format( area_name=area_name, parent_name=parent_name)) self._areas_list.setCurrentRow(0) def create_ui(self): areas_label = QLabel(_("Areas")) self.layout.addWidget(areas_label, 0, 0) self._areas_list = QListWidget(self) areas_label.setBuddy(self._areas_list) self._areas_list.currentRowChanged.connect(self.on_areas_list_listbox) self.layout.addWidget(self._areas_list, 1, 0) props_label = QLabel(_("Area properties")) self.layout.addWidget(props_label, 0, 1) self._area_props = QListWidget() props_label.setBuddy(self._area_props) self.layout.addWidget(self._area_props, 1, 1) def on_areas_list_listbox(self, index): self._area_props.clear() for key, value in self._areas[index][1][1].items(): self._area_props.addItem(f"{underscored_to_words(key)}: {value}") self._area_props.addItem( _("Area id: {}").format(self._areas[index][0])) @property def selected_area_id(self): return self._areas[self._areas_list.currentRow()][0]
class SignalGrouper(QDialog): def __init__(self, chartData, parent=None): QDialog.__init__(self, parent) self.chartData = chartData self._create() def _create(self): self.mLayout = QVBoxLayout(self) self.gSelector = QListWidget() groups = self.chartData.getDataGroups() self.gSelector.addItems(groups) self.gSelector.currentTextChanged.connect(self._updateGroupList) self.chartData.dataGroupAdded.connect(self.gSelector.addItem) self.chartData.dataGroupAdded.connect(self.gSelector.addItem) self.mLayout.addWidget(self.gSelector) self.sSelector = QListWidget() self.mLayout.addWidget(self.sSelector) groupBtn = QPushButton('Create group from selected') groupBtn.clicked.connect(self.createNewGroup) self.mLayout.addWidget(groupBtn) def _updateGroupList(self): newGroup = self.gSelector.currentItem().text() sStruct = self.chartData[newGroup].getColStructure() self.sSelector.clear() for ws in sStruct: firstChannel = sStruct[ws][0] isOneSignal = self.chartData[newGroup][firstChannel][ws][0] if isOneSignal: item = QListWidgetItem(ws, self.sSelector) item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setCheckState(Qt.Unchecked) def createNewGroup(self): checkList = [] for i in range(self.sSelector.count()): sItem = self.sSelector.item(i) if sItem.checkState() == Qt.Checked: checkList.append(sItem.text()) if len(checkList) > 0: groupName, result = QInputDialog().getText(self, 'Input', 'Enter group name:') if result: ws = self.gSelector.currentItem().text() sStruct = self.chartData[ws].getColStructure(checkList) sKeys = list(sStruct.keys()) for s in range(len(sKeys)): if sStruct[sKeys[s]] != sStruct[sKeys[s-1]]: print('Signals have diffrent channel sets') return self.chartData.appendSignalGroup(ws, groupName, sStruct[sKeys[0]], checkList) else: return else: return
class DWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) hlayout = QHBoxLayout() ##################################################### Left self.menu_level = 0 self.item_list = QListWidget() self.fill_main_item_list() #self.item_list.setMinimumWidth(256) self.item_list.setMaximumWidth(300) self.item_list.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.item_list.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.item_list.itemClicked[QListWidgetItem].connect(self.item_clicked) ##################################################### Right b = QTabWidget() b.addTab(QWidget(), "Primera") b.addTab(QWidget(), "Segunda") b.setMinimumWidth(768) #b.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) b.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) hlayout.addWidget(self.item_list) hlayout.addWidget(b) self.setLayout(hlayout) @Slot() def item_clicked(self, item): self.menu_level += 1 item_text = item.text() if self.menu_level < 2: self.item_list.clear() item = QListWidgetItem("< Back") item.setSizeHint(QSize(item.sizeHint().width(), 50)) self.item_list.addItem(item) for i in range(10): item = QListWidgetItem("Sub menu {} ({})".format(i, item_text)) item.setSizeHint(QSize(item.sizeHint().width(), 50)) self.item_list.addItem(item) elif "Back" in item_text: self.item_list.clear() self.menu_level = 0 self.fill_main_item_list() def fill_main_item_list(self): for i in range(10): item = QListWidgetItem("Menu {}".format(i)) item.setSizeHint(QSize(item.sizeHint().width(), 50)) self.item_list.addItem(item)
class ServerGUI(QMainWindow): server = None def __init__(self): super().__init__() self.setWindowTitle("Stopped") self.start_button = QPushButton("Start") self.clients_list = QListWidget() self.start_button.clicked.connect(self.start_server) # Setting layout self.layout = QVBoxLayout() self.layout.addWidget(self.start_button) self.layout.addWidget(QLabel("Clients:")) self.layout.addWidget(self.clients_list) widget = QWidget() widget.setLayout(self.layout) self.setCentralWidget(widget) self.setIcon() def setIcon(self): appIcon = QIcon("icons/server.png") self.setWindowIcon(appIcon) def stop_server(self): self.server.stop_server() self.server = None self.start_button.clicked.connect(self.start_server) self.start_button.setText("Start") self.setWindowTitle("Stopped") def start_server(self): ip, port = "0.0.0.0", random.randint(8000, 8999) if self.server is None: self.server = Server(ip, port, server_gui=self) self.server.start_server() self.start_button.setText("Stop") self.start_button.clicked.connect(self.stop_server) self.setWindowTitle(f"{ip}:{port}") def update_client_list(self, clients): self.clients_list.clear() for client in clients: self.clients_list.addItem(f"{client.username}:{client.socket_id}")
class ppDiscoverWidget(QWidget, Discovery): DeviceChanged = Signal(ppDevice) def __init__(self): QWidget.__init__(self) Discovery.__init__(self, DeviceID.BEBOP_FAMILY) self.button = QPushButton("Refresh Devices") self.lst = QListWidget(self) self.layout = QVBoxLayout() self.layout.addWidget(self.lst) self.layout.addWidget(self.button) self.setLayout(self.layout) self.button.clicked.connect(self.discover) self.lst.currentItemChanged.connect(self.on_item_changed) self.setFixedWidth(140) def add_service(self, zeroconf, type, name): """ Internal function for zeroconf.ServiceBrowser. """ info = super().add_service(zeroconf, type, name) # self.devices.append(info) item = ppDevice(info) self.lst.addItem(item) # item2=ppDevice(info) # self.lst.addItem(item2) print('[' + item.name + '-' + item.ip + ']') item.connect() item.start_stream() def discover(self, wd=2): print("searching devices...") self.lst.clear() #self.devices = [] super().start() super().wait_for_change(2) super().stop() print("OK") def on_item_changed(self, curr, prev): print("switch on " + curr.name) self.DeviceChanged.emit(curr) @property def curentDevice(self): return self.lst.currentItem()
class AutocompleteWidget(QDialog): WIDTH = 300 HEIGHT = 120 def __init__(self, suggestions: list): super(AutocompleteWidget, self).__init__() self.widget = QListWidget() self.widget.setStyleSheet("background-color: #232323;") self.setWindowFlags(Qt.FramelessWindowHint | Qt.Window) self.vbox = QVBoxLayout() self.label = QLabel("") self.vbox.addWidget(self.widget, 10) self.vbox.addWidget(self.label, 1) self.setLayout(self.vbox) self.updateSuggestionList(suggestions) self.result = None def updateSuggestionList(self, suggestions): self.widget.clear() if suggestions: for keyword in suggestions: self.widget.addItem(AutoCompleteListWidgetItem(keyword)) self.label.setText("Number of suggestions: {}.".format( len(suggestions))) else: self.label.setText("No available suggestions.") self.setSize() def setSize(self): self.setFixedSize(self.minimumSizeHint()) self.setFixedHeight(AutocompleteWidget.HEIGHT) self.setFixedWidth(AutocompleteWidget.WIDTH) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() if e.key() == Qt.Key_Return: selectedItems = self.widget.selectedItems() if len(selectedItems) > 0: self.result = selectedItems[0] self.close() if e.key() == Qt.Key_Backspace: self.close() if e.key() == Qt.Key_Left: self.parent().setFocus()
class SimpleTodoPlus(QWidget): def __init__(self): QWidget.__init__(self) self.todo_list_widget = QListWidget(self) self.todo_list_widget.itemChanged.connect(self.onItemChanged) self.add_todo_btn = QPushButton("Add Todo", self) self.add_todo_btn.clicked.connect(self.add_todo_btn_clicked) self.remove_todo_btn = QPushButton("Remove Todo", self) self.remove_todo_btn.clicked.connect(self.remove_todo_btn_clicked) self.clear_todo_btn = QPushButton("Clear Todo", self) self.clear_todo_btn.clicked.connect(self.clear_todo_btn_clicked) vbox_layout = QVBoxLayout(self) vbox_layout.addWidget(self.todo_list_widget) hbox_layout = QHBoxLayout() hbox_layout.addWidget(self.add_todo_btn) hbox_layout.addWidget(self.remove_todo_btn) hbox_layout.addWidget(self.clear_todo_btn) vbox_layout.addLayout(hbox_layout) def add_todo_btn_clicked(self): item = QListWidgetItem(f"Todo {self.todo_list_widget.count() + 1}") item.setFlags(item.flags() | Qt.ItemIsUserCheckable | Qt.ItemIsEditable) item.setCheckState(Qt.Unchecked) self.todo_list_widget.addItem(item) self.todo_list_widget.edit(self.todo_list_widget.indexFromItem(item)) def remove_todo_btn_clicked(self): if self.todo_list_widget.count(): self.todo_list_widget.takeItem(self.todo_list_widget.currentRow()) def clear_todo_btn_clicked(self): self.todo_list_widget.clear() def onItemChanged(self, item): font = item.font() font.setStrikeOut(item.checkState() == Qt.Checked) item.setFont(font)
class MyWidget(QWidget): def __init__(self): QWidget.__init__(self) self.search = QLineEdit() self.results = QListWidget() self.layout = QVBoxLayout() self.layout.addWidget(self.search) self.layout.addWidget(self.results) self.setLayout(self.layout) self.search.returnPressed.connect(self.search_word) @Slot() def search_word(self): self.results.clear() for word in find_similar_ending_words(self.search.text()): self.results.addItem(word)
def populate_list_with_track_info(track: MKVTrack, list_widget: QListWidget): """ Populate the listwidget with the selected track's information :param self: :param track: :param list_widget: :return: """ track_name = "N/A" if track.track_name is not None: track_name = track.track_name list_widget.clear() list_widget.addItem(" File Path: " + track.file_path) list_widget.addItem(" Track ID: " + str(track.track_id)) list_widget.addItem(" Track Name: " + track_name) list_widget.addItem(" Track Type: " + track._track_type) list_widget.addItem(" Track Codec: " + track._track_codec) list_widget.addItem(" Language: " + track.language) list_widget.addItem(" Default Track: " + str(track.default_track)) list_widget.addItem(" Forced Track: " + str(track.forced_track))
def clear(self) -> None: QListWidget.clear(self) # 防止异步加载时,信息错乱 QtTask().CancelTasks(self.GetName())
class ProjectSwitcher(QDialog): def __init__(self, configurationManager: ConfigurationManager, projectComboBox): super(ProjectSwitcher, self).__init__() self.setWindowFlags(Qt.FramelessWindowHint | Qt.Window) self.configurationManager = configurationManager self.projectComboBox = projectComboBox self.latestProjectIndex = -1 self.setStyleSheet("background-color: #232323; color: white;") self.projectList = QListWidget() self.vbox = QVBoxLayout() self.pathLabel = QLabel() self.pathLabel.setStyleSheet("font-size: 10px; color: grey;") self.vbox.addWidget(QLabel("<center>Project switcher</center>"), 1) self.vbox.addWidget(self.projectList, 10) self.vbox.addWidget(self.pathLabel, 1) self.setLayout(self.vbox) def showSwitcher(self): self.latestProjectIndex = self.getCurrentProjectIndex() self.updateProjectList() self.updateProjectListCurrentItem(self.latestProjectIndex) self.setFixedSize(self.sizeHint()) self.setFixedWidth(500) self.show() def getCurrentProjectIndex(self): for i in range(len(self.configurationManager.allProjects)): if self.configurationManager.allProjects[i].proxy.getProjectPath( ) == self.configurationManager.currentProject.proxy.getProjectPath( ): return i return -1 # should never execute def updateProjectList(self): self.projectList.clear() for project in self.configurationManager.allProjects: self.projectList.addItem(ProjectSwitcherListItem(project.proxy)) def updateProjectListCurrentItem(self, index): self.projectList.setCurrentRow(index) projectProxy = self.projectList.currentItem().projectProxy self.pathLabel.setText(projectProxy.getProjectPath()) def hideSwitcher(self): if self.latestProjectIndex >= -1: self.projectComboBox.setCurrentText( self.projectList.currentItem().projectProxy.path) self.hide() def keyPressEvent(self, event): if event.key() == Qt.Key_Tab or event.key( ) == Qt.Key_Down or event.key() == Qt.Key_E: self.latestProjectIndex = (self.latestProjectIndex + 1) % len( self.configurationManager.allProjects) elif event.key() == Qt.Key_Up or event.key() == Qt.Key_Backtab: self.latestProjectIndex -= 1 if self.latestProjectIndex < 0: self.latestProjectIndex = len( self.configurationManager.allProjects) - 1 self.updateProjectListCurrentItem(self.latestProjectIndex) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Backtab: return if event.modifiers() != Qt.ControlModifier: if self.latestProjectIndex != -1: self.projectComboBox.setCurrentText( self.projectList.currentItem().projectProxy.path) self.latestProjectIndex = -1 self.hideSwitcher() def focusOutEvent(self, event): super(ProjectSwitcher, self).focusOutEvent(event) self.hide()
class DatasheetView(QMainWindow): def __init__(self, pdfPath=None, pageNumber=1): super().__init__() # initialize data files # self.fileStore = path.join(path.curdir, "/files") # mkdir(self.fileStore) self.svgFiles = [] # window dimensions self.top = 300 self.left = 800 self.width = 860 self.height = 980 self.setGeometry(self.left, self.top, self.width, self.height) # window title self.setWindowTitle("Hello") # sets up main layout -- splitters self.initUILayout() self.initUIToolbar() self.populatePDF(pdfPath, pageNumber) self.show() def initUILayout(self): # set left-side, Dynamic View self.dynamicViewDisplay = QLabel() self.vBoxA = QVBoxLayout() self.vBoxA.addWidget(self.dynamicViewDisplay) self.groupA = QGroupBox() self.groupA.setTitle("Dynamic Veiw") self.groupA.setLayout(self.vBoxA) # set left-side, Static View self.staticViewDisplay = QLabel() self.vBoxB = QVBoxLayout() self.vBoxB.addWidget(self.staticViewDisplay) self.groupB = QGroupBox() self.groupB.setTitle("Static View") self.groupB.setLayout(self.vBoxB) # add Dynamic and Static Views to resizeable left-side Splitter self.altViewSplit = QSplitter(Qt.Vertical) self.altViewSplit.addWidget(self.groupA) self.altViewSplit.addWidget(self.groupB) # set up Tools View section self.toolsTabView = QTabWidget() self.toolsTabView.setTabsClosable(True) self.toolsTabView.setMovable(True) self.toolsTabView.setDocumentMode(True) # self.toolsTabView.setTabBarAutoHide(True) # add attribute for storing page notes self.notesDB = [] self.notesDisplay = QListWidget(self) self.notesDisplay.setMaximumHeight(200) # add ToC to Tools View self.ToCListView = QListWidget() self.toolsTabView.addTab(self.ToCListView, "Table of Contents") # add notes list to tools view self.toolsTabView.addTab(self.notesDisplay, "Notes") # add tools view to the left-side splitter self.altViewSplit.addWidget(self.toolsTabView) # set right-side view -- SVG Viewer self.mainDisplay = QSvgWidget() self.vBoxMain = QVBoxLayout() self.vBoxMain.addWidget(self.mainDisplay) self.notesArea = QLineEdit() self.notesArea.setPlaceholderText("Add a note about this page...") self.notesArea.returnPressed.connect(self.onAddNote) self.vBoxMain.addWidget(self.notesArea) self.mainViewGroup = QGroupBox() self.mainViewGroup.setTitle("Main View") self.mainViewGroup.setLayout(self.vBoxMain) # join both sides together self.leftRightSplit = QSplitter(Qt.Horizontal) self.leftRightSplit.addWidget(self.altViewSplit) self.leftRightSplit.addWidget(self.mainViewGroup) self.setCentralWidget(self.leftRightSplit) def initUIToolbar(self): mainMenu = self.menuBar() # get the menu bar already in use by this QMainWindow class fileMenu = mainMenu.addMenu("File") editMenu = mainMenu.addMenu("Edit") LayoutMenu = mainMenu.addMenu("Layout") AboutMenu = mainMenu.addMenu("About") saveAction = fileMenu.addAction("Save") quitAction = fileMenu.addAction("Exit Bettersheets") quitAction.triggered.connect(self.quitApp) copyAction = editMenu.addAction("Copy") resetAction = LayoutMenu.addAction("Reset Default Layout") # mainMenu.setNativeMenuBar(True) # mainMenu.show() self. toolBar = self.addToolBar("Tools") self.toolBar.addAction(saveAction) self.toolBar.addAction(copyAction) def contextMenuEvent(self, event): # return super().contextMenuEvent(event) contextMenu = QMenu() selectAction = contextMenu.addAction("Select Area") extractAction = contextMenu.addAction("Extract Content") openAction = contextMenu.addAction("Open PDF") closeAction = contextMenu.addAction("Close PDF") quitAction = contextMenu.addAction("Quit") triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos())) if triggered_action == quitAction: self.quitApp() def quitApp(self): self.close() def onAddNote(self): print("note added") text = self.notesArea.text() if text: self.notesDB.append(text) self.notesDisplay.clear() self.notesDisplay.addItems(self.notesDB) self.notesArea.clear() def populatePDF(self, pdfPath, pageNumber): if pdfPath: self.document = PDFContext(pdfPath, pageNumber) ToC = self.document.getToC() ToC_headings_list = [x[1] for x in ToC] self.ToCListView.clear() self.ToCListView.addItems(ToC_headings_list) # display page in main view self.document.openPDF(pdfPath, pageNumber) self.SVGString = self.document.getRender(self.document.currentPageNumber) # set filename of current PDF self.pdfName = path.split(pdfPath)[1].split('.')[0] # write current page to .svg file file_loc = self._writeSVGToFile_(self.pdfName, pageNumber, self.SVGString) # open the file we just wrote to self.mainDisplay.load(file_loc) @staticmethod def _writeSVGToFile_(pdfName: str, pageNumber: int, svg_string: str) -> str: """ return the full file path we just wrote """ file_loc = f"./src/main/files/{pdfName}-page-{pageNumber}.svg" with open(file_loc , 'w') as f: f.write(svg_string) print("File_loc: ", file_loc) return file_loc
class PersonaUI(QWidget): """ Widget for Persona creation view. :param MainFrame mainframe: application mainframe :param QWidget op: parent widget """ def __init__(self, mainframe, op): QWidget.__init__(self) self.mainframe = mainframe self.op = op self.grid = QGridLayout() self.setLayout(self.grid) self.listP = None self.listLS = None self.listEL1 = None self.listEL2 = None self.nameT = None self.levelT = None self.textT = None self.strT = None self.magT = None self.endT = None self.agiT = None self.luckT = None self.createFrame = None self.buttonFrame = None self.bfgrid = None # Actual create frame variables. self.cfgrid = None self.lsdic = None self.slashO = None self.strikeO = None self.pierceO = None self.fireO = None self.iceO = None self.windO = None self.elecO = None self.darkO = None self.lightO = None self.arcO = None self.iSpellOs = None self.lsSpellO = None self.lslevel = None self.initUI(True) def initUI(self, infoDump): """ Initializes the basic UI showing the list of Personas. Does a lot of stuff. :param dict infoDump: not sure lol """ self.mainframe.setWindowTitle("Persona Creator") if not infoDump: self.createFrameDraw() self.initButtonFrame(infoDump) self.listP = QListWidget(self) self.grid.addWidget(self.listP, 0, 3, 2, 1) temp = json_reader.readPerNames() self.listP.addItems(temp) def initButtonFrame(self, infoDump): """ Initializes the buttonframes that are present in all Persona creator views. :param dict infoDump: not sure lol """ self.buttonFrame = QWidget(self) self.bfgrid = QGridLayout() self.buttonFrame.setLayout(self.bfgrid) self.grid.addWidget(self.buttonFrame, 3, 0, 1, 4) new = QPushButton(self.buttonFrame, text="New") new.clicked.connect(self.new) self.bfgrid.addWidget(new, 4, 0) back = QPushButton(self.buttonFrame, text="Back") back.clicked.connect(self.back) self.bfgrid.addWidget(back, 4, 4) remove = QPushButton(self.buttonFrame, text="Remove") remove.clicked.connect(self.remove) self.bfgrid.addWidget(remove, 4, 3) edit = QPushButton(self.buttonFrame, text="Edit") edit.clicked.connect(self.edit) self.bfgrid.addWidget(edit, 4, 2) if not infoDump: save = QPushButton(self.buttonFrame, text="Save") save.clicked.connect(self.save) self.bfgrid.addWidget(save, 4, 1) def createFrameDraw(self): """ Initializes the GUI of the actual creation frame view. Does a LOT of stuff. """ self.createFrame = QWidget(self) self.cfgrid = QGridLayout() self.createFrame.setLayout(self.cfgrid) self.grid.addWidget(self.createFrame, 0, 0, 2, 2) self.lsdic = {} nameL = QLabel(self.createFrame, text="Name:") self.cfgrid.addWidget(nameL, 0, 0) self.nameT = QLineEdit(self.createFrame) self.nameT.setFixedSize(100, 20) self.cfgrid.addWidget(self.nameT, 0, 1) strL = QLabel(self.createFrame, text="Str") self.cfgrid.addWidget(strL, 0, 2) self.strT = QLineEdit(self.createFrame) self.strT.setFixedSize(20, 20) self.cfgrid.addWidget(self.strT, 0, 3) magL = QLabel(self.createFrame, text="Mag") self.cfgrid.addWidget(magL, 1, 2) self.magT = QLineEdit(self.createFrame) self.magT.setFixedSize(20, 20) self.cfgrid.addWidget(self.magT, 1, 3) endL = QLabel(self.createFrame, text="End") self.cfgrid.addWidget(endL, 2, 2) self.endT = QLineEdit(self.createFrame) self.endT.setFixedSize(20, 20) self.cfgrid.addWidget(self.endT, 2, 3) agiL = QLabel(self.createFrame, text="Agi") self.cfgrid.addWidget(agiL, 3, 2) self.agiT = QLineEdit(self.createFrame) self.agiT.setFixedSize(20, 20) self.cfgrid.addWidget(self.agiT, 3, 3) luckL = QLabel(self.createFrame, text="Luck") self.cfgrid.addWidget(luckL, 4, 2) self.luckT = QLineEdit(self.createFrame) self.luckT.setFixedSize(20, 20) self.cfgrid.addWidget(self.luckT, 4, 3) resList = json_reader.data_list("resistances") resL = QLabel(self.createFrame, text="Resistance:") self.cfgrid.addWidget(resL, 0, 5) slashL = QLabel(self.createFrame, text="Slash") self.cfgrid.addWidget(slashL, 1, 5) self.slashO = QComboBox(self.createFrame) self.slashO.addItems(resList) self.slashO.setCurrentIndex(1) self.cfgrid.addWidget(self.slashO, 1, 6) strikeL = QLabel(self.createFrame, text="Strike") self.cfgrid.addWidget(strikeL, 2, 5) self.strikeO = QComboBox(self.createFrame) self.strikeO.addItems(resList) self.strikeO.setCurrentIndex(1) self.cfgrid.addWidget(self.strikeO, 2, 6) pierceL = QLabel(self.createFrame, text="Pierce") self.cfgrid.addWidget(pierceL, 3, 5) self.pierceO = QComboBox(self.createFrame) self.pierceO.addItems(resList) self.pierceO.setCurrentIndex(1) self.cfgrid.addWidget(self.pierceO, 3, 6) fireL = QLabel(self.createFrame, text="Fire") self.cfgrid.addWidget(fireL, 4, 5) self.fireO = QComboBox(self.createFrame) self.fireO.addItems(resList) self.fireO.setCurrentIndex(1) self.cfgrid.addWidget(self.fireO, 4, 6) iceL = QLabel(self.createFrame, text="Ice") self.cfgrid.addWidget(iceL, 5, 5) self.iceO = QComboBox(self.createFrame) self.iceO.addItems(resList) self.iceO.setCurrentIndex(1) self.cfgrid.addWidget(self.iceO, 5, 6) elecL = QLabel(self.createFrame, text="Elec") self.cfgrid.addWidget(elecL, 6, 5) self.elecO = QComboBox(self.createFrame) self.elecO.addItems(resList) self.elecO.setCurrentIndex(1) self.cfgrid.addWidget(self.elecO, 6, 6) windL = QLabel(self.createFrame, text="Wind") self.cfgrid.addWidget(windL, 7, 5) self.windO = QComboBox(self.createFrame) self.windO.addItems(resList) self.windO.setCurrentIndex(1) self.cfgrid.addWidget(self.windO, 7, 6) lightL = QLabel(self.createFrame, text="Light") self.cfgrid.addWidget(lightL, 8, 5) self.lightO = QComboBox(self.createFrame) self.lightO.addItems(resList) self.lightO.setCurrentIndex(1) self.cfgrid.addWidget(self.lightO, 8, 6) darkL = QLabel(self.createFrame, text="Dark") self.cfgrid.addWidget(darkL, 9, 5) self.darkO = QComboBox(self.createFrame) self.darkO.addItems(resList) self.darkO.setCurrentIndex(1) self.cfgrid.addWidget(self.darkO, 9, 6) spellList = json_reader.data_list("spells") self.listLS = QListWidget(self.createFrame) self.listLS.setFixedSize(200, 300) self.cfgrid.addWidget(self.listLS, 3, 7, 8, 2) newLS = QPushButton(self.createFrame, text="+") newLS.clicked.connect(self.addLS) self.cfgrid.addWidget(newLS, 2, 7) delLS = QPushButton(self.createFrame, text="DEL") delLS.clicked.connect(self.delLS) self.cfgrid.addWidget(delLS, 2, 8) lsl = QLabel(self.createFrame, text="Learned Spells:") self.cfgrid.addWidget(lsl, 0, 7, 1, 2) arcanaL = QLabel(self.createFrame, text="Arcana:") self.cfgrid.addWidget(arcanaL, 1, 0) arc_list = json_reader.data_list("arcanas") self.arcO = QComboBox(self.createFrame) self.arcO.addItems(arc_list) self.arcO.setCurrentIndex(0) self.cfgrid.addWidget(self.arcO, 1, 1) levelL = QLabel(self.createFrame, text="Level:") self.cfgrid.addWidget(levelL, 2, 0) self.levelT = QLineEdit(self.createFrame) self.levelT.setFixedSize(20, 20) self.cfgrid.addWidget(self.levelT, 2, 1) heritageL = QLabel(self.createFrame, text="Inherits:") self.cfgrid.addWidget(heritageL, 3, 0, 1, 2) elements = json_reader.data_list("elements") elements.append("Support") self.listEL1 = QComboBox(self.createFrame) self.listEL1.addItems(elements) self.cfgrid.addWidget(self.listEL1, 4, 0) self.listEL2 = QComboBox(self.createFrame) self.listEL2.addItems(elements) self.cfgrid.addWidget(self.listEL2, 4, 1) iSpellL = QLabel(self.createFrame, text="Initial Spells:") self.cfgrid.addWidget(iSpellL, 5, 0, 1, 2) self.iSpellOs = [] for i in range(6, 9): temp = QComboBox(self.createFrame) temp.addItems(spellList) temp2 = QComboBox(self.createFrame) temp2.addItems(spellList) self.cfgrid.addWidget(temp, i, 0, 1, 2) self.cfgrid.addWidget(temp2, i, 2, 1, 2) self.iSpellOs.extend([temp, temp2]) textL = QLabel(self.createFrame, text="Info:") self.cfgrid.addWidget(textL, 10, 0) self.textT = QTextEdit(self.createFrame) self.textT.setFixedSize(300, 100) self.cfgrid.addWidget(self.textT, 10, 1, 1, 5) self.lslevel = QLineEdit(self.createFrame) self.lslevel.setFixedSize(40, 20) self.lsSpellO = QComboBox(self.createFrame) self.lsSpellO.addItems(spellList) self.cfgrid.addWidget(self.lsSpellO, 1, 7) self.cfgrid.addWidget(self.lslevel, 1, 8) def addLS(self): """ Add a learned spell to the list, based on what was entered. """ print("Adding learned spell") chosenSpell = self.lsSpellO.currentText() if (int)(self.lslevel.text()) <= (int)(self.levelT.text()): popup("You cannot add a spell at an earlier level than the Persona's base level", "Critical") return if chosenSpell != "": print("Ok") self.lsdic[chosenSpell] = self.lslevel.text() self.listLS.addItem(chosenSpell + " at level " + self.lslevel.text()) self.lslevel.setText("") self.lsSpellO.setCurrentIndex(0) return popup("You must choose a spell", "Critical") def delLS(self): """ Remove the selected learned spell from the list """ print("Deleting learned spell") key = "" i = 0 while len(self.listLS.currentItem().text()) > i: if self.listLS.currentItem().text()[i] == " " and \ self.listLS.currentItem().text()[i+1] == "a" and \ self.listLS.currentItem().text()[i+2] == "t": # TODO EWWWWWW break key += self.listLS.currentItem().text()[i] i = i + 1 print(key) print(self.lsdic.pop(key)) self.listLS.takeItem(self.listLS.currentRow()) def loadPer(self, name): """ Load a certain Persona from file. :param str name: name of Persona to load """ data = json_reader.readOne(name, 'pers') self.nameT.setText(data["name"]) self.textT.setText(data["desc"]) self.strT.setText(data["stats"][0]) self.magT.setText(data["stats"][1]) self.endT.setText(data["stats"][2]) self.agiT.setText(data["stats"][3]) self.luckT.setText(data["stats"][4]) self.levelT.setText(data["level"]) self.arcO.setCurrentIndex( [self.arcO.itemText(i) for i in range(self.arcO.count())].index(data["arcana"]) ) self.listEL1.setCurrentIndex( [self.listEL1.itemText(i) for i in range(self.listEL1.count())].index(data["heritage"][0]) ) self.listEL2.setCurrentIndex( [self.listEL2.itemText(i) for i in range(self.listEL2.count())].index(data["heritage"][1]) ) self.slashO.setCurrentIndex( [self.slashO.itemText(i) for i in range(self.slashO.count())].index(data["resistance"][0]) ) self.strikeO.setCurrentIndex( [self.strikeO.itemText(i) for i in range(self.strikeO.count())].index(data["resistance"][1]) ) self.pierceO.setCurrentIndex( [self.pierceO.itemText(i) for i in range(self.pierceO.count())].index(data["resistance"][2]) ) self.fireO.setCurrentIndex( [self.fireO.itemText(i) for i in range(self.fireO.count())].index(data["resistance"][3]) ) self.iceO.setCurrentIndex( [self.iceO.itemText(i) for i in range(self.iceO.count())].index(data["resistance"][4]) ) self.elecO.setCurrentIndex( [self.elecO.itemText(i) for i in range(self.elecO.count())].index(data["resistance"][5]) ) self.windO.setCurrentIndex( [self.windO.itemText(i) for i in range(self.windO.count())].index(data["resistance"][6]) ) self.lightO.setCurrentIndex( [self.lightO.itemText(i) for i in range(self.lightO.count())].index(data["resistance"][7]) ) self.darkO.setCurrentIndex( [self.darkO.itemText(i) for i in range(self.darkO.count())].index(data["resistance"][8]) ) i = 0 for combobox in self.iSpellOs: combobox.setCurrentIndex( [combobox.itemText(j) for j in range(combobox.count()-1)].index(data["spellDeck"][i]) ) i += 1 self.lsdic = data["spellLearn"] self.listLS.clear() for spell, level in self.lsdic.items(): self.listLS.addItem(spell + " at level " + level) print("Loaded " + data["name"]) def edit(self): """ Switch to edit view, also loads the selected Persona. """ try: if self.listP.currentItem().text() != "": if self.createFrame and not popup("Override any unsaved changes?", "Warning"): return self.loadPer(self.listP.currentItem().text()) except AttributeError: # To initialize createFrame UI before load if self.listP.currentItem().text() != "": temp = self.listP.currentItem().text() self.buttonFrame.close() self.initUI(False) self.loadPer(temp) else: return self.createFrame.show() self.mainframe.center() print("Changed to edit frame") def save(self): """ Validate all info and save to file on disk. """ if os.path.exists(json_reader.buildPath("data/pers/"+self.nameT.text()+".json")): if not popup("Override existing Persona "+self.nameT.text()+"?", "Question"): return print("Saving") spellDeck = [] for combobox in self.iSpellOs: spellDeck.append(combobox.currentText()) stats = [self.strT.text(), self.magT.text(), self.endT.text(), self.agiT.text(), self.luckT.text()] res = [self.slashO.currentText(), self.strikeO.currentText(), self.pierceO.currentText(), self.fireO.currentText(), self.iceO.currentText(), self.elecO.currentText(), self.windO.currentText(), self.lightO.currentText(), self.darkO.currentText()] try: (int)(self.levelT.text()) (int)(self.strT.text()) (int)(self.magT.text()) (int)(self.endT.text()) (int)(self.agiT.text()) (int)(self.luckT.text()) except ValueError: popup("There is a number entry that isn't valid.\nEntries requiring numbers are:\nLEVEL\nSTR" "\nMAG\nEND\nAGI\nLUCK", "Critical") print("Not Saved") return if not (self.nameT.text() and not self.nameT.text().isspace()): popup("No name entered for your Persona. Name is a required field.", "Critical") print("No Name, not saved") return toWrite = Persona( self.nameT.text(), self.arcO.currentText(), self.levelT.text(), self.textT.toPlainText(), spellDeck, self.lsdic, stats, res, [self.listEL1.currentText(), self.listEL2.currentText()] ) json_reader.writeOne(toWrite, 'pers') temp = self.nameT.text() if (temp not in [self.listP.item(i).text() for i in range(self.listP.count())]): self.listP.addItem(temp) self.loadPer(temp) print("Saved Persona") def remove(self): """ Remove a created Persona from the list and delete the file on disk. """ if self.listP.currentItem().text() == "": return if not popup( "Are you certain you want to completely remove this Persona?\n(Cannot be undone)", "Warning" ): return print("Removing Persona " + self.listP.currentItem().text()) json_reader.deletePer(self.listP.currentItem().text()) self.listP.takeItem( [self.listP.item(i).text() for i in range(self.listP.count())].index( self.listP.currentItem().text()) ) def new(self): """ Open an empty Persona edit view. """ if self.createFrame and not popup("Override any unsaved changes?", "Warning"): return if self.createFrame: self.createFrame.close() self.buttonFrame.close() self.initUI(False) self.createFrame.show() self.mainframe.center() print("Created") def back(self): """ Return to the parent widget. """ print("Returned to main screen") self.mainframe.changeState(self.op)
class BrowserWin(QWidget): def __init__(self, *args, **kwargs): super(BrowserWin, self).__init__(*args, **kwargs) # parent Maya window self.setParent(mainWindow) self.setWindowFlags(Qt.Window) # Window settings self.setWindowTitle('AC_AssetBrowser') # Build window self.mainLayout = QVBoxLayout() self.btnLayout = QHBoxLayout() self.radioLayout = QHBoxLayout() # radio buttons load import self.radioLabel = QLabel("Action: ") self.importRadioBtn = QRadioButton("Import File") self.openRadioBtn = QRadioButton("Open File") self.saveRadioBtn = QRadioButton("Save File") # Find asset directories to load from and populate the drop down self.fileType = QComboBox() self.__populate_list(self.fileType) self.curr_cat = self.fileType.currentText() # list of assets in self.list self.fileList = QListWidget() self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection) self.__populate_list(self.fileList, directory=os.path.join(DIRECTORY, self.curr_cat)) self.fileName = QLineEdit() self.loadBtn = QPushButton("Load Asset") self.publishBtn = QPushButton("Publish") self.closeBtn = QPushButton("Close") # Add widgets to layouts self.radioLayout.addWidget(self.radioLabel) self.radioLayout.addWidget(self.importRadioBtn) self.radioLayout.addWidget(self.openRadioBtn) self.radioLayout.addWidget(self.saveRadioBtn) self.mainLayout.addLayout(self.radioLayout) self.mainLayout.addWidget(self.fileType) self.mainLayout.addWidget(self.fileList) self.mainLayout.addWidget(self.fileName) self.btnLayout.addWidget(self.loadBtn) self.btnLayout.addWidget(self.publishBtn) self.btnLayout.addWidget(self.closeBtn) self.mainLayout.addLayout(self.btnLayout) self.setLayout(self.mainLayout) # Set state of widgets self.importRadioBtn.toggle() self.fileName.setPlaceholderText("file_name") self.fileName.setEnabled(False) self.publishBtn.setEnabled(False) # Signals self.fileType.currentIndexChanged.connect(self.selectionChanged) self.loadBtn.clicked.connect(self.loadBtnCmd) self.publishBtn.clicked.connect(self.publishBtnCmd) self.closeBtn.clicked.connect(self.closeBtnCmd) self.importRadioBtn.toggled.connect(self.onImportToggled) self.openRadioBtn.toggled.connect(self.onOpenToggled) self.saveRadioBtn.toggled.connect(self.onSaveToggled) def __populate_list(self, destination, directory=DIRECTORY): _dirs = os.listdir(directory) _items = [_dir for _dir in _dirs] return destination.addItems(_items) def selectionChanged(self): self.curr_cat = self.fileType.currentText() self.fileList.clear() self.__populate_list(self.fileList, directory=os.path.join(DIRECTORY, self.curr_cat)) def loadBtnCmd(self): if self.importRadioBtn.isChecked(): selected_files = self.fileList.selectedItems() for _file in selected_files: asset_file = os.path.join(DIRECTORY, self.curr_cat, _file.text()) cmds.file(asset_file, i=True) elif self.openRadioBtn.isChecked(): selected_file = self.fileList.currentItem() asset_file = os.path.join(DIRECTORY, self.curr_cat, selected_file.text()) cmds.file(asset_file, o=True, force=True) else: print("Did you mean to publish this asset?") def publishBtnCmd(self): if self.saveRadioBtn.isChecked() and self.fileName.text() is not None: path_to_save = os.path.join(DIRECTORY, self.curr_cat, self.fileName.text()) cmds.file(rn="{}.ma".format(path_to_save)) cmds.file(save=True) self.fileList.clear() self.__populate_list(self.fileList, directory=os.path.join( DIRECTORY, self.curr_cat)) def closeBtnCmd(self): self.close() def onSaveToggled(self): items = self.fileList.selectedItems() for item in items: item.setSelected(False) self.fileName.setEnabled(not self.fileName.isEnabled()) self.publishBtn.setEnabled(not self.publishBtn.isEnabled()) def onImportToggled(self): if self.importRadioBtn.isChecked(): self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection) def onOpenToggled(self): if self.openRadioBtn.isChecked(): items = self.fileList.selectedItems() items.pop() for item in items: item.setSelected(False) self.fileList.setSelectionMode(QAbstractItemView.SingleSelection)
class SelectPackages_Dialog(QDialog): def __init__(self, parent, packages): super(SelectPackages_Dialog, self).__init__(parent) self.file_paths = [] self.required_packages = packages self.setLayout(QVBoxLayout()) self.layout().addWidget(QLabel('You need to select the locations of the following required node packages')) # package lists required_packages_list_widget = QListWidget() for p in packages: package_item = QListWidgetItem() package_item.setText(p) required_packages_list_widget.addItem(package_item) selected_items_widget = QWidget() selected_items_widget.setLayout(QVBoxLayout()) self.selected_packages_list_widget = QListWidget() selected_items_widget.layout().addWidget(self.selected_packages_list_widget) auto_import_button = QPushButton('auto import') auto_import_button.clicked.connect(self.auto_import_button_clicked) selected_items_widget.layout().addWidget(auto_import_button) add_package_button = QPushButton('add') add_package_button.clicked.connect(self.add_package_button_clicked) selected_items_widget.layout().addWidget(add_package_button) clear_package_list_button = QPushButton('clear') clear_package_list_button.clicked.connect(self.clear_selected_packages_list) selected_items_widget.layout().addWidget(clear_package_list_button) finished_button = QPushButton('OK') finished_button.clicked.connect(self.finished_button_clicked) selected_items_widget.layout().addWidget(finished_button) packages_lists_widget = QWidget() packages_lists_widget.setLayout(QHBoxLayout()) packages_lists_widget.layout().addWidget(required_packages_list_widget) packages_lists_widget.layout().addWidget(selected_items_widget) self.layout().addWidget(packages_lists_widget) self.setWindowTitle('select required packages') def auto_import_button_clicked(self): packages_dir = '../packages' folders_list = [x[0] for x in os.walk(packages_dir)] required_files = self.required_packages.copy() for folder in folders_list: for r_f in required_files: if r_f+'.pypac' in os.listdir(packages_dir+'/'+folder): self.file_paths.append(packages_dir+'/'+folder+'/'+r_f+'.pypac') break self.rebuild_selected_packages_list_widget() if len(self.file_paths) == len(self.required_packages): self.finished() def add_package_button_clicked(self): file_names = QFileDialog.getOpenFileNames(self, 'select package files', '../packages', 'PyScript Package(*.pypac)')[0] for file_name in file_names: try: f = open(file_name) f.close() self.file_paths.append(file_name) except FileNotFoundError: GlobalStorage.debug('couldn\'t open file') self.rebuild_selected_packages_list_widget() def rebuild_selected_packages_list_widget(self): # remove all items self.selected_packages_list_widget.clear() for f in self.file_paths: file_item = QListWidgetItem() file_item.setText(f) self.selected_packages_list_widget.addItem(file_item) def clear_selected_packages_list(self): self.file_paths.clear() self.rebuild_selected_packages_list_widget() def finished_button_clicked(self): # TODO analyse for potentially wrong packages self.finished() def finished(self): self.accept()
class Order(QWidget): def __init__(self): super(Order, self).__init__() self.game_on = False self.required_bosses = [ 'Asylum Demon', 'Bell Gargoyle', 'Quelaag', 'Iron Golem', 'ornstein & smough', 'Ceaseless Discharge', 'Sif', '4 Kings', 'Bed Of Chaos', 'Seath', 'Pinwheel', 'Nito', 'Gwyn' ] self.order_list = QListWidget() self.order_list.setDragDropMode(QAbstractItemView.InternalMove) self.capra_box = QCheckBox("Capra Demon") self.capra_box.toggled.connect( lambda: self.add_to_list(self.capra_box)) self.centipede_box = QCheckBox("Centipede Demon") self.centipede_box.toggled.connect( lambda: self.add_to_list(self.centipede_box)) self.priscilla_box = QCheckBox("Priscilla") self.priscilla_box.toggled.connect( lambda: self.add_to_list(self.priscilla_box)) self.gwyndolin_box = QCheckBox("Gwyndolin") self.gwyndolin_box.toggled.connect( lambda: self.add_to_list(self.gwyndolin_box)) self.firesage_box = QCheckBox("Demon Firesage") self.firesage_box.toggled.connect( lambda: self.add_to_list(self.firesage_box)) self.gaping_box = QCheckBox("Gaping Dragon") self.gaping_box.toggled.connect( lambda: self.add_to_list(self.gaping_box)) self.butterfly_box = QCheckBox("Moonlight Butterfly") self.butterfly_box.toggled.connect( lambda: self.add_to_list(self.butterfly_box)) self.start_button = QPushButton("Start New Game") self.start_button.clicked.connect(self.start_game) self.selected_bosses = [] for i in self.required_bosses: self.order_list.addItem(i) self.selected_bosses.append(i) self.layout = QGridLayout() self.layout.addWidget(self.capra_box, 0, 0) self.layout.addWidget(self.centipede_box, 0, 1) self.layout.addWidget(self.priscilla_box, 1, 0) self.layout.addWidget(self.gwyndolin_box, 1, 1) self.layout.addWidget(self.firesage_box, 2, 0) self.layout.addWidget(self.gaping_box, 2, 1) self.layout.addWidget(self.butterfly_box, 3, 0) self.layout.addWidget(self.order_list, 4, 0, 1, 2) self.setLayout(self.layout) def start_game(self): self.game_on = True def add_to_list(self, item): if item.checkState(): self.order_list.addItem(item.text()) self.selected_bosses.append(item.text()) else: self.order_list.clear() del self.selected_bosses[self.selected_bosses.index(item.text())] for i in self.selected_bosses: self.order_list.addItem(i)
class MyWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle( 'Graphical utility for destroying, zeroing, and deleting files') self.label_donate = QLabel( 'Copyright (c) 2021, Aleksandr Suvorov | Donate: 4048 0250 0089 5923' ) self.label_donate.setAlignment(Qt.AlignCenter) self.label_logo = QLabel(f'Smart Cleaner<sup> {VERSION}</sup>') self.label_logo.setAlignment(Qt.AlignCenter) self.label_logo.setStyleSheet('font-size: 48px;') self.label_files = QLabel('Files') self.label_files.setStyleSheet("color: rgb(84, 180, 40);") self.label_dirs = QLabel('Folders') self.label_dirs.setStyleSheet("color: rgb(177, 98, 42);") self.label_errors = QLabel('Errors') self.label_errors.setStyleSheet("color: rgb(255, 68, 44);") self.lcd_files = QLCDNumber() self.lcd_files.setSegmentStyle(QLCDNumber.Flat) self.lcd_files.setStyleSheet("color: rgb(84, 180, 40);") self.lcd_dirs = QLCDNumber() self.lcd_dirs.setSegmentStyle(QLCDNumber.Flat) self.lcd_dirs.setStyleSheet("color: rgb(177, 98, 42);") self.lcd_errors = QLCDNumber() self.lcd_errors.setSegmentStyle(QLCDNumber.Flat) self.lcd_errors.setMinimumHeight(30) self.lcd_errors.setStyleSheet("color: rgb(255, 68, 44);") self.lcd_files.setDigitCount(15) self.lcd_dirs.setDigitCount(15) self.lcd_errors.setDigitCount(15) self.h_box1 = QHBoxLayout() self.h_box1.addWidget(self.label_dirs) self.h_box1.addWidget(self.label_files) self.h_box1.addWidget(self.label_errors) self.h_box2 = QHBoxLayout() self.h_box2.addWidget(self.lcd_dirs) self.h_box2.addWidget(self.lcd_files) self.h_box2.addWidget(self.lcd_errors) self.label_cons = QLabel('Information console:') self.text_browser = QTextBrowser() self.text_browser.setText( f'Smart Cleaner v{VERSION} \nUtility for overwriting, zeroing, and deleting files\n' f'https://github.com/mysmarthub') self.btn_console_clear = QPushButton('Reset') self.btn_donate = QPushButton('Donate | Visa: 4048 0250 0089 5923') self.btn_donate.setToolTip( 'We will be grateful for any financial support.\nThis will help the program ' 'develop and remain free.\nThanks!') self.btn_exit = QPushButton('Exit') self.h_box3 = QHBoxLayout() self.h_box3.addWidget(self.btn_donate) self.h_box3.addStretch(1) self.h_box3.addWidget(self.btn_console_clear) self.chb_del_dirs = QCheckBox('Delete folders') self.chb_del_dirs.setChecked(True) self.label_shred = QLabel('Rewrite:') self.spin_box = QSpinBox() self.spin_box.setMinimum(1) self.spin_box.setMaximum(1000) self.spin_box.setValue(30) self.h_box4 = QHBoxLayout() self.h_box4.addWidget(self.chb_del_dirs) self.h_box4.addWidget(self.label_shred) self.h_box4.addWidget(self.spin_box) self.h_box4.addStretch(1) self.list_widget = QListWidget() self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.btn_add_folder = QPushButton('+ Folder') self.btn_add_files = QPushButton('+ Files') self.btn_remove_item = QPushButton('- Remove') self.btn_zero_files = QPushButton('Zeroing') self.btn_shred_files = QPushButton('Erasing') self.btn_del_files = QPushButton('Delete') self.h_box5 = QHBoxLayout() self.h_box5.addWidget(self.btn_add_folder) self.h_box5.addWidget(self.btn_add_files) self.h_box5.addWidget(self.btn_remove_item) self.h_box5.addStretch(1) self.h_box5.addWidget(self.btn_shred_files) self.h_box5.addWidget(self.btn_zero_files) self.h_box5.addWidget(self.btn_del_files) self.h_box5.addWidget(self.btn_exit) self.v_box = QVBoxLayout() self.v_box.addWidget(self.label_logo) self.v_box.addLayout(self.h_box1) self.v_box.addLayout(self.h_box2) self.v_box.addWidget(self.label_cons) self.v_box.addWidget(self.text_browser) self.v_box.addLayout(self.h_box3) self.v_box.addLayout(self.h_box4) self.v_box.addWidget(self.list_widget) self.v_box.addLayout(self.h_box5) self.v_box.addWidget(self.label_donate) self.setLayout(self.v_box) self.smart_cleaner = SmartCleaner() self.btn_donate.clicked.connect( lambda: webbrowser.open('https://yoomoney.ru/to/4100115206129186')) self.btn_console_clear.clicked.connect(self.clear_console) self.btn_add_folder.clicked.connect(self.add_dir) self.btn_add_files.clicked.connect(self.add_files) self.btn_remove_item.clicked.connect(self.remove_items) self.btn_shred_files.clicked.connect(self.shred_start) self.btn_zero_files.clicked.connect(self.zeroing_start) self.btn_del_files.clicked.connect(self.delete_start) self.btn_exit.clicked.connect(self.close) self.smart_cleaner.signal.connect(self.update_information) self.smart_cleaner.started.connect(self.at_start) self.smart_cleaner.finished.connect(self.at_finish) def clear_console(self): self.lcd_dirs.display(0) self.lcd_files.display(0) self.lcd_errors.display(0) self.text_browser.setText( f'Smart Cleaner v{VERSION} \nUtility for overwriting, zeroing, and deleting files\n' f'https://github.com/mysmarthub') def add_dir(self) -> None: path = QFileDialog.getExistingDirectory(self, 'Select the folder to add: ') self._add_path(path) def add_files(self) -> None: path_tuple = QFileDialog.getOpenFileNames(self, 'Select files to add: ') for path in path_tuple[0]: self._add_path(path) def add_item(self, item: str) -> None: self.list_widget.addItem(item) def remove_items(self) -> None: for SelectedItem in self.list_widget.selectedItems(): self.list_widget.takeItem(self.list_widget.row(SelectedItem)) self.smart_cleaner.path_data.del_path(SelectedItem.text()) self.text_browser.append( f'{SelectedItem.text()}\nThe path was successfully deleted!!!') def _add_path(self, path: str) -> None: if path: if self.smart_cleaner.path_data.add_path(path): self.add_item(path) self.text_browser.append( f'{path}\nThe path was added successfully!') else: self.text_browser.append( f'Error when adding or the path was added earlier!!!') def shred_start(self): self.start(method='shred') def zeroing_start(self): self.start(method='zero') def delete_start(self): self.start(method='del') def start(self, method='shred'): if not self.smart_cleaner.path_data.is_any_data: self.show_msg('Warning!', 'There is no data for mashing!!!') else: reply = QMessageBox.question( self, 'Warning!', 'The data will be destroyed, are you sure?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: if method == 'zero': self.text_browser.append('Files are reset to zero.') elif method == 'shred': self.text_browser.append('File mashing is started.') elif method == 'del': self.text_browser.append('File deletion started.') self.smart_cleaner.work_method = method self.smart_cleaner.shreds = self.spin_box.value() self.smart_cleaner.delete_a_folder = self.chb_del_dirs.isChecked( ) self.smart_cleaner.start() def update_information(self, s: str) -> None: self.text_browser.append(s) self.update_lcd() def update_lcd(self) -> None: self.lcd_dirs.display(str(self.smart_cleaner.cleaner.count_del_dirs)) self.lcd_files.display(str(self.smart_cleaner.cleaner.count_del_files)) self.lcd_errors.display(str(self.smart_cleaner.num_errors)) def at_start(self): self.from_disable(True) def at_finish(self) -> None: if self.smart_cleaner.work_method != 'zero': self.list_widget.clear() self.update_lcd() self.from_disable(False) self.finish_msg() def finish_msg(self) -> None: if self.smart_cleaner.work_method == 'zero': msg = ('Reset', 'Reset files: ') count = self.smart_cleaner.cleaner.count_zero_files elif self.smart_cleaner.work_method == 'shred': msg = ('Mashing', 'Passageways: ') count = self.smart_cleaner.cleaner.count_del_files else: msg = ('Delete', 'Deleted files: ') count = self.smart_cleaner.cleaner.count_del_files self.show_msg( 'Warning!', f'{msg[0]} completed successfully!!!\n' f' {msg[1]} {count}\n ' f'Deleted folders: {self.smart_cleaner.cleaner.count_del_dirs}\n ' f'Errors: {self.smart_cleaner.num_errors}') def from_disable(self, status: bool) -> None: self.btn_zero_files.setDisabled(status) self.btn_remove_item.setDisabled(status) self.btn_add_folder.setDisabled(status) self.btn_shred_files.setDisabled(status) self.btn_console_clear.setDisabled(status) self.btn_add_files.setDisabled(status) self.btn_del_files.setDisabled(status) self.chb_del_dirs.setDisabled(status) self.spin_box.setDisabled(status) self.list_widget.setDisabled(status) def show_msg(self, title: str = 'Warning!', msg: str = 'Message...') -> None: QMessageBox.about(self, title, msg) def closeEvent(self, event) -> None: reply = QMessageBox.question( self, 'Exit', 'Are you sure you want to terminate the program?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.hide() self.smart_cleaner.wait(3000) event.accept() else: event.ignore()
class MatchStatWindow(QDialog): def __init__(self, parent=None): super(MatchStatWindow, self).__init__(parent) self.setModal(True) self.setWindowTitle("Mérkőzés választása") self.resize(740, 600) self.layout = QVBoxLayout() self.setLayout(self.layout) self.merkozesek = QListWidget() self.merkozesek.setFixedHeight(200) self.merkozesek.setFixedWidth(730) self.merkozesek.itemDoubleClicked.connect(self.stat_game) self.layout.addWidget(self.merkozesek) self.szumma = MatchSumWidget(self) self.layout.addWidget(self.szumma) self.history = QWidget() self.history.setFixedWidth(690) self.history_layout = QGridLayout() self.history.setLayout(self.history_layout) scroll = QScrollArea() scroll.setWidget(self.history) scroll.setWidgetResizable(True) self.layout.addWidget(scroll) self.match_valasztas() def match_valasztas(self): matches = QSqlRelationalTableModel(db=db) matches.setTable("match_settings") matches.setSort(8, Qt.DescendingOrder) matches.select() self.merkozesek.clear() for i in range(matches.rowCount()): self.merkozesek.addItem(str(matches.record(i).value(1)) + "\t" + str(matches.record(i).value(2)) + "\t" + str(int(matches.record(i).value(3)) + matches.record(i).value(6)) + "\t" + str(int(matches.record(i).value(3)) + matches.record(i).value(7)) + "\t" + str(matches.record(i).value(4)) + "\t" + str(matches.record(i).value(5)) + "\t" + str(matches.record(i).value(8))[:16] + "\t" + str(matches.record(i).value(0)) ) def stat_game(self): # Az átvett adatok: para = self.merkozesek.currentItem().text().rsplit("\t") # Összegyűjtjük egy listába a szükséges infókat self.get_adatok(para) self.szumma.change_data(self.adatok) for x in reversed(range(self.history_layout.count())): self.history_layout.itemAt(x).widget().deleteLater() # kiszedjük az adott meccs összes set és leg esetére a dobásokat sor = 0 for s in range(1, self.adatok[8] + 1): # s: a set-ek száma if self.adatok[8] != 1: self.history_layout.addWidget(QLabel("Set: " + str(s)), sor, 0, 1, 2) sor += 1 for l in range(1, self.adatok[7][s-1] + 1): sl1_model = QSqlQueryModel() p1_data_list = [] p1_data_list.append(self.adatok[4]) # start_score1 sl1_query = QSqlQuery(f"select * from dobas where match_id ={self.adatok[6]} and set_id={s} and leg_id={l} and player_id='{self.adatok[0]}'", db=db) sl1_model.setQuery(sl1_query) for i in range(sl1_model.rowCount()): # Itt a model már tartalmazza a p1 összes dobását az adott leg-ben. p1_data_row = [] p1_data_row.append(sl1_model.record(i).value(1)) p1_data_row.append(sl1_model.record(i).value(2)) p1_data_list.append(p1_data_row) self.history_layout.addWidget(PlayerLegWidget(self, p1_data_list), sor, 0, Qt.AlignTop) sl2_model = QSqlQueryModel() p2_data_list = [] p2_data_list.append(self.adatok[5]) # start_score2 sl2_query = QSqlQuery(f"select * from dobas where match_id ={self.adatok[6]} and set_id={s} and leg_id={l} and player_id='{self.adatok[2]}'", db=db) sl2_model.setQuery(sl2_query) for j in range(sl2_model.rowCount()): p2_data_row = [] p2_data_row.append(sl2_model.record(j).value(1)) p2_data_row.append(sl2_model.record(j).value(2)) p2_data_list.append(p2_data_row) self.history_layout.addWidget(PlayerLegWidget(self, p2_data_list), sor, 1, Qt.AlignTop) sor += 1 def get_adatok(self, para): print(para) # self.adatok[0] : p1_id # self.adatok[1] : name1 # self.adatok[2] : p2_id # self.adatok[3] : name2 # self.adatok[4] : start_score1 # self.adatok[5] : start_score2 # self.adatok[6] : match # self.adatok[7] : legs # self.adatok[8] : sets # self.adatok[9] : dátum self.adatok = [] name1_id = int(para[0]) self.adatok.append(name1_id) query_name1 = QSqlQuery(f"select player_name from players where player_id={name1_id}", db=db) query_name1.exec_() while query_name1.next(): name1 = query_name1.value(0) self.adatok.append(name1) name2_id = int(para[1]) self.adatok.append(name2_id) query_name2 = QSqlQuery(f"select player_name from players where player_id={name2_id}", db=db) query_name2.exec_() while query_name2.next(): name2 = query_name2.value(0) self.adatok.append(name2) start_score1 = int(para[2]) start_score2 = int(para[3]) match = int(para[7]) setek = int(para[5]) self.adatok.append(start_score1) self.adatok.append(start_score2) self.adatok.append(match) # Kell a max set-number, ezt beállítani a sets változóba # Ciklussal minden set-ben megnézni a max leg-numbert, és ezeket append-elni a legs[]-hez # Végül leg, set sorrendben append-elni az adatokhoz legs = [] sets = 0 query2 = QSqlQuery( f"select max(set_id) as max_set from matches where match_id={match}", db=db) query2.exec_() while query2.next(): sets = int(query2.value(0)) for i in range(1, sets + 1): query = QSqlQuery(f"select max(leg_id) as max_leg from matches where match_id={match} and set_id={i}", db=db) query.exec_() while query.next(): legs.append(int(query.value(0))) # sets.append(int(query.value(1))) self.adatok.append(legs) self.adatok.append(sets) datum = para[6][:16] self.adatok.append(datum) print(self.adatok)
class LevelSelector(QDialog): def __init__(self, parent): super(LevelSelector, self).__init__(parent) self.setWindowTitle("Level Selector") self.setModal(True) self.selected_world = 1 self.selected_level = 1 self.object_set = 0 self.object_data_offset = 0x0 self.enemy_data_offset = 0x0 self.world_label = QLabel(parent=self, text="World") self.world_list = QListWidget(parent=self) self.world_list.addItems(WORLD_ITEMS) self.world_list.itemDoubleClicked.connect(self.on_ok) self.world_list.itemSelectionChanged.connect(self.on_world_click) self.level_label = QLabel(parent=self, text="Level") self.level_list = QListWidget(parent=self) self.level_list.itemDoubleClicked.connect(self.on_ok) self.level_list.itemSelectionChanged.connect(self.on_level_click) self.enemy_data_label = QLabel(parent=self, text="Enemy Data") self.enemy_data_spinner = Spinner(parent=self) self.object_data_label = QLabel(parent=self, text="Object Data") self.object_data_spinner = Spinner(self) self.object_set_label = QLabel(parent=self, text="Object Set") self.object_set_dropdown = QComboBox(self) self.object_set_dropdown.addItems(OBJECT_SET_ITEMS) self.button_ok = QPushButton("Ok", self) self.button_ok.clicked.connect(self.on_ok) self.button_cancel = QPushButton("Cancel", self) self.button_cancel.clicked.connect(self.close) self.window_layout = QGridLayout(self) self.window_layout.addWidget(self.world_label, 0, 0) self.window_layout.addWidget(self.level_label, 0, 1) self.window_layout.addWidget(self.world_list, 1, 0) self.window_layout.addWidget(self.level_list, 1, 1) self.window_layout.addWidget(self.enemy_data_label, 2, 0) self.window_layout.addWidget(self.object_data_label, 2, 1) self.window_layout.addWidget(self.enemy_data_spinner, 3, 0) self.window_layout.addWidget(self.object_data_spinner, 3, 1) self.window_layout.addWidget(self.object_set_label, 4, 0) self.window_layout.addWidget(self.object_set_dropdown, 4, 1) self.window_layout.addWidget(self.button_ok, 5, 0) self.window_layout.addWidget(self.button_cancel, 5, 1) self.setLayout(self.window_layout) self.world_list.setCurrentRow(1) # select Level 1-1 self.on_world_click() def keyPressEvent(self, key_event: QKeyEvent): if key_event.key() == Qt.Key_Escape: self.reject() def on_world_click(self): index = self.world_list.currentRow() assert index >= 0 self.level_list.clear() # skip first meaningless item for level in Level.offsets[1:]: if level.game_world == index: if level.name: self.level_list.addItem(level.name) if self.level_list.count(): self.level_list.setCurrentRow(0) self.on_level_click() def on_level_click(self): index = self.level_list.currentRow() assert index >= 0 self.selected_world = self.world_list.currentRow() self.selected_level = index + 1 level_is_overworld = self.selected_world == OVERWORLD_MAPS_INDEX if level_is_overworld: level_array_offset = self.selected_level else: level_array_offset = Level.world_indexes[self.selected_world] + self.selected_level object_data_for_lvl = Level.offsets[level_array_offset].rom_level_offset if not level_is_overworld: object_data_for_lvl -= Level.HEADER_LENGTH self.object_data_spinner.setValue(object_data_for_lvl) if not level_is_overworld: enemy_data_for_lvl = Level.offsets[level_array_offset].enemy_offset else: enemy_data_for_lvl = 0 if enemy_data_for_lvl > 0: # data in look up table is off by one, since workshop ignores the first byte enemy_data_for_lvl -= 1 self.enemy_data_spinner.setValue(enemy_data_for_lvl) self.enemy_data_spinner.setEnabled(not level_is_overworld) # if self.selected_world >= WORLD_1_INDEX: object_set_index = Level.offsets[level_array_offset].real_obj_set self.object_set_dropdown.setCurrentIndex(object_set_index) self.button_ok.setDisabled(self.selected_world == 0) def on_ok(self, _): if self.selected_world == 0: return self.object_set = self.object_set_dropdown.currentIndex() self.object_data_offset = self.object_data_spinner.value() # skip the first byte, because it seems useless self.enemy_data_offset = self.enemy_data_spinner.value() + 1 self.accept() def closeEvent(self, _close_event: QCloseEvent): self.reject()
class TimerWindow(QWidget): elapsed_time = 0 thread_running = False #api_token = 'fea20970f5bb1b75c96dfa8985fd15b2a3c0f8a8d3261381d0176a05475781ee88d9f7252511e5e085b99e1cee37efa86f7364b7ed5203bccd2c2fd9b76057fe' apa = IdleTime() workingthread = None systray = None db = Database() api_token = db.readDatabase()['userdata']['api_token'] def __init__(self): super().__init__() self.title = 'Timey' self.left = 10 self.top = 10 self.width = 440 self.height = 680 self.initUI() self.NetworkSetup() def initUI(self): self.setWindowTitle(self.title) self.setWindowIcon(QIcon(Config.icon)) self.setGeometry(self.left, self.top, self.width, self.height) layout = QGridLayout() self.setLayout(layout) layout.setColumnStretch(1, 4) layout.setColumnStretch(2, 4) style = """ background-color: white; border-bottom: 1px solid #fff123; """ self.setStyleSheet(style) self.labeltimer = QLabel('00:00:00', self) self.labeltimer.setAlignment(Qt.AlignCenter) self.labeltimer.setStyleSheet("""QLabel { font: medium Ubuntu; font-size: 32px; color: #006325; border-width:1px; } """) fa5_icon = qta.icon('fa5s.play') #fa5_button = QtGui.QPushButton(fa5_icon, 'Font Awesome! (regular)') self.button = QPushButton(fa5_icon, "Start") self.button.clicked.connect(self.clickStart) self.button.setStyleSheet("""QPushButton { #background-color: #f06325; #color: white; #font-color: white; #min-width: 70px; #max-width: 70px; #min-height: 70px; #max-height: 70px; #border-radius: 35px; #border-width: 1px; border-color: #ae32a0; border-style: solid; } QPushButton:hover { background-color: #328930; } QPushButton:pressed { background-color: black; color: black; border-width:10px; } """) #self.label4 = QLabel('Working: ', self) #self.label4.setAlignment(Qt.AlignCenter) self.label3 = QLabel('None', self) self.label3.setAlignment(Qt.AlignCenter) self.test = QListWidget(self) self.test.addItem("item4") self.test.itemSelectionChanged.connect(self.selectItem) self.addtask = QLineEdit(self) #fa5_plusicon = qta.icon('fa5s.plus') self.addtaskbutton = QPushButton(qta.icon('fa5s.plus'), "Add") self.addtaskbutton.clicked.connect(self._click_additem) self.deltaskbutton = QPushButton(qta.icon('fa5s.minus'), "Del") self.deltaskbutton.clicked.connect(self._click_deltask) self.tasks = QListWidget(self) self.tasks.addItem("No tasks") layout.addWidget(self.labeltimer, 0, 0) layout.addWidget(self.button, 0, 1) #layout.addWidget(self.label4,1,0) layout.addWidget(self.label3, 1, 0) layout.addWidget(self.test, 2, 0) layout.addWidget(self.addtask, 3, 0) layout.addWidget(self.addtaskbutton, 3, 1) layout.addWidget(self.deltaskbutton, 3, 2) layout.addWidget(self.tasks, 4, 0) self.show() print("init end") def _update_timer(self): if self.thread_running == True: self.thread_running = False return 0 while True: #self.elapsed_time = time.time() self.thread_running = True ''' this is little weired.. but works for now ''' if self.apa.thread_exit == True or self.thread_exit == True: data = api.activity_current(self.api_token) print(data) if not data.get('error'): api.activity_stop(self.api_token, data['id']) self.button.setText('Start') self.workingthread.exit() self.thread_running = False break self.elapsed_time += 1 self.labeltimer.setText(self._online_time(self.elapsed_time)) time.sleep(1) def _click_additem(self): print("oh oh oh oh") print(self.addtask.text()) text = self.addtask.text() project_id = None if len(text) > 0: print("This seems acceptable") for _x in self.test.selectedItems(): project_id = _x.data(Qt.UserRole) print(project_id) if project_id == None: QMessageBox.information(self, 'PyQt5 message', "Please select a a project first", QMessageBox.Ok) else: api.task_add(self.api_token, project_id, text) self.selectItem() else: QMessageBox.information(self, 'PyQt5 message', "Please enter a taskname first!", QMessageBox.Ok) print("please enter a name of the task you want to add first") def _click_deltask(self): print("Ooopsie") task_id = None for _x in self.tasks.selectedItems(): task_id = _x.data(Qt.UserRole) print(task_id) if task_id is not None: api.task_delete(self.api_token, task_id) self.selectItem() else: QMessageBox.information(self, 'PyQt5 message', "unable to delete task, no such task_id", QMessageBox.Ok) def clickStart(self): logging.debug("click start/stop button") print(self.button.text()) #self.test.clear() data = {} ''' user click start timer ''' if self.button.text() == 'Start': project_id = None task_id = None for _x in self.test.selectedItems(): project_id = _x.data(Qt.UserRole) for _x in self.tasks.selectedItems(): task_id = _x.data(Qt.UserRole) if project_id == None: msgBox = QMessageBox() msgBox.setIcon(QMessageBox.Information) msgBox.setText("Please select a project first") msgBox.setWindowTitle("Select project") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() print("Please select one of your project first") return 0 else: data = api.activity_start(self.api_token, project_id, task_id) ''' this need to be fix ''' try: if data.get('error'): errorBox = DialogBox() returnValue = errorBox.MsgBox( data.get('error') + "Do you want to stop current activity?", "error") if returnValue == QMessageBox.Ok: data = api.activity_current(self.api_token) print(data) api.activity_stop(self.api_token, data['id']) print("Time to do something weired!") return 0 #do we need this? #print(data.get('error')) elif data: #apa = IdleTime() self.apa.thread_exit = False print(self.workingthread) self.workingthread = QThread() self.workingthread.started.connect(self.apa.thread_handle) #self.apa.moveToThread(self.workingthread) self.workingthread.start() self.thread_exit = False t = threading.Thread(target=self._update_timer) t.start() self.systray.StartWorking.setText("Stop Working") self.button.setText('Stop') fa5s_icon = qta.icon('fa5s.stop') self.button.setIcon(fa5s_icon) self.test.setDisabled(True) return 1 except AttributeError: ''' if we reach this stage we either got an invalid API response (no error field) or our internet connection isnt working ''' #errorBox = DialogBox() #errorBox.MsgBox("No internet connection or invalid API response", "error") QMessageBox.information( self, 'error', "No internet connection or invalid API response", QMessageBox.Ok) else: ''' stop activity if its running ''' data = api.activity_current(self.api_token) print(data) api.activity_stop(self.api_token, data['id']) self.thread_exit = True self.apa.thread_exit = True self.systray.StartWorking.setText("Start Working") self.button.setText('Start') fa5s_icon = qta.icon('fa5s.play') self.button.setIcon(fa5s_icon) self.test.setDisabled(False) print("end of clickstart") def selectItem(self): for _x in self.test.selectedItems(): self.label3.setText(_x.text()) print(_x.text()) print(_x.data(Qt.UserRole)) try: data = api.task_get(self.api_token, _x.data(Qt.UserRole)) except ApiException: data = self.db.searchTask(_x.data(Qt.UserRole)) self.tasks.clear() print(data) for _x in data: item = QListWidgetItem(_x["name"], self.tasks) item.setData(Qt.UserRole, _x["task_id"]) #print(self.test.text()) def NetworkSetup(self): self.test.clear() data_p2 = None data_p = None try: data_p = api.get_projects(self.api_token) except ApiException: data_p = self.db.readDatabase()["projects"] #print("data_p:") #print(data_p) #print("data_p2") #print(data_p2) l = [] print(data_p) for _x in data_p: print("loop") print(_x) #self.test.addItem(_x["name"]) item = QListWidgetItem(_x["name"], self.test) item.setData(Qt.UserRole, _x["id"]) #l = [] try: lol = api.task_get(self.api_token, _x["id"]) print(lol) for _x in lol: #if len(lol) > 0: l.append(_x) except ApiException: pass #print(lol) print(l) if len(l) > 0: self.db.saveTasks(l) end_date = datetime.utcnow().isoformat() start_date = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0).isoformat() try: data = api.get_activity(self.api_token, start_date, end_date) except ApiException: data = [{"duration": 20}, {"duration": 400}, {"duration": 300}] print(data) for _x in data: #self.db.save_activity() self.elapsed_time += _x['duration'] ''' Set timer ''' self.labeltimer.setText(self._online_time(self.elapsed_time)) if len(data) > 0: self.db.save_activity(data) try: whoami = api.whoami(self.api_token) self.db.saveUser(whoami["username"], whoami["api_token"], whoami['api_expire']) self.db.saveProjects(data_p) except (ApiException, TypeError): pass #self.db.saveTasks def _online_time(self, data): hour = 0 minute = 0 second = 0 hour = int(data / 60 / 60) data = data - (hour * 3600) minute = int(data / 60) data = data - (minute * 60) second = int(data) if hour < 10: hour = "0" + str(hour) if minute < 10: minute = "0" + str(minute) if second < 10: second = "0" + str(second) time_string = str(hour) + ":" + str(minute) + ":" + str(second) return time_string def closeEvent(self, event): data = api.activity_current(self.api_token) print(data) try: if data.get('error'): msg = "are you sure you want to quit?" elif data.get('id'): msg = "Are you sure you want to quit? if you quit the app we will stop the timetracker." except: msg = "Are you sure you want to quit" #pass errorBox = DialogBox() returnValue = errorBox.MsgBox(msg, "error") if returnValue == QMessageBox.Ok: #if data.get('id'): try: api.activity_stop(self.api_token, data['id']) except (TypeError, KeyError): pass self.thread_exit = True self.apa.thread_exit = True time.sleep(2) event.accept() else: event.ignore() print("close event")
class SelectPackages_Dialog(QDialog): def __init__(self, parent, packages): super(SelectPackages_Dialog, self).__init__(parent) self.file_paths = [] self.required_packages = packages self.setLayout(QVBoxLayout()) self.layout().addWidget( QLabel( 'You need to select the locations of the following required node packages' )) # package lists required_packages_list_widget = QListWidget() for p in packages: package_item = QListWidgetItem() package_item.setText(p) required_packages_list_widget.addItem(package_item) selected_items_widget = QWidget() selected_items_widget.setLayout(QVBoxLayout()) self.selected_packages_list_widget = QListWidget() selected_items_widget.layout().addWidget( self.selected_packages_list_widget) auto_import_button = QPushButton('auto import') auto_import_button.setFocus() auto_import_button.clicked.connect(self.auto_import_button_clicked) selected_items_widget.layout().addWidget(auto_import_button) add_package_button = QPushButton('add') add_package_button.clicked.connect(self.add_package_button_clicked) selected_items_widget.layout().addWidget(add_package_button) clear_package_list_button = QPushButton('clear') clear_package_list_button.clicked.connect( self.clear_selected_packages_list) selected_items_widget.layout().addWidget(clear_package_list_button) finished_button = QPushButton('OK') finished_button.clicked.connect(self.finished_button_clicked) selected_items_widget.layout().addWidget(finished_button) packages_lists_widget = QWidget() packages_lists_widget.setLayout(QHBoxLayout()) packages_lists_widget.layout().addWidget(required_packages_list_widget) packages_lists_widget.layout().addWidget(selected_items_widget) self.layout().addWidget(packages_lists_widget) self.setWindowTitle('select required packages') def auto_import_button_clicked(self): packages_dir = '../packages' folders_list = [ x[0] for x in os.walk(packages_dir) if os.path.basename( os.path.normpath(x[0])) in self.required_packages ] required_files = self.required_packages.copy() for folder in folders_list: for r_f in required_files: if r_f + '.rpc' in os.listdir(packages_dir + '/' + folder): self.file_paths.append( os.path.normpath(packages_dir + '/' + folder + '/' + r_f + '.rpc')) break self.rebuild_selected_packages_list_widget() self.clean_packages_list() if self.all_required_packages_selected(): self.finished() def add_package_button_clicked(self): file_names = \ QFileDialog.getOpenFileNames(self, 'select package files', '../packages', 'Ryven Package(*.rpc)')[0] for file_name in file_names: try: f = open(file_name) f.close() self.file_paths.append(file_name) except FileNotFoundError: Debugger.debug('couldn\'t open file') self.rebuild_selected_packages_list_widget() def rebuild_selected_packages_list_widget(self): # remove all items self.selected_packages_list_widget.clear() for f in self.file_paths: file_item = QListWidgetItem() file_item.setText(f) self.selected_packages_list_widget.addItem(file_item) def clear_selected_packages_list(self): self.file_paths.clear() self.rebuild_selected_packages_list_widget() def finished_button_clicked(self): self.clean_packages_list() if self.all_required_packages_selected(): self.finished() def clean_packages_list(self): """remove duplicates from self.file_paths""" files_dict = {} for p in self.file_paths: filename = os.path.splitext(os.path.basename(p))[0] files_dict[filename] = p self.file_paths = list(files_dict.values()) self.rebuild_selected_packages_list_widget() def all_required_packages_selected(self): files = [ os.path.splitext(os.path.basename(path))[0] for path in self.file_paths ] # search for missing packages for p in self.required_packages: if p not in files: return False return True def finished(self): self.accept()
class FileSystemWidget(QWidget, DirectoryObserver): """ Widget for listing directory contents and download files from the RDP client. """ # fileDownloadRequested(file, targetPath, dialog) fileDownloadRequested = Signal(File, str, FileDownloadDialog) def __init__(self, root: Directory, parent: QObject = None): """ :param root: root of all directories. Directories in root will be displayed with drive icons. :param parent: parent object. """ super().__init__(parent) self.root = root self.breadcrumbLabel = QLabel() self.titleLabel = QLabel() self.titleLabel.setStyleSheet("font-weight: bold") self.titleSeparator: QFrame = QFrame() self.titleSeparator.setFrameShape(QFrame.HLine) self.listWidget = QListWidget() self.listWidget.setSortingEnabled(True) self.listWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.listWidget.customContextMenuRequested.connect(self.onCustomContextMenu) self.verticalLayout = QVBoxLayout() self.verticalLayout.addWidget(self.breadcrumbLabel) self.verticalLayout.addWidget(self.listWidget) self.setLayout(self.verticalLayout) self.listWidget.itemDoubleClicked.connect(self.onItemDoubleClicked) self.currentPath: Path = Path("/") self.currentDirectory: Directory = root self.listCurrentDirectory() self.currentDirectory.addObserver(self) def setWindowTitle(self, title: str): """ Set the window title. When the title is not blank, a title label and a separator is displayed. :param title: the new title. """ previousTitle = self.windowTitle() super().setWindowTitle(title) self.titleLabel.setText(title) if previousTitle == "" and title != "": self.verticalLayout.insertWidget(0, self.titleLabel) self.verticalLayout.insertWidget(1, self.titleSeparator) elif title == "" and previousTitle != "": self.verticalLayout.removeWidget(self.titleLabel) self.verticalLayout.removeWidget(self.titleSeparator) # noinspection PyTypeChecker self.titleLabel.setParent(None) # noinspection PyTypeChecker self.titleSeparator.setParent(None) def onItemDoubleClicked(self, item: FileSystemItem): """ Handle double-clicks on items in the list. When the item is a directory, the current path changes and the contents of the directory are listed. Files are ignored. :param item: the item that was clicked. """ if not item.isDirectory() and not item.isDrive(): return if item.text() == "..": self.currentPath = self.currentPath.parent else: self.currentPath = self.currentPath / item.text() self.listCurrentDirectory() def listCurrentDirectory(self): """ Refresh the list widget with the current directory's contents. """ node = self.root for part in self.currentPath.parts[1 :]: node = next(d for d in node.directories if d.name == part) self.listWidget.clear() self.breadcrumbLabel.setText(f"Location: {str(self.currentPath)}") if node != self.root: self.listWidget.addItem(FileSystemItem("..", FileSystemItemType.Directory)) for directory in node.directories: self.listWidget.addItem(FileSystemItem(directory.name, directory.type)) for file in node.files: self.listWidget.addItem(FileSystemItem(file.name, file.type)) if node is not self.currentDirectory: self.currentDirectory.removeObserver(self) node.addObserver(self) self.currentDirectory = node node.list() def onDirectoryChanged(self): """ Refresh the directory view when the directory has changed. """ self.listCurrentDirectory() def currentItemText(self) -> str: try: return self.listWidget.selectedItems()[0].text() except IndexError: return "" def selectedFile(self) -> Optional[File]: text = self.currentItemText() if text == "": return None if text == "..": return self.currentDirectory.parent for sequence in [self.currentDirectory.files, self.currentDirectory.directories]: for file in sequence: if text == file.name: return file return None def canDownloadSelectedItem(self) -> bool: return self.selectedFile().type == FileSystemItemType.File def onCustomContextMenu(self, localPosition: QPoint): """ Show a custom context menu with a "Download file" action when a file is right-clicked. :param localPosition: position where the user clicked. """ selectedFile = self.selectedFile() if selectedFile is None: return globalPosition = self.listWidget.mapToGlobal(localPosition) downloadAction = QAction("Download file") downloadAction.setEnabled(selectedFile.type in [FileSystemItemType.File]) downloadAction.triggered.connect(self.downloadFile) itemMenu = QMenu() itemMenu.addAction(downloadAction) itemMenu.exec_(globalPosition) def downloadFile(self): file = self.selectedFile() if file.type != FileSystemItemType.File: return filePath = file.getFullPath() targetPath, _ = QFileDialog.getSaveFileName(self, f"Download file {filePath}", file.name) if targetPath != "": dialog = FileDownloadDialog(filePath, targetPath, self) dialog.show() self.fileDownloadRequested.emit(file, targetPath, dialog)
class QtEpsInfo(QtWidgets.QWidget, Ui_EpsInfo): def __init__(self, owner): super(self.__class__, self).__init__() Ui_EpsInfo.__init__(self) self.setupUi(self) self.owner = weakref.ref(owner) self.epsListWidget = QListWidget() self.epsListWidget.setFlow(self.epsListWidget.LeftToRight) self.epsListWidget.setWrapping(True) self.epsListWidget.setFrameShape(self.epsListWidget.NoFrame) self.epsListWidget.setResizeMode(self.epsListWidget.Adjust) self.epsListWidget.itemClicked.connect(self.SelectEps) self.gridLayout_2.addWidget(self.epsListWidget, 1, 0) self.closeFlag = self.__class__.__name__ self.bookId = "" self.loadingForm = QtLoading(self) self.setWindowTitle("章节列表") self.greed = QColor(18, 161, 130) self.blue = QColor(97, 154, 195) self.white = QColor(0, 0, 0, 0) def OpenEpsInfo(self, bookId): self.show() self.loadingForm.show() self.bookId = bookId self.epsListWidget.clear() if bookId not in BookMgr().books: self.owner().qtTask.AddHttpTask(lambda x: BookMgr().AddBookById(self.bookId, x), self.OpenBookInfoBack, cleanFlag=self.closeFlag) else: self.owner().qtTask.AddHttpTask(lambda x: BookMgr().AddBookEpsInfo(self.bookId, x), self.OpenEpsInfoBack, cleanFlag=self.closeFlag) def OpenBookInfoBack(self, msg): if msg == Status.Ok: self.owner().qtTask.AddHttpTask(lambda x: BookMgr().AddBookEpsInfo(self.bookId, x), self.OpenEpsInfoBack, cleanFlag=self.closeFlag) else: self.loadingForm.close() def OpenEpsInfoBack(self, msg): self.loadingForm.close() self.epsListWidget.clear() if msg == Status.Ok: self.UpdateEpsInfo() return def UpdateEpsInfo(self): self.epsListWidget.clear() info = BookMgr().books.get(self.bookId) if not info: return downloadEpsId = self.owner().downloadForm.GetDownloadEpsId(self.bookId) for index, epsInfo in enumerate(info.eps): label = QLabel(epsInfo.title) label.setContentsMargins(20, 10, 20, 10) item = QListWidgetItem(self.epsListWidget) item.setSizeHint(label.sizeHint()) if index in downloadEpsId: item.setBackground(self.greed) else: item.setBackground(self.white) self.epsListWidget.setItemWidget(item, label) def SelectEps(self, item): if item.background().color() == self.greed: return elif item.background().color() == self.blue: item.setBackground(self.white) else: item.setBackground(self.blue) return def SelectAll(self): for i in range(self.epsListWidget.count()): item = self.epsListWidget.item(i) if item.background().color() == self.greed: continue item.setBackground(self.blue) return def CancleSelect(self): for i in range(self.epsListWidget.count()): item = self.epsListWidget.item(i) if item.background().color() == self.greed: continue item.setBackground(self.white) return def StartDownload(self): downloadIds = [] for i in range(self.epsListWidget.count()): item = self.epsListWidget.item(i) if item.background().color() == self.blue: downloadIds.append(i) if not downloadIds: return self.owner().downloadForm.AddDownload(self.bookId, downloadIds) self.UpdateEpsInfo() return
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('清单') self.setFixedSize(320, 480) # 布局 layout = QVBoxLayout() # 清单视图 self.items_view = QListWidget() self.items_view.setIconSize(QSize(14, 14)) self.items_view.doubleClicked.connect(self.toggle_complete) layout.addWidget(self.items_view) # 按钮布局 button_layout = QHBoxLayout() layout.addLayout(button_layout) # delete button self.delete_button = QPushButton('DELETE') self.delete_button.clicked.connect(self.delete) button_layout.addWidget(self.delete_button) # Complete button self.complete_button = QPushButton('COMPLETE') self.complete_button.clicked.connect(self.complete) button_layout.addWidget(self.complete_button) # add input self.add_input = QLineEdit() self.add_input.returnPressed.connect(self.add) layout.addWidget(self.add_input) # add button self.add_button = QPushButton('ADD') self.add_button.clicked.connect(self.add) layout.addWidget(self.add_button) # status bar self.setStatusBar(QStatusBar()) container = QWidget() container.setLayout(layout) self.setCentralWidget(container) self.setStyleSheet(""" QListWidget { border: 1px solid #999; font-size: 13px; } QListWidget::item { color: #000; height: 30px; border-bottom: 1px solid #dedede; } QListWidget::item:selected { background-color: #fff9dd; } QPushButton { height: 24px; background-color: #fddb3a; font-weight: 900; } QLineEdit { padding: 5px; } """) self.items = [] self.load() self.list_items() @Slot() def add(self): name = self.add_input.text() if name: self.items_view.addItem(QListWidgetItem(name)) self.add_input.setText('') self.items.append({'name': name, 'done': False}) # self.save() db.save(name, False) @Slot() def delete(self): items = self.items_view.selectedItems() if items: self.items.pop(self.items_view.currentRow()) db.delete(self.items_view.currentRow() + 1) self.items_view.clear() self.list_items() # self.save() @Slot() def complete(self): items = self.items_view.selectedItems() if items: item_data = self.items[self.items_view.currentRow()] if not item_data['done']: icon = QIcon('done.svg') items[0].setIcon(icon) item_data['done'] = True # self.save() db.update(True, self.items_view.currentRow() + 1) @Slot() def toggle_complete(self): items = self.items_view.selectedItems() if items: item_data = self.items[self.items_view.currentRow()] if not item_data['done']: icon = QIcon('done.svg') items[0].setIcon(icon) item_data['done'] = True db.update(True, self.items_view.currentRow() + 1) else: icon = QIcon('') items[0].setIcon(icon) item_data['done'] = False db.update(False, self.items_view.currentRow() + 1) # self.save() def list_items(self): for item in self.items: list_item = QListWidgetItem(item['name']) if item['done']: icon = QIcon('done.svg') list_item.setIcon(icon) self.items_view.addItem(list_item) def load(self): # with open('data.json', 'r') as f: # self.items = json.load(f) self.items = db.select() def save(self): with open('data.json', 'w') as f: json.dump(self.items, f)
class CreationContainer(QWidget): """ Apparently just another level of parent class for social link display. Man I was stupid. Still am luigi2hands :param MainFrame mainframe: application mainframe :param QWidget op: parent widget :param int load: index to load maybe? """ def __init__(self, mainframe, op, load): QWidget.__init__(self) self.mainframe = mainframe self.op = op self.op.cc = self self.load = load # View initializers... self.actions = None self.window = None self.initUI() self.op.grid.addWidget(self, 0, 0, 2, 10) def initUI(self): """ Initialize the GUI. Does lots of stuff. """ self.grid = QGridLayout() self.setLayout(self.grid) self.actions = self.op.link.getIDs() self.actions.append("New element") types = ["Info", "Speak", "Camera Change", "Movement"] self.save = QPushButton(self, text="Save") self.grid.addWidget(self.save, 3, 0) self.existing_connections = QListWidget(self) self.populateExistingConnections() self.grid.addWidget(self.existing_connections, 1, 5, 2, 1) self.next = QComboBox(self) self.next.addItems(self.actions) self.next.setMaximumWidth(150) if self.load != 0: self.next.setCurrentIndex(self.op.i) self.grid.addWidget(self.next, 3, 2) self.window = None self.actOM = QComboBox(self) self.actOM.addItems(types) self.actOM.activated.connect(self.changeFrame) self.grid.addWidget(self.actOM, 0, 0, 1, 2) self.connect() self.next.setCurrentIndex(self.next.count() - 1) self.backB = QPushButton(self, text="Back to List Menu") self.backB.clicked.connect(self.back) self.grid.addWidget(self.backB, 3, 4) self.lead = QLabel(self, text="Leads to:") self.lead.setAlignment(Qt.AlignRight) self.grid.addWidget(self.lead, 3, 1) self.connectB = QPushButton(self, text="Connect") self.connectB.clicked.connect(self.lightConnect) self.grid.addWidget(self.connectB, 3, 3) self.follow_path = QPushButton(self, text="Enter linked element") self.follow_path.clicked.connect(self.follow) self.grid.addWidget(self.follow_path, 0, 6, 2, 1) self.rmvRel = QPushButton(self, text="Remove this connection") self.rmvRel.clicked.connect(self.removeRelation) self.grid.addWidget(self.rmvRel, 1, 6, 2, 1) self.conLab = QLabel(self, text="This action connects to:") self.grid.addWidget(self.conLab, 0, 5) def removeRelation(self): """ Remove a relation, which will also delete the uniquely dependant subtree. """ if not self.existing_connections.currentItem() or \ not popup("Are you sure you want to remove this relation? Any elements with a unique dependancy " "on this relation will also be deleted.\nIt is highly recommended you take a look at " "the graphical view of the tree in order to see the potential effects of the deletion.", "Warning"): return self.op.link.delRelation( self.op.i, self.actions.index(self.existing_connections.currentItem().text())) self.populateExistingConnections() self.updateElementList() self.op.linkstored.save() def populateExistingConnections(self): """ Display all the existing connections of the current node. """ self.existing_connections.clear() for relation in self.op.link.getRelations(self.op.i): self.existing_connections.addItem( self.op.link.getOneID(self.op.link.getItem(relation))) def back(self): """ Return to the higher-level cutscene container view... """ if not popup("Return to list main menu?\n(Lose any unsaved changes)", "Warning"): return self.close() self.op.cc = None self.op.viewF(False) def follow(self): """ Move on to the edit view of the selected relationship. """ if not self.existing_connections.currentItem() or \ self.existing_connections.currentItem().text() == "": return self.next.setCurrentIndex([ self.next.itemText(i) for i in range(self.next.count()) ].index(self.existing_connections.currentItem().text())) self.op.i = self.actions.index(self.next.currentText()) self.connect() self.next.setCurrentIndex(self.next.count() - 1) def lightConnect(self): """ Create a relationship between the current action and another. """ if not self.checkCached(): popup("Please save this action before linking it to a new one", "Information") return if self.next.currentText() == "New element": self.op.link.addRelation(self.op.i, self.op.link.size()) print("Linked to index " + str(self.op.link.size())) self.op.i = self.op.link.size() self.load = 0 self.changeFrame(0) self.updateElementList() else: self.op.link.addRelation( self.op.i, self.actions.index(self.next.currentText())) print("Linked to index " + str(self.actions.index(self.next.currentText()))) self.populateExistingConnections() def connect(self): """ Create a relationship between the current action and another, and enter the edit view of the relationship. :raises Exception: if the requested new action's type can't be processed (should never happen) """ print(self.next.currentText()) if self.next.currentText() == "New element": self.load = 0 self.changeFrame(0) else: if isinstance( self.op.link.getItem( self.actions.index(self.next.currentText())), Info): self.actOM.setCurrentIndex(0) elif isinstance( self.op.link.getItem( self.actions.index(self.next.currentText())), Speak): self.actOM.setCurrentIndex(1) elif isinstance( self.op.link.getItem( self.actions.index(self.next.currentText())), Camera): self.actOM.setCurrentIndex(2) elif isinstance( self.op.link.getItem( self.actions.index(self.next.currentText())), Movement): self.actOM.setCurrentIndex(3) else: raise Exception("Not a type!") self.load = self.op.link.getItem( self.actions.index(self.next.currentText())) self.changeFrame(0) def checkCached(self): """ Check if the current element has been saved before. :returns: if the element has been saved :rtype: bool """ print(len(self.op.link.items) - 1) print(self.op.i) if self.op.link.getItem(self.op.i) == []: return False return True def updateElementList(self): """ Update the relationships list, I think. """ self.next.clear() self.actions = self.op.link.getIDs() self.actions.append("New element") self.next.addItems(self.actions) self.next.setCurrentIndex(len(self.actions) - 1) def changeFrame(self, _): """ Change view to edit a certain type of action. :param objct _: unused, but required by caller """ print("Changed to " + self.actOM.currentText()) try: self.window.close() except AttributeError: pass # No window open if self.actOM.currentText() == "Speak": self.window = SpeakFrame(self, self.load) elif self.actOM.currentText() == "Camera Change": self.window = CameraFrame(self, self.load) elif self.actOM.currentText() == "Movement": self.window = MoveFrame(self, self.load) else: # self.actOM.currentText() == "Info": self.window = InfoFrame(self, self.load) try: self.save.clicked.disconnect() except: #pylint: disable=bare-except pass self.save.clicked.connect(self.window.save) self.populateExistingConnections() self.updateElementList()
class Widget(QWidget): def __init__(self): QWidget.__init__(self) # Data for plotting and marker data storage self.data = {} self.slice_index = { 'ind1': 0, 'ind2': 0 } self.marker_id = 0 self.marker_ind = [] self.marker_setpoint = { 'Marker1': 0, 'Marker2': 0, } # Error message dialog widget self.error_popup = QErrorMessage() self.error_popup.setWindowTitle('Snap file error') # Left (List of Checkboxes) self.list_widget = QListWidget() #Resize width and height self.list_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.list_widget.setMinimumWidth(200) self.list_widget.setMaximumWidth(400) # self.list_widget.setMinimumHeight(300) self.list_widget.setMaximumHeight(500) # Signal groupbox self.signal_groupbox = QGroupBox('Available Signals') self.signal_groupbox.setMinimumWidth(200) self.signal_groupbox.setMaximumWidth(350) self.signal_groupbox.setMinimumHeight(100) self.sig_group_layout = QVBoxLayout() self.signal_groupbox.setLayout(self.sig_group_layout) # Statistics groupbox self.stats_groupbox = QGroupBox('Statistics') self.stats_groupbox.setMinimumWidth(200) self.stats_groupbox.setMaximumWidth(350) self.stats_groupbox.setMinimumHeight(240) self.stats_group_layout = QFormLayout() # Label initiation # Marker Time 1 self.mark_one_time_label = QLabel('Marker1_time: ') self.mark_one_time_value = QLabel() # Marker Time 2 self.mark_two_time_label = QLabel('Marker2_time: ') self.mark_two_time_value = QLabel() # On/Off labels for 0/1 signals counter self.on_off_label = QLabel('On/Off: ') self.on_off_value = QLabel() # Mean value self.mean_label = QLabel('Mean: ') self.mean_value = QLabel() # Standard deviation self.std_label = QLabel('Sigma(STD): ') self.std_value = QLabel() # Minimal value self.min_label = QLabel('Min: ') self.min_value = QLabel() # Maximual value self.max_label = QLabel('Max: ') self.max_value = QLabel() # Max - Min value self.val_diff_label = QLabel('Max-Min: ') self.val_diff_value = QLabel() # Time difference (X-axis) self.time_diff_label = QLabel('Time_diff: ') self.time_diff_value = QLabel('') # Row addition of labels self.stats_group_layout.addRow(self.mark_one_time_label, self.mark_one_time_value) self.stats_group_layout.addRow(self.mark_two_time_label, self.mark_two_time_value) self.stats_group_layout.addRow(self.time_diff_label, self.time_diff_value) self.stats_group_layout.addRow(self.on_off_label, self.on_off_value) self.stats_group_layout.addRow(self.mean_label, self.mean_value) self.stats_group_layout.addRow(self.std_label, self.std_value) self.stats_group_layout.addRow(self.min_label, self.min_value) self.stats_group_layout.addRow(self.max_label, self.max_value) self.stats_group_layout.addRow(self.val_diff_label, self.val_diff_value) self.stats_groupbox.setLayout(self.stats_group_layout) # Set markers section of the application (bottom left) self.marker_grid = QGridLayout() self.marker_one_notice = QLabel() self.marker_two_notice = QLabel() self.set_marker_one_label = QLabel('Set Marker1:') self.set_marker_two_label = QLabel('Set Marker2:') self.set_marker_one_value = QLineEdit() self.set_marker_one_value.setMaximumWidth(100) self.set_marker_two_value = QLineEdit() self.set_marker_two_value.setMaximumWidth(100) self.marker_grid.addWidget(self.set_marker_one_label) self.marker_grid.addWidget(self.set_marker_one_value) self.marker_grid.addWidget(self.marker_one_notice) self.marker_grid.addWidget(self.set_marker_two_label) self.marker_grid.addWidget(self.set_marker_two_value) self.marker_grid.addWidget(self.marker_two_notice) # Leftside app layout self.v_layout = QVBoxLayout() self.v_layout.addWidget(self.list_widget) self.v_layout.addWidget(self.signal_groupbox) self.v_layout.addWidget(self.stats_groupbox) self.v_layout.addLayout(self.marker_grid) # Matplotlib figure self.fig = Figure(figsize=(5, 3)) self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.ax = self.canvas.figure.subplots() self.ax.grid() self.ax.set_xlabel('Time[s]') self.fig.suptitle('Parameter Plot') # QWidget Layout self.h_layout = QHBoxLayout() self.h_layout.addLayout(self.v_layout) self.h_layout.addWidget(self.canvas) # Set the layout to the QWidget self.setLayout(self.h_layout) # ListWidget and plot connections self.list_widget.itemChanged.connect(self.item_changed) self.click_event = self.fig.canvas.mpl_connect('button_press_event', self.on_click) self.set_marker_one_value.returnPressed.connect( lambda: self.add_marker('one')) self.set_marker_two_value.returnPressed.connect( lambda: self.add_marker('two')) # Add radio button when signal is checked for plotting def add_radio_button(self, name): self.rad_btn = QRadioButton(name) self.rad_btn.toggled.connect(self.calculate_signal_stats) self.sig_group_layout.addWidget(self.rad_btn) # Remove radio button when signal is unchecked for plotting def remove_radio_button(self, name): for item in self.signal_groupbox.children(): try: if item.text() == name: item.setParent(None) except AttributeError: pass # Remove all radiobuttons on new data load def clear_signals(self): count = 0 for item in self.signal_groupbox.children(): if count == 0: count = 1 continue else: item.setParent(None) # Check state of all radiobuttons, if none is checked remove stats values def check_signals(self): count = 0 num_of_check = 0 for item in self.signal_groupbox.children(): if count == 0: count = 1 continue else: if item.isChecked(): num_of_check += 1 # If no radiobuttons are checked, remove stats if num_of_check == 0: self.mean_value.setText('') self.std_value.setText('') self.max_value.setText('') self.min_value.setText('') self.val_diff_value.setText('') self.on_off_value.setText('') # Item additon of listWidget def fill_list(self, list_items): self.list_widget.clear() for column in list_items: item = QListWidgetItem(column) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) item.setCheckState(Qt.Unchecked) self.list_widget.addItem(item) self.show() # If new data is loaded, replace the old one def replace_data(self, temp): if not temp == self.data: self.data = temp self.clear_signals() @Slot() # Item state changed in listWidget event handler def item_changed(self, item): if item.checkState() == Qt.Unchecked: self.remove_plot(item.text()) self.remove_radio_button(item.text()) self.check_signals() else: self.add_plot(self.data['Time'], self.data[item.text()], item.text()) self.add_radio_button(item.text()) # Method for plotting data def add_plot(self, x_data, y_data, name): self.ax.plot(x_data, y_data, label=name, picker=3) self.ax.grid(True) self.ax.relim() self.ax.set_xlabel('Time[s]') self.ax.autoscale_view() self.ax.legend(loc='upper right') self.canvas.draw() # Method for marker addition via QLineEdit def add_marker(self, label): # Check if any signal is plotted sig_count = 0 for i in range(self.list_widget.count()): if self.list_widget.item(i).checkState() == Qt.Checked: sig_count += 1 if sig_count == 0: self.marker_one_notice.setText('No active signal!') self.marker_two_notice.setText('No active signal!') return try: max_time = self.data['Time'][-1] min_time = self.data['Time'][0] except KeyError: self.marker_one_notice.setText('Signal data not loaded!') self.marker_two_notice.setText('Signal data not loaded!') if label == 'one': try: mark1_value = float(self.set_marker_one_value.text()) if mark1_value < max_time and mark1_value > min_time: if self.marker_id == 0: self.marker_id += 1 label_id = self.marker_id elif self.marker_id == 1: self.marker_id += 1 label_id = self.marker_id self.remove_marker('first') else: self.remove_marker('first') label_id = 1 self.marker_one_notice.setText('') self.marker_setpoint['Marker1'] = mark1_value self.mark_one_time_value.setText( self.set_marker_one_value.text()) self.calculate_marker_stats() self.calculate_signal_stats() # Draw the marker L = self.ax.axvline( x=float(self.set_marker_one_value.text()), linestyle='dashed', color='red', label='_Marker' + str(label_id)) self.fig.canvas.draw() else: self.marker_one_notice.setText('Marker1 out of bounds') except ValueError: self.marker_one_notice.setText('Non-Valid value entered!') else: try: mark2_value = float(self.set_marker_two_value.text()) if mark2_value < max_time and mark2_value > min_time: if self.marker_id == 1: self.marker_id += 1 label_id = self.marker_id elif self.marker_id == 2: label_id = 2 self.remove_marker('second') else: self.marker_two_notice.setText('Marker1 not placed') self.marker_two_notice.setText('') self.marker_setpoint['Marker2'] = mark2_value self.mark_two_time_value.setText( self.set_marker_two_value.text()) self.calculate_marker_stats() self.calculate_signal_stats() # Draw the marker L = self.ax.axvline( x=float(self.set_marker_two_value.text()), linestyle='dashed', color='red', label='_Marker' + str(label_id)) self.fig.canvas.draw() else: self.marker_two_notice.setText('Marker2 out of bounds') except: self.marker_two_notice.setText('Non-Valid value entered!') # Marker removal method def remove_marker(self, label): for item in self.ax.lines: if 'Marker' in item.get_label(): self.marker_ind.append(item) # If there are two markers remove them from plot and adjust marker # time labels if label == 'both': self.marker_ind[0].remove() self.marker_ind[1].remove() self.marker_ind = [] self.marker_setpoint['Marker1'] = 0 self.marker_setpoint['Marker2'] = 0 self.mark_one_time_value.setText('') self.mark_two_time_value.setText('') self.time_diff_value.setText('') self.marker_id = 0 # Remove only marker1 elif label == 'first': self.marker_ind[0].remove() self.marker_ind = [] self.marker_setpoint['Marker1'] = 0 self.mark_one_time_value.setText('') self.marker_id -= 1 elif label == 'second': self.marker_ind[1].remove() self.marker_ind = [] self.marker_setpoint['Marker2'] = 0 self.mark_two_time_value.setText('') self.marker_id -= 1 self.ax.set_xlabel('Time[s]') self.canvas.draw() # Method for plot removal def remove_plot(self, name): cnt = 0 for item in self.ax.lines: if item.get_label() == name: self.ax.lines[cnt].remove() cnt += 1 self.ax.relim() self.ax.autoscale_view() self.ax.legend(loc='upper right') self.ax.set_xlabel('Time[s]') self.canvas.draw() # Check if all elements are unticked counter = 0 for i in range(self.list_widget.count()): if self.list_widget.item(i).checkState() == Qt.Checked: counter +=1 if counter == 0: self.remove_marker('both') # On click event for plot, only two markers can be active at the time def on_click(self, event): try: # Catch left click event if event.button == 1: x = event.xdata if self.marker_id < 2: if self.marker_id == 0: self.marker_setpoint['Marker1'] = round(x) self.mark_one_time_value.setText( str(self.marker_setpoint['Marker1'])) self.calculate_marker_stats() self.calculate_signal_stats() else: self.marker_setpoint['Marker2'] = round(x) self.mark_two_time_value.setText( str(self.marker_setpoint['Marker2'])) self.calculate_marker_stats() self.calculate_signal_stats() self.marker_id += 1 L = self.ax.axvline(x=x, linestyle='dashed', color='red', label='_Marker' + str(self.marker_id)) self.fig.canvas.draw() # Catch right click event elif event.button == 3: self.remove_marker('both') except TypeError: pass # Marker analysis method def calculate_marker_stats(self): if self.marker_setpoint['Marker2'] == 0: diff = self.data['Time'][-1] - self.marker_setpoint['Marker1'] self.time_diff_value.setText(str(diff)) else: diff = self.marker_setpoint['Marker2'] - \ self.marker_setpoint['Marker1'] self.time_diff_value.setText(convert_seconds(diff)) # Signal analysis method def calculate_signal_stats(self): self.check_signals() selected_signal = '' signal_data = [] num_off, num_on = 0, 0 for item in self.signal_groupbox.children(): try: if item.isChecked(): # Signal extraction block selected_signal = item.text() # If only one marker, Marker1 is placed on graph if self.marker_setpoint['Marker2'] == 0 and self.marker_setpoint['Marker1'] != 0: for i in range(len(self.data['Time'])): if self.data['Time'][i] > self.marker_setpoint['Marker1']: self.slice_index['ind1'] = i break signal_data = np.asarray( self.data[selected_signal][self.slice_index['ind1']:], dtype=np.float32) # Both markers, Marker1 and Marker2 are present on graph elif self.marker_setpoint['Marker1'] != 0 and self.marker_setpoint['Marker2'] != 0: for i in range(len(self.data['Time'])): if self.data['Time'][i] > self.marker_setpoint['Marker1']: self.slice_index['ind1'] = i break for i in range(len(self.data['Time'])): if self.data['Time'][len(self.data['Time']) - i - 1] < self.marker_setpoint['Marker2']: self.slice_index['ind2'] = len(self.data['Time']) - i break signal_data = np.asarray( self.data[selected_signal][self.slice_index['ind1']:self.slice_index['ind2'] - 1], dtype=np.float32) # No markers present, whole signal stats are showed else: signal_data = np.asarray(self.data[selected_signal], dtype=np.float32) try: # Signal mean calculation self.mean_value.setText(str(np.mean(signal_data))) # Standard deviation self.std_value.setText(str(np.std(signal_data))) # Maximum value self.max_value.setText(str(np.max(signal_data))) # Minimum value self.min_value.setText(str(np.min(signal_data))) # Max - Min self.val_diff_value.setText(str(np.max(signal_data) - (np.min(signal_data)))) if np.max(signal_data) == 1.0: for i in range(len(signal_data)): if i != len(signal_data) - 1: temp = signal_data[i] - signal_data[i+1] if temp == 1: num_off += 1 elif temp == -1: num_on += 1 self.on_off_value.setText(str(num_on) + '\\' + str(num_off)) except ValueError: err_line1 = 'Missing data, result is empty array!' err_line2 = '\n Please check snap file.' self.error_popup.showMessage(err_line1 + err_line2) except AttributeError: pass
class SelectPlayersWindow(QDialog): def __init__(self, parent=None): super(SelectPlayersWindow, self).__init__(parent) self.parent = parent self.setModal(True) self.setWindowTitle("Torna résztvevők") self.resize(520, 600) self.layout = QVBoxLayout() self.setLayout(self.layout) self.read_config() self.create_torna_selection() self.nevek_layout = QHBoxLayout() self.layout.addLayout(self.nevek_layout) self.show_saved_players() self.show_torna_players() self.gomb_nev_layout = QVBoxLayout() self.nevek_layout.addLayout(self.gomb_nev_layout) self.show_current_players() self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonbox.clicked.connect(self.buttonbox_click) self.layout.addWidget(self.buttonbox) def create_torna_selection(self): self.tournaments = QComboBox() self.tournaments.setModelColumn(0) self.tournaments.currentIndexChanged.connect(self.torna_valasztas) self.layout.addWidget(self.tournaments) self.load_torna() def load_torna(self): torna = QSqlQueryModel() query = QSqlQuery("select * from torna_settings where aktiv=2") torna.setQuery(query) if torna.record(0).value(0): for i in range(torna.rowCount()): self.tournaments.addItem( torna.record(i).value(1), torna.record(i).value(0)) # a value(0) a torna_id else: print("Nincs aktív torna") def show_saved_players(self): self.saved_players = QListWidget() self.saved_players.setFixedHeight(500) self.saved_players.setFixedWidth(150) self.saved_players.setSortingEnabled(True) self.saved_players.itemDoubleClicked.connect(self.add_resztvevo) self.load_saved_players() self.nevek_layout.addWidget(self.saved_players) def show_torna_players(self): self.torna_players = QListWidget() self.torna_players.setFixedHeight(500) self.torna_players.setFixedWidth(150) self.torna_players.setSortingEnabled(True) self.torna_players.itemDoubleClicked.connect(self.add_resztvevo) self.load_torna_players() self.nevek_layout.addWidget(self.torna_players) def load_saved_players(self): players = QSqlQueryModel() players_query = QSqlQuery("select * from players where aktiv=1") players.setQuery(players_query) self.saved_players.clear() for i in range(players.rowCount()): item = QListWidgetItem(players.record(i).value(1)) item.setData(Qt.UserRole, players.record(i).value(0)) self.saved_players.addItem(item) def load_torna_players(self): players = QSqlQueryModel() players_query = QSqlQuery( "select * from torna_resztvevok where 1 group by player_id, player_name" ) players.setQuery(players_query) self.torna_players.clear() for i in range(players.rowCount()): item = QListWidgetItem(players.record(i).value(1)) item.setData(Qt.UserRole, players.record(i).value(0)) self.torna_players.addItem(item) def add_resztvevo(self, item): new_item = QListWidgetItem(item) new_item.setData(Qt.UserRole, item.data(Qt.UserRole)) self.current_players.addItem(new_item) query = QSqlQuery( f"insert into torna_resztvevok (player_id, player_name, torna_id) values ({new_item.data(Qt.UserRole)}, '{new_item.text()}', {self.torna_id})" ) query.exec_() def show_current_players(self): query = QSqlQuery("select max(player_id) from torna_resztvevok") query.exec_() while query.next(): self.first_new_id = int(query.value(0)) + 1 print(self.first_new_id) self.add_new = QPushButton("Új") self.add_new.clicked.connect(self.uj_ember) self.current_players = QListWidget() self.current_players.setFixedHeight(470) self.current_players.setFixedWidth(150) self.current_players.setSortingEnabled(True) self.gomb_nev_layout.addWidget(self.add_new) self.current_players.itemDoubleClicked.connect(self.remove_resztvevo) self.gomb_nev_layout.addWidget(self.current_players) def uj_ember(self): ujember, ok = QInputDialog.getText( self, "Új versenyző", '<html style="font-size: 15px;">Írd be a versenyző nevét!</html>') if ok and len(ujember): item = QListWidgetItem(ujember) item.setData(Qt.UserRole, self.first_new_id) self.current_players.addItem(item) self.first_new_id += 1 query = QSqlQuery( f"insert into torna_resztvevok (player_id, player_name, torna_id) values ({item.data(Qt.UserRole)}, '{item.text()}', {self.torna_id})" ) query.exec_() def remove_resztvevo(self, item): self.current_players.takeItem( self.current_players.row(self.current_players.selectedItems()[0])) # print(item.data(Qt.UserRole), item.text()) query = QSqlQuery( f"delete from torna_resztvevok where player_id={item.data(Qt.UserRole)} and torna_id={self.torna_id}" ) query.exec_() def torna_valasztas(self, i): self.torna_id = self.tournaments.itemData(i) players = QSqlQueryModel() players_query = QSqlQuery( f"select * from torna_resztvevok where torna_id={self.torna_id}") players.setQuery(players_query) self.current_players.clear() for i in range(players.rowCount()): item = QListWidgetItem(players.record(i).value(1)) item.setData(Qt.UserRole, players.record(i).value(0)) self.current_players.addItem(item) def buttonbox_click(self, b): if b.text() == "OK": self.accept() elif b.text() == "Cancel": self.reject() def accept(self): # for i in range(self.current_players.count()): # item = self.current_players.item(i) # print(self.torna_id, item.data(Qt.UserRole), item.text()) # itt vannak a beszúrandó adatok super().accept() # INSERT INTO `torna_resztvevok` (`player_id`, `player_name`, `torna_id`) # VALUES ('1111', 'teszt_user2', '8892') ON DUPLICATE KEY UPDATE player_name='teszt_user2'; def read_config(self): if os.path.exists('config.ini'): # Van config.ini, ki kell értékelni config.read('config.ini') self.station_id = config['DEFAULT'].get('station id') self.secret = config['DEFAULT'].get('secret key') # todo módosítani kell a torna_match táblát, hogy tartalmazza a tabla mellett a hozzá tartozó secret-et is else: # Nincs config.ini, alapértékekkel inicializálni msg = QMessageBox(self) msg.setStyleSheet("fonz-size: 20px") msg.setWindowTitle("Hiányzó beállítás file!") msg.setText( '<html style="font-size: 14px; color: red">Nem tudtam beolvasni a konfigurációt!<br></html>' + '<html style="font-size: 16px">Kérem módosítsa a beállításokat!</html>' ) msg.exec_() sys.exit(1)
class DatasheetView(QMainWindow): def __init__(self, pdfPath=None, openPages=[1]): super().__init__() if pdfPath: self.myPdfContext = PDFContext(pdfPath, openPages) # store diretory for debugging purposes self.svgDirectory = self.myPdfContext.directory # window dimensions self.top = 300 self.left = 800 self.width = 860 self.height = 980 self.setGeometry(self.left, self.top, self.width, self.height) # window title self.setWindowTitle("BetterSheets") # sets up main layout -- splitters self.initUILayout() self.initUIToolbar() self.initToC() # self.initPdfViewer() # must be called after initUI to ensure PDFContext object exists self.show() print(self.mainDisplay.getVisibleChild()) def initUILayout(self): # set left-side, Dynamic View self.dynamicViewDisplay = QLabel() self.vBoxA = QVBoxLayout() self.vBoxA.addWidget(self.dynamicViewDisplay) self.groupA = QGroupBox() self.groupA.setTitle("Dynamic Veiw") self.groupA.setLayout(self.vBoxA) # set left-side, Static View self.staticViewDisplay = QLabel() self.vBoxB = QVBoxLayout() self.vBoxB.addWidget(self.staticViewDisplay) self.groupB = QGroupBox() self.groupB.setTitle("Static View") self.groupB.setLayout(self.vBoxB) # add Dynamic and Static Views to resizeable left-side Splitter self.altViewSplit = QSplitter(Qt.Vertical) self.altViewSplit.addWidget(self.groupA) self.altViewSplit.addWidget(self.groupB) # set up Tools View section self.toolsTabView = QTabWidget() self.toolsTabView.setTabsClosable(True) self.toolsTabView.setMovable(True) self.toolsTabView.setDocumentMode(True) # self.toolsTabView.setTabBarAutoHide(True) # add attribute for storing page notes self.notesDB = [] self.notesDisplay = QListWidget(self) self.notesDisplay.setMaximumHeight(200) # add ToC to Tools View self.ToCListView = QListWidget() self.toolsTabView.addTab(self.ToCListView, "Table of Contents") # add notes list to tools view self.toolsTabView.addTab(self.notesDisplay, "Notes") # add tools view to the left-side splitter self.altViewSplit.addWidget(self.toolsTabView) # set up main viewport self.mainDisplay = QDatasheetPageDisplayWidget(self.myPdfContext) self.mainDisplay.renderPages(1, 4) self.mainScroller = QScrollArea(self) self.mainScroller.setWidget(self.mainDisplay) self.mainScroller.setWidgetResizable(True) self.mainScroller.setBackgroundRole(QtGui.QPalette.Dark) self.mainScroller.setFixedHeight(800) print(self.mainScroller.viewport().childrenRect()) # set up document tools self.hBoxDocTools = QHBoxLayout() self.searchLabel = QLabel("Search: ") self.searchBox = QLineEdit() self.searchBox.setPlaceholderText("Search") # self. self.vBoxMain = QVBoxLayout() self.vBoxMain.addWidget(self.mainScroller) self.notesArea = QLineEdit() self.notesArea.setPlaceholderText("Add a note about this page...") self.notesArea.returnPressed.connect(self.onAddNote) self.vBoxMain.addWidget(self.notesArea) self.mainViewGroup = QGroupBox() self.mainViewGroup.setTitle("Main View") self.mainViewGroup.setLayout(self.vBoxMain) # join both sides together self.leftRightSplit = QSplitter(Qt.Horizontal) self.leftRightSplit.addWidget(self.altViewSplit) self.leftRightSplit.addWidget(self.mainViewGroup) self.setCentralWidget(self.leftRightSplit) def initUIToolbar(self): mainMenu = self.menuBar( ) # get the menu bar already in use by this QMainWindow subclass fileMenu = mainMenu.addMenu("File") editMenu = mainMenu.addMenu("Edit") LayoutMenu = mainMenu.addMenu("Layout") AboutMenu = mainMenu.addMenu("About") saveAction = fileMenu.addAction("Save") quitAction = fileMenu.addAction("Exit Bettersheets") quitAction.triggered.connect(self.quitApp) copyAction = editMenu.addAction("Copy") resetAction = LayoutMenu.addAction("Reset Default Layout") self.toolBar = self.addToolBar("Tools") self.toolBar.addAction(saveAction) self.toolBar.addAction(copyAction) def contextMenuEvent(self, event): # return super().contextMenuEvent(event) contextMenu = QMenu() selectAction = contextMenu.addAction("Select Area") extractAction = contextMenu.addAction("Extract Content") openAction = contextMenu.addAction("Open PDF") closeAction = contextMenu.addAction("Close PDF") quitAction = contextMenu.addAction("Quit") triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos())) if triggered_action == quitAction: self.quitApp() def quitApp(self): self.close() def onAddNote(self): print("note added") text = self.notesArea.text() if text: self.notesDB.append(text) self.notesDisplay.clear() self.notesDisplay.addItems(self.notesDB) self.notesArea.clear() def initPdfViewer(self, openPages: int): pass def initToC(self): # get table of contents ToC = self.myPdfContext.getToC() ToC_headings_list = [x[1] for x in ToC] self.ToCListView.clear() self.ToCListView.addItems(ToC_headings_list)
class QtBookInfo(QtWidgets.QWidget, Ui_BookInfo): def __init__(self, owner): super(self.__class__, self).__init__() Ui_BookInfo.__init__(self) self.setupUi(self) self.owner = weakref.ref(owner) self.loadingForm = QtLoading(self) self.bookId = "" self.url = "" self.path = "" self.bookName = "" self.lastEpsId = -1 self.msgForm = QtBubbleLabel(self) self.picture.installEventFilter(self) self.title.setGeometry(QRect(328, 240, 329, 27 * 4)) self.title.setWordWrap(True) self.title.setAlignment(Qt.AlignTop) self.title.setContextMenuPolicy(Qt.CustomContextMenu) self.title.customContextMenuRequested.connect(self.CopyTitle) # self.autor.setContextMenuPolicy(Qt.CustomContextMenu) # self.autor.customContextMenuRequested.connect(self.OpenAutor) layouy = self.horizontalLayout_4 self.autorList = QtCategoryList(self) layouy.addWidget(QLabel("作者:")) layouy.addWidget(self.autorList) self.autorList.itemClicked.connect(self.ClickTagsItem) self.description.setContextMenuPolicy(Qt.CustomContextMenu) self.description.customContextMenuRequested.connect( self.CopyDescription) self.description.setGeometry(QRect(328, 240, 329, 27 * 4)) self.description.setWordWrap(True) self.description.setAlignment(Qt.AlignTop) # self.categories.setGeometry(QRect(328, 240, 329, 27 * 4)) # self.categories.setWordWrap(True) # self.categories.setAlignment(Qt.AlignTop) layouy = self.horizontalLayout_6 self.categoriesList = QtCategoryList(self) layouy.addWidget(QLabel("分类:")) layouy.addWidget(self.categoriesList) self.categoriesList.itemClicked.connect(self.ClickCategoriesItem) # self.tags.setGeometry(QRect(328, 240, 329, 27 * 4)) # self.tags.setWordWrap(True) # self.tags.setAlignment(Qt.AlignTop) layouy = self.horizontalLayout_7 self.tagsList = QtCategoryList(self) layouy.addWidget(QLabel("Tags:")) layouy.addWidget(self.tagsList) self.tagsList.itemClicked.connect(self.ClickTagsItem) self.epsListWidget = QListWidget(self) self.epsListWidget.setFlow(self.epsListWidget.LeftToRight) self.epsListWidget.setWrapping(True) self.epsListWidget.setFrameShape(self.epsListWidget.NoFrame) self.epsListWidget.setResizeMode(self.epsListWidget.Adjust) self.epsLayout.addWidget(self.epsListWidget) self.listWidget = QtBookList(self, self.__class__.__name__) self.listWidget.InitUser(self.LoadNextPage) self.listWidget.doubleClicked.connect(self.OpenCommentInfo) self.childrenListWidget = QtBookList(None, self.__class__.__name__) self.childrenListWidget.InitUser(self.LoadChildrenNextPage) self.childrenWidget = QtWidgets.QWidget() layout = QHBoxLayout(self.childrenWidget) label = QLabel() label.setMinimumWidth(100) layout.addWidget(label) layout3 = QVBoxLayout() layout2 = QHBoxLayout() self.commentLine2 = QLineEdit() self.commentButton2 = QPushButton("回复") self.commentButton2.clicked.connect(self.SendCommentChildren) layout2.addWidget(self.commentLine2) layout2.addWidget(self.commentButton2) layout3.addLayout(layout2) layout3.addWidget(self.childrenListWidget) layout.addLayout(layout3) self.commentLayout.addWidget(self.listWidget) layout = QHBoxLayout() self.commentLine = QLineEdit() layout.addWidget(self.commentLine) self.commentButton = QPushButton("发送评论") layout.addWidget(self.commentButton) self.commentLayout.addLayout(layout, 1, 0) self.commentButton.clicked.connect(self.SendComment) # self.stackedWidget.addWidget(self.qtReadImg) self.epsListWidget.clicked.connect(self.OpenReadImg) self.closeFlag = self.__class__.__name__ + "-close" # 切换book时,取消加载 def closeEvent(self, a0: QtGui.QCloseEvent) -> None: if self.stackedWidget.currentIndex() == 1: self.stackedWidget.setCurrentIndex(0) self.owner().qtReadImg.AddHistory() self.LoadHistory() a0.ignore() else: a0.accept() def CopyTitle(self): clipboard = QApplication.clipboard() clipboard.setText(self.title.text()) self.msgForm.ShowMsg("复制标题") return # def OpenAutor(self): # text = self.autor.text() # self.owner().userForm.listWidget.setCurrentRow(0) # self.owner().searchForm.searchEdit.setText(text) # self.owner().searchForm.Search() # return def Clear(self): self.stackedWidget.setCurrentIndex(0) self.owner().qtTask.CancelTasks(self.closeFlag) self.epsListWidget.clear() self.ClearCommnetList() def CopyDescription(self): clipboard = QApplication.clipboard() clipboard.setText(self.description.text()) self.msgForm.ShowMsg("复制描述") return def OpenBook(self, bookId): self.bookId = bookId self.setWindowTitle(self.bookId) # if self.bookId in self.owner().downloadForm.downloadDict: # self.download.setEnabled(False) # else: # self.download.setEnabled(True) self.Clear() self.show() self.loadingForm.show() self.owner().qtTask.AddHttpTask( lambda x: BookMgr().AddBookById(bookId, x), self.OpenBookBack) def close(self): super(self.__class__, self).close() def OpenBookBack(self, msg): self.loadingForm.close() self.listWidget.UpdatePage(1, 1) self.childrenListWidget.UpdatePage(1, 1) self.childrenListWidget.UpdateState() self.listWidget.UpdateState() self.categoriesList.clear() self.tagsList.clear() self.autorList.clear() info = BookMgr().books.get(self.bookId) if msg == Status.Ok and info: # self.autor.setText(info.author) self.autorList.AddItem(info.author) self.title.setText(info.title) self.bookName = info.title self.description.setText(info.description) self.isFinished.setText("完本" if info.finished else "未完本") for name in info.categories: self.categoriesList.AddItem(name) # self.categories.setText(','.join(info.categories)) # self.tags.setText(','.join(info.tags)) for name in info.tags: self.tagsList.AddItem(name) self.likes.setText(str(info.totalLikes)) self.views.setText(str(info.totalViews)) if info.isFavourite: self.favorites.setEnabled(False) else: self.favorites.setEnabled(True) self.picture.setText("图片加载中...") fileServer = info.thumb.get("fileServer") path = info.thumb.get("path") name = info.thumb.get("originalName") self.url = fileServer self.path = path timeArray, day = ToolUtil.GetDateStr(info.updated_at) self.updateTick.setText(str(day) + "天前更新") if config.IsLoadingPicture: self.owner().qtTask.AddDownloadTask( fileServer, path, completeCallBack=self.UpdatePicture, cleanFlag=self.closeFlag) self.owner().qtTask.AddHttpTask(lambda x: Server().Send( req.GetComments(self.bookId), bakParam=x), self.GetCommnetBack, cleanFlag=self.closeFlag) self.owner().qtTask.AddHttpTask( lambda x: BookMgr().AddBookEpsInfo(self.bookId, x), self.GetEpsBack, cleanFlag=self.closeFlag) self.startRead.setEnabled(False) else: # QtWidgets.QMessageBox.information(self, '加载失败', msg, QtWidgets.QMessageBox.Yes) self.msgForm.ShowError(msg) self.hide() return def UpdatePicture(self, data, status): if status == Status.Ok: pic = QtGui.QPixmap() pic.loadFromData(data) pic.scaled(self.picture.size(), QtCore.Qt.KeepAspectRatio) self.picture.setPixmap(pic) # self.picture.setScaledContents(True) self.update() else: self.picture.setText("图片加载失败") return # 加载评论 def GetCommnetBack(self, data): try: self.loadingForm.close() self.listWidget.UpdateState() msg = json.loads(data) if msg.get("code") == 200: comments = msg.get("data", {}).get("comments", {}) topComments = msg.get("data", {}).get("topComments", []) page = int(comments.get("page", 1)) pages = int(comments.get("pages", 1)) limit = int(comments.get("limit", 1)) self.listWidget.UpdatePage(page, pages) total = comments.get("total", 0) self.tabWidget.setTabText(1, "评论({})".format(str(total))) if page == 1: for index, info in enumerate(topComments): floor = "置顶" content = info.get("content") name = info.get("_user", {}).get("name") avatar = info.get("_user", {}).get("avatar", {}) createdTime = info.get("created_at") commentsCount = info.get("commentsCount") commnetId = info.get('_id') likesCount = info.get("likesCount") self.listWidget.AddUserItem(commnetId, commentsCount, likesCount, content, name, createdTime, floor, avatar.get("fileServer"), avatar.get("path"), avatar.get("originalName")) for index, info in enumerate(comments.get("docs")): floor = total - ((page - 1) * limit + index) content = info.get("content") name = info.get("_user", {}).get("name") avatar = info.get("_user", {}).get("avatar", {}) createdTime = info.get("created_at") commentsCount = info.get("commentsCount") commnetId = info.get('_id') likesCount = info.get("likesCount") self.listWidget.AddUserItem(commnetId, commentsCount, likesCount, content, name, createdTime, floor, avatar.get("fileServer"), avatar.get("path"), avatar.get("originalName")) return except Exception as es: Log.Error(es) def GetEpsBack(self, st): if st == Status.Ok: self.UpdateEpsData() self.lastEpsId = -1 self.LoadHistory() return return def UpdateEpsData(self): self.epsListWidget.clear() info = BookMgr().books.get(self.bookId) if not info: return self.startRead.setEnabled(True) downloadIds = self.owner().downloadForm.GetDownloadCompleteEpsId( self.bookId) for index, epsInfo in enumerate(info.eps): label = QLabel(epsInfo.title) label.setContentsMargins(20, 10, 20, 10) item = QListWidgetItem(self.epsListWidget) if index in downloadIds: item.setBackground(QColor(18, 161, 130)) else: item.setBackground(QColor(0, 0, 0, 0)) item.setSizeHint(label.sizeHint()) self.epsListWidget.setItemWidget(item, label) self.tabWidget.setTabText(0, "章节({})".format(str(len(info.eps)))) return def AddDownload(self): self.owner().epsInfoForm.OpenEpsInfo(self.bookId) # if self.owner().downloadForm.AddDownload(self.bookId): # QtBubbleLabel.ShowMsgEx(self, "添加下载成功") # else: # QtBubbleLabel.ShowMsgEx(self, "已在下载列表") # self.download.setEnabled(False) def AddFavority(self): User().AddAndDelFavorites(self.bookId) QtBubbleLabel.ShowMsgEx(self, "添加收藏成功") self.favorites.setEnabled(False) def LoadNextPage(self): self.loadingForm.show() self.owner().qtTask.AddHttpTask(lambda x: Server( ).Send(req.GetComments(self.bookId, self.listWidget.page + 1), bakParam=x), self.GetCommnetBack, cleanFlag=self.closeFlag) return def OpenReadImg(self, modelIndex): index = modelIndex.row() self.OpenReadIndex(index) def OpenReadIndex(self, index): item = self.epsListWidget.item(index) if not item: return widget = self.epsListWidget.itemWidget(item) if not widget: return name = widget.text() self.hide() self.owner().qtReadImg.OpenPage(self.bookId, index, name) # self.stackedWidget.setCurrentIndex(1) def StartRead(self): if self.lastEpsId >= 0: self.OpenReadIndex(self.lastEpsId) else: self.OpenReadIndex(0) return def LoadHistory(self): info = self.owner().historyForm.GetHistory(self.bookId) if not info: self.startRead.setText("观看第{}章".format(str(1))) return if self.lastEpsId == info.epsId: self.startRead.setText("观看第{}章".format(str(self.lastEpsId + 1))) return if self.lastEpsId >= 0: item = self.epsListWidget.item(self.lastEpsId) if item: downloadIds = self.owner( ).downloadForm.GetDownloadCompleteEpsId(self.bookId) if self.lastEpsId in downloadIds: item.setBackground(QColor(18, 161, 130)) else: item.setBackground(QColor(0, 0, 0, 0)) item = self.epsListWidget.item(info.epsId) if not item: return item.setBackground(QColor(238, 162, 164)) self.epsListWidget.update() self.lastEpsId = info.epsId self.startRead.setText("观看第{}章".format(str(self.lastEpsId + 1))) def ClickCategoriesItem(self, item): text = item.text() self.owner().userForm.listWidget.setCurrentRow(1) self.owner().searchForm.searchEdit.setText("") self.owner().searchForm.OpenSearchCategories(text) return def ClickTagsItem(self, item): text = item.text() self.owner().userForm.listWidget.setCurrentRow(1) self.owner().searchForm.searchEdit.setText(text) self.owner().searchForm.Search() return def SendComment(self): data = self.commentLine.text() if not data: return self.commentLine.setText("") self.loadingForm.show() self.owner().qtTask.AddHttpTask(lambda x: Server().Send( req.SendComment(self.bookId, data), bakParam=x), callBack=self.SendCommentBack) def SendCommentBack(self, msg): try: data = json.loads(msg) if data.get("code") == 200: self.ClearCommnetList() self.owner().qtTask.AddHttpTask(lambda x: Server().Send( req.GetComments(self.bookId), bakParam=x), self.GetCommnetBack, cleanFlag=self.closeFlag) else: self.loadingForm.close() QtBubbleLabel.ShowErrorEx(self, data.get("message", "错误")) self.commentLine.setText("") except Exception as es: self.loadingForm.close() Log.Error(es) def OpenCommentInfo(self, modelIndex): index = modelIndex.row() item = self.listWidget.item(index) if not item: return widget = self.listWidget.itemWidget(item) if not widget: return self.childrenListWidget.clear() self.childrenListWidget.UpdatePage(1, 1) self.childrenListWidget.UpdateState() if self.childrenListWidget.parentId == index: # self.childrenWidget.hide() self.childrenWidget.setParent(None) widget.gridLayout.removeWidget(self.childrenWidget) self.childrenListWidget.parentId = -1 item.setSizeHint(widget.sizeHint()) return if self.childrenListWidget.parentId >= 0: item2 = self.listWidget.item(self.childrenListWidget.parentId) widget2 = self.listWidget.itemWidget(item2) self.childrenWidget.setParent(None) widget2.gridLayout.removeWidget(self.childrenWidget) self.childrenListWidget.parentId = -1 item2.setSizeHint(widget2.sizeHint()) self.loadingForm.show() self.owner().qtTask.AddHttpTask(lambda x: Server().Send( req.GetCommentsChildrenReq(widget.id), bakParam=x), self.LoadCommentInfoBack, backParam=index, cleanFlag=self.closeFlag) def LoadCommentInfoBack(self, msg, index): try: self.loadingForm.close() item = self.listWidget.item(index) if not item: return widget = self.listWidget.itemWidget(item) if not widget: return self.childrenListWidget.UpdateState() data = json.loads(msg) self.childrenListWidget.parentId = index widget.gridLayout.addWidget(self.childrenWidget, 1, 0, 1, 1) if data.get("code") == 200: comments = data.get("data", {}).get("comments", {}) page = int(comments.get("page", 1)) total = int(comments.get("total", 1)) pages = int(comments.get("pages", 1)) limit = int(comments.get("limit", 1)) self.childrenListWidget.UpdatePage(page, pages) for index, info in enumerate(comments.get("docs")): floor = total - ((page - 1) * limit + index) content = info.get("content") name = info.get("_user", {}).get("name") avatar = info.get("_user", {}).get("avatar", {}) createdTime = info.get("created_at") commentsCount = info.get("commentsCount") likesCount = info.get("likesCount") commnetId = info.get('_id') self.childrenListWidget.AddUserItem( commnetId, commentsCount, likesCount, content, name, createdTime, floor, avatar.get("fileServer"), avatar.get("path"), avatar.get("originalName")) pass self.listWidget.scrollToItem( item, self.listWidget.ScrollHint.PositionAtTop) size = self.listWidget.size() item.setSizeHint(size) except Exception as es: Log.Error(es) def SendCommentChildren(self): data = self.commentLine2.text() if not data: return index = self.childrenListWidget.parentId item = self.listWidget.item(index) if not item: return widget = self.listWidget.itemWidget(item) if not widget: return self.commentLine2.setText("") commentId = widget.id self.loadingForm.show() self.childrenListWidget.clear() self.owner().qtTask.AddHttpTask(lambda x: Server().Send( req.SendCommentChildrenReq(commentId, data), bakParam=x), callBack=self.SendCommentChildrenBack, backParam=index) def SendCommentChildrenBack(self, msg, index): try: item = self.listWidget.item(index) if not item: self.loadingForm.close() return widget = self.listWidget.itemWidget(item) if not widget: self.loadingForm.close() return data = json.loads(msg) if data.get("code") == 200: self.owner().qtTask.AddHttpTask(lambda x: Server().Send( req.GetCommentsChildrenReq(widget.id), bakParam=x), self.LoadCommentInfoBack, backParam=index, cleanFlag=self.closeFlag) else: self.loadingForm.close() QtBubbleLabel.ShowErrorEx(self, data.get("message", "错误")) self.commentLine.setText("") except Exception as es: self.loadingForm.close() Log.Error(es) def LoadChildrenNextPage(self): index = self.childrenListWidget.parentId item = self.listWidget.item(index) if not item: return widget = self.listWidget.itemWidget(item) if not widget: return self.loadingForm.show() self.owner().qtTask.AddHttpTask( lambda x: Server().Send(req.GetCommentsChildrenReq( widget.id, self.childrenListWidget.page + 1), bakParam=x), self.LoadCommentInfoBack, backParam=index, cleanFlag=self.closeFlag) return def ClearCommnetList(self): if self.childrenListWidget.parentId >= 0: item2 = self.listWidget.item(self.childrenListWidget.parentId) widget2 = self.listWidget.itemWidget(item2) self.childrenWidget.setParent(None) widget2.gridLayout.removeWidget(self.childrenWidget) self.childrenListWidget.parentId = -1 item2.setSizeHint(widget2.sizeHint()) self.childrenListWidget.clear() self.listWidget.clear() def eventFilter(self, obj, event): if event.type() == QEvent.MouseButtonPress: if event.button() == Qt.LeftButton: if obj.pixmap() and not obj.text(): QtImgMgr().ShowImg(obj.pixmap()) return True else: return False else: return super(self.__class__, self).eventFilter(obj, event)
class Randomizer(QWidget): """A game randomizer for selecting a random game to play from the user's collection. User can select which platforms to choose from. gamesData: Raw table data in list of dictionaries""" def __init__(self, gamesData: list, platformsData: list, genresData: list): super(Randomizer, self).__init__() self._consoleItems = platformsData self._genreItems = genresData self._gamesData = gamesData self._games = [] # For holding the games to randomize self._gameCount = 0 self._coverdir = path.join("data", "images", "covers") self.consoleLabel = QLabel("Platforms") self.consoleList = QListWidget() self.consoleList.addItems(self._consoleItems) self.consoleList.setSelectionMode(QAbstractItemView.MultiSelection) self.consoleList.setMaximumWidth(350) self.consoleList.itemClicked.connect(self._updateGameCount) self.genreLabel = QLabel("Genres") self.genreMatchExclusiveCB = QCheckBox("Match exclusive") self.genreMatchExclusiveCB.setToolTip( "Only match games which exclusively contain the selected genres.") self.genreMatchExclusiveCB.setChecked(False) self.genreMatchExclusiveCB.stateChanged.connect(self._updateGameCount) self.genreList = QListWidget() self.genreList.addItems(self._genreItems) self.genreList.setSelectionMode(QAbstractItemView.MultiSelection) self.genreList.setMaximumWidth(350) self.genreList.itemClicked.connect(self._updateGameCount) self.btnAll = QPushButton("Select All") self.btnAll.setMaximumSize(self.btnAll.sizeHint()) self.btnAll.clicked.connect(self.consoleList.selectAll) self.btnAll.clicked.connect(self.genreList.selectAll) self.btnAll.clicked.connect(self._updateGameCount) self.btnNone = QPushButton("Select None") self.btnNone.setMaximumSize(self.btnNone.sizeHint()) self.btnNone.clicked.connect(self.consoleList.clearSelection) self.btnNone.clicked.connect(self.genreList.clearSelection) self.btnNone.clicked.connect(self._updateGameCount) self._btnRnd = QPushButton("Randomize") self._btnRnd.setMaximumSize(self._btnRnd.sizeHint()) self._btnRnd.clicked.connect(self._randomize) self._lblFont = QFont() self._lblFont.setPointSize(14) self._lblFont.setBold(True) self._lblPlay = QLabel() self._lblPlay.setAlignment(Qt.AlignCenter) self._lblPlay.setFont(self._lblFont) self._lblTitle = QLabel() self._lblTitle.setAlignment(Qt.AlignCenter) self._lblTitle.setFont(self._lblFont) self._lblTitle.setWordWrap(True) # Cover image self._cover = QLabel() self._cover.setVisible(False) self._cover.setAlignment(Qt.AlignCenter) p = QPixmap(path.join(self._coverdir, "none.png")) w = self._cover.width() h = self._cover.height() self._cover.setPixmap( p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) self._hboxButtons = QHBoxLayout() self._vboxLists = QVBoxLayout() self._vboxConsoles = QVBoxLayout() self._hboxGenres = QHBoxLayout() self._vboxGenres = QVBoxLayout() self._vboxResult = QVBoxLayout() self._grid = QGridLayout() self._hboxButtons.addWidget(self.btnAll, 0) self._hboxButtons.addWidget(self.btnNone, 0) self._hboxButtons.addWidget(self._btnRnd, 0) self._vboxConsoles.addWidget(self.consoleLabel, 0) self._vboxConsoles.addWidget(self.consoleList, 1) self._hboxGenres.addWidget(self.genreLabel, 0) self._hboxGenres.addWidget(self.genreMatchExclusiveCB, 0) self._vboxGenres.addWidget(self.genreList, 1) self._vboxLists.addSpacing(10) self._vboxLists.addLayout(self._vboxConsoles, 1) self._vboxLists.addSpacing(10) self._vboxLists.addLayout(self._hboxGenres, 0) self._vboxLists.addLayout(self._vboxGenres, 1) self._vboxResult.addStretch(3) self._vboxResult.addWidget(self._lblPlay, 0) self._vboxResult.addWidget(self._lblTitle, 0) self._vboxResult.addSpacing(50) self._vboxResult.addWidget(self._cover, 0) self._vboxResult.addStretch(3) self._grid.setMargin(0) self._grid.setSpacing(0) self._grid.addLayout(self._vboxLists, 0, 0) self._grid.addLayout(self._hboxButtons, 1, 0) self._grid.addLayout(self._vboxResult, 0, 1, 1, -1) self.widget = QWidget() self.widget.setLayout(self._grid) def _getSelectedItems(self) -> tuple: return [x.text() for x in self.consoleList.selectedItems() ], [x.text() for x in self.genreList.selectedItems()] def _randomize(self): platforms, genres = self._getSelectedItems() if len(self._games) > 0 and (len(platforms) > 0 or len(genres) > 0): choice = randint(0, len(self._games) - 1) self._lblPlay.setText("You will play:") self._lblTitle.setText( f"{self._games[choice]['name']}" if len(platforms) == 1 else f"{self._games[choice]['name']} [{self._games[choice]['platform']}]" ) # Cover image cover = str(self._games[choice]['id']) + ".jpg" if path.exists(path.join(self._coverdir, cover)): # Update cover image if the game has one pixmap = path.join(self._coverdir, cover) self._cover.setVisible(True) else: pixmap = path.join(self._coverdir, "none.png") self._cover.setVisible(False) p = QPixmap(pixmap) w = self._cover.width() h = self._cover.height() self._cover.setPixmap( p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) elif len(self._games) == 0 and (len(platforms) > 0 or len(genres) > 0): self._lblPlay.setText("") self._lblTitle.setText("No games found with those criteria.") self._cover.setVisible(False) else: self._lblPlay.setText("") self._lblTitle.setText("Select at least one console or genre...") self._cover.setVisible(False) def _updateGameCount(self): platforms, genres = self._getSelectedItems() self._gameCount = 0 self._games = [] if len(platforms) > 0 or len(genres) > 0: for row in self._gamesData: if len(platforms) > 0 and len(genres) > 0: if row["platform"] in platforms: if self.genreMatchExclusiveCB.isChecked(): count = 0 for genre in row["genre"].split(", "): if genre in genres: count += 1 else: # Not exclusive count = 0 break if count == len(genres): self._gameCount += 1 self._games.append(row) else: for genre in row["genre"].split(", "): if genre in genres: self._gameCount += 1 self._games.append(row) break # We only need to match with one genre elif len(platforms) > 0 and len(genres) == 0: if row["platform"] in platforms: self._gameCount += 1 self._games.append(row) elif len(platforms) == 0 and len(genres) > 0: if self.genreMatchExclusiveCB.isChecked(): count = 0 for genre in row["genre"].split(", "): if genre in genres: count += 1 else: # Not exclusive count = 0 break if count == len(genres): self._gameCount += 1 self._games.append(row) else: for genre in row["genre"].split(", "): if genre in genres: self._gameCount += 1 self._games.append(row) break # We only need to match with one genre def gameCount(self) -> int: return self._gameCount def updateLists(self, gamesData: list, platformsData: list, genresData: list): self._gamesData = gamesData self._consoleItems = platformsData self._genreItems = genresData self.consoleList.clear() self.genreList.clear() self.consoleList.addItems(self._consoleItems) self.genreList.addItems(self._genreItems)