def save_property(self, table: QTableWidget, stackwidget: QStackedWidget, listwidget: QListWidget, keyword: str = '') -> None: """ Saves the currently selected Property template to the config file. """ # Set None Item to prevent loss of the currently edited item: # The current item is closed and thus saved. table.setCurrentItem(None) selected_template_text = listwidget.currentIndex().data() table_data = [] ncolumns = table.rowCount() for rownum in range(ncolumns): try: # only one column! value = table.cellWidget(rownum, 0).getText() except AttributeError: value = '' if value: table_data.append(value) # make sure to have always a blank item first: table_data.insert(0, '') if keyword: # save as dictionary for properties to have "_cif_key : itemlist" # for a table item as dropdown menu in the main table. table_data = [keyword, table_data] self.settings.save_template_list('property/' + selected_template_text, table_data) stackwidget.setCurrentIndex(0) print('saved')
class SearchReference(QDialog): def __init__(self, db, reference_class): super().__init__(flags=Qt.WindowMaximizeButtonHint | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint) # Object variables self.db = db self.reference_class = reference_class self.result_value = "" # Widgets self.grid = QGridLayout(self) self.search_line = QLineEdit(self) self.search_button = QPushButton("Search", self) self.result_list = QListWidget() self.apply_button = QPushButton("Apply", self) # Initialization self._configWidgets() def _configWidgets(self): self.setWindowIcon(QIcon("logo.png")) # Binding self.apply_button.clicked.connect(self.applySelection) self.result_list.itemDoubleClicked.connect(self.applySelection) self.search_line.returnPressed.connect(self.search) self.search_button.clicked.connect(self.search) # Grid layout self.grid.addWidget(self.search_line, 1, 0) self.grid.addWidget(self.search_button, 1, 1, Qt.AlignRight) self.grid.addWidget(self.result_list, 2, 0, 1, 2) self.grid.addWidget(self.apply_button, 3, 1, Qt.AlignRight) self.setLayout(self.grid) def applySelection(self): if self.result_list.currentIndex().isValid(): item = self.result_list.selectedItems()[0].data(Qt.UserRole).text self.result_value = item self.accept() def setResult(self, references): self.result_list.clear() for reference in references: item = QListWidgetItem() item.setData(Qt.UserRole, reference) item.setText("{}".format(reference.text)) self.result_list.insertItem(0, item) def search(self): search_text = self.search_line.text() result = self.db.search_references(search_text, self.reference_class) self.setResult(result)
class MapSelection(QWidget): def __init__(self, available_maps, selected_maps): super().__init__() self._available = available_maps self._selected = selected_maps self._hbox = QHBoxLayout(self) self._vbox_wrapper = QWidget() self._vbox = QVBoxLayout(self._vbox_wrapper) self._rbutton = QPushButton( icon=self.style().standardIcon(QStyle.SP_ArrowRight)) self._lbutton = QPushButton( icon=self.style().standardIcon(QStyle.SP_ArrowLeft)) self._available_list = QListWidget() self._available_list.addItems(available_maps) self._selected_list = QListWidget() self._selected_list.addItems(selected_maps) self._vbox.addWidget(self._rbutton) self._vbox.addWidget(self._lbutton) self._hbox.addWidget(self._available_list) self._hbox.addWidget(self._vbox_wrapper) self._hbox.addWidget(self._selected_list) self._add_callback = None self._remove_callback = None self._rbutton.clicked.connect(self._add_clicked) self._lbutton.clicked.connect(self._remove_clicked) def add(self, index): self._selected.append(self._available[index]) self._selected_list.addItem(self._available[index]) def _add_clicked(self): index = self._available_list.currentItem() if self._add_callback and index: self._selected.append(index.text()) self._selected_list.addItem(index.text()) self._add_callback(index.text()) def _remove_clicked(self): index = self._selected_list.currentIndex().row() if self._remove_callback and index >= 0: del self._selected[index] self._selected_list.takeItem(index) self._remove_callback(index) def on_add(self, callback): self._add_callback = callback def on_remove(self, callback): self._remove_callback = callback
class SettingsRootWidget(QWidget): def __init__(self): super().__init__() self.categories_list = QListWidget() self.current_category = "" self.init_ui() def init_ui(self): theme = ThemeLoader.loaded_theme self.setStyleSheet(theme.apply_to_stylesheet(styles.main_window_style)) self.categories_list.setFixedWidth(200) self.categories_list.setStyleSheet( theme.apply_to_stylesheet(styles.settings_categories_list_style)) self.categories_list.currentItemChanged.connect(self.category_changed) self.categories_list.setSelectionMode( QAbstractItemView.SingleSelection) settings = AppStorage.get_settings() first_settings = settings.get_settings(settings.get_categories()[0]) self.current_category = settings.get_categories()[0] for category in settings.get_categories(): item = QListWidgetItem(category.display_name) self.categories_list.addItem(item) self.settings_container = SettingsContainerWidget(first_settings) self.settings_container.setFixedWidth(400) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setAlignment(Qt.AlignLeft) layout.addWidget(self.categories_list) layout.addWidget(self.settings_container) self.setLayout(layout) def category_changed(self, _, previous): if previous: layout = self.layout() layout.removeWidget(self.settings_container) self.settings_container.deleteLater() self.settings_container = None settings = AppStorage.get_settings() self.current_category = settings.get_categories()[ self.categories_list.currentIndex().row()] self.settings_container = SettingsContainerWidget( settings.get_settings(self.current_category)) layout.addWidget(self.settings_container)
class ViewJWidget(QDockWidget): ITEM_COLOR_OK = QBrush(QColor(255, 255, 255)) ITEM_COLOR_NG = QBrush(QColor(255, 255, 0)) def __init__(self, parent): super(ViewJWidget, self).__init__('View J List', parent) self.p = parent self.viewListWidget = QListWidget() self.viewlistLayout = QVBoxLayout() self.viewlistLayout.setContentsMargins(0, 0, 0, 0) self.viewlistLayout.addWidget(self.viewListWidget) self.viewWidgetContainer = QWidget() self.viewWidgetContainer.setLayout(self.viewlistLayout) self.setObjectName('View') self.setWidget(self.viewWidgetContainer) self.setFeatures(QDockWidget.DockWidgetFloatable) def itemClicked_connect(self, f): self.viewListWidget.itemClicked.connect(f) def count(self): return self.viewListWidget.count() def get_current_idx(self): return self.viewListWidget.currentIndex().row() def set_current_idx(self, idx): self.viewListWidget.setCurrentRow(idx) def initialize(self): self.viewListWidget.clear() list_of_view_id = self.p.matching.get_list_of_view_id() for view_id in list_of_view_id: self.viewListWidget.addItem(self.item_text(view_id)) def update_text(self): list_of_view_id = self.p.matching.get_list_of_view_id() assert self.count() == len(list_of_view_id) for i in range(self.count()): self.viewListWidget.item(i).setText( self.item_text(list_of_view_id[i])) def item_text(self, view_id): view_id_i = self.p.matching.get_view_id_i() return '(ID={}, K={}, M={}) {}'.format( view_id, self.p.matching.get_keypoint_count(view_id), self.p.matching.get_match_count(view_id_i, view_id), self.p.matching.get_filename(view_id))
class recommend_result(QWidget): def __init__(self, table): super().__init__() self.db = DBModel() self.table = table self.init() def set_db(self, db): self.db = db self.detail.set_db(db, self.table) def init(self): self.keyword = '' self.result = None self.list = QListWidget() self.list.addItem("-----结果-----") self.layout = QGridLayout() self.layout.addWidget(self.list, 0, 0, 10, 8) self.setLayout(self.layout) self.list.itemClicked.connect(self.item_detail) self.detail = item_detail.item_detail() def get_data(self): System.clear_data(self) if self.db == None: print('数据库初始化失败!', System.func_name()) return list = self.db.get_all_from_table(self.table) self.result = list if len(list) == 0: print('没有数据', System.func_name()) self.list.addItem('没有数据!') return System.set_recommendlist(self.list, list, "编号", "标题", "内容") QApplication.processEvents() print('显示完成') def set_data(self, keyword): self.keyword = keyword print('开始获取内容', System.func_name()) System.clear_data(self) list = self.db.get_search_from_table(1, keyword, self.table, 0) self.result = list System.set_recommendlist(self.list, list, "编号", "标题", "内容") QApplication.processEvents() print('显示完成') def item_detail(self): print('item detail') index = self.list.currentIndex().row() if index == 0: print('非item') return else: item = self.result[index - 1] print("是item") print(item[1]) id = item[0] title = str(item[1].encode('latin-1').decode('gbk')).strip() article = str(item[2].encode('latin-1').decode('gbk')).strip() self.detail._signal.connect(self.renew_item) self.detail.set_content(str(id), title, article) self.detail.exec() def renew_item(self): self.set_data(self.keyword)
class MainWindow(QWidget): """Main window class that provides logic of the program. Allows to search concept and to show information about concepts and relations """ def __init__(self, application): super().__init__() self.application = application self.db = self.openDatabase() self._initUI() def initActions(self): """initalization of actions for main windows""" self.help_action = QAction("&Help", self) self.help_action.setShortcut("F1") self.help_action.setStatusTip('Help') self.help_action.triggered.connect(lambda: HelpDialog(self)) self.new_db_action = QAction("New DB", self) self.new_db_action.setShortcut("Ctrl+N") self.new_db_action.triggered.connect(self.openNewDB) self.delete_сoncept_action = QAction("&Delete", self) self.delete_сoncept_action.setShortcut("DEL") self.delete_сoncept_action.setStatusTip("Delete") self.delete_сoncept_action.triggered.connect(lambda: self.delete(Concept)) self.delete_subcategory_action = QAction("&Delete subcategory", self) self.delete_subcategory_action.triggered.connect(lambda: self.delete(Subcategory)) self.edit_concept_action = QAction("&Edit", self) self.edit_concept_action.setShortcut("F2") self.edit_concept_action.triggered.connect(self.editConcept) self.edit_relation_action = QAction("&Edit", self) self.edit_relation_action.setShortcut("Ctrl+F2") self.edit_relation_action.triggered.connect(self.editRelation) self.exit_action = QAction("&Exit", self) self.exit_action.setShortcut("ESC") self.exit_action.triggered.connect(self.close) self.select_relation_action = QAction("&Select relation", self) self.select_relation_action.triggered.connect(self.setRelationDescription) self.delete_relation_action = QAction("&Delete", self) self.delete_relation_action.setShortcut("Ctrl+DEL") self.delete_relation_action.triggered.connect(lambda: self.delete(Relation)) def openNewDB(self): """This method deletes setting.py file and closes current application session. This uses for creating a new instance of Main Window. """ if os.path.exists("setting.py"): os.remove("setting.py") self.application.exit(1) def _initUI(self): self.setWindowIcon(QIcon("logo.png")) self.setWindowTitle('GraphNotes') self.resize(1000, 700) self.initActions() self.add_data_button = QPushButton("Add data", self) self.search_box = QGroupBox() self._initSearchFrame(self.search_box) self.concept_list = QListWidget(self) self.relation_list = QListWidget(self) self.result_table = QTextEdit(self) self.concept_list.itemClicked.connect(self.searchRelations) self.concept_list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.concept_list.setContextMenuPolicy(Qt.CustomContextMenu) self.concept_list.customContextMenuRequested.connect(self._showConceptContextMenu) self.relation_list.setContextMenuPolicy(Qt.CustomContextMenu) self.relation_list.customContextMenuRequested.connect(self._showRelationContextMenu) self.relation_list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.relation_list.itemClicked.connect(self.setRelationDescription) self.grid = QGridLayout() self.result_table.setReadOnly(True) self.search() self._configWidgets() self._bindWidgets() self.show() def _showConceptContextMenu(self, pos): global_position = self.concept_list.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.edit_concept_action) my_menu.addAction(self.delete_сoncept_action) my_menu.addAction(self.delete_subcategory_action) my_menu.addSeparator() my_menu.addAction(self.help_action) my_menu.addAction(self.exit_action) my_menu.exec(global_position) def _initSearchFrame(self, frame): self.search_line = QLineEdit(frame) checkboxes = QGroupBox() checkboxes.setStyleSheet("border:0;") self.concept_checkbox = QCheckBox("Concept", checkboxes) self.description_checkbox = QCheckBox("Description", checkboxes) self.study_checkbox = QCheckBox("Study", checkboxes) self.search_button = QPushButton("Search", checkboxes) checkboxes_layout = QGridLayout(checkboxes) checkboxes_layout.addWidget(self.concept_checkbox, 0, 0) checkboxes_layout.addWidget(self.description_checkbox, 0, 1) checkboxes_layout.addWidget(self.study_checkbox, 0, 2) checkboxes_layout.setContentsMargins(0, 0, 0, 0) self.concept_checkbox.setChecked(True) grid = QGridLayout(frame) grid.addWidget(self.search_line, 1, 0) grid.addWidget(self.search_button, 1, 1) grid.addWidget(checkboxes, 2, 0, Qt.AlignLeft) frame.setLayout(grid) def getSearchData(self): """This method reads parameters of search line and checkboxes, and returns "Subcategory" class. None and [] uses for showing checkboxes that have been checked. """ concept = self.search_line.text() if self.concept_checkbox.isChecked() else None description = [Description(text=self.search_line.text())] if self.description_checkbox.isChecked() else [] study = self.search_line.text() if self.study_checkbox.isChecked() else None return Subcategory(subcategory=concept, description=description, study=study) def searchRelations(self): """This method triggers when the user clicked on the concept. This method selected ID of a subcategory from selected item in conceptions list and then searches and setting all information about this selected concept. """ subcategory_id = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1].id self.setConceptDescription() result = self.db.search_relation(subcategory_id) self.setResult(result, self.relation_list) def _showRelationContextMenu(self, pos): global_position = self.relation_list.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.edit_relation_action) my_menu.addAction(self.delete_relation_action) my_menu.addSeparator() my_menu.exec(global_position) def editRelation(self): """This method opens dialog for editing Relation""" if self.relation_list.currentIndex().isValid(): relation = self.relation_list.selectedItems()[0].data(Qt.UserRole)[2] dlg = EditRelationDialog(self, relation) if dlg.exec_(): relation = dlg.getValue() self.db.update_relation(relation) self.select_relation_action.trigger() def editConcept(self): """This method opens dialog for editing Concept""" if self.concept_list.currentIndex().isValid(): concept = self.concept_list.selectedItems()[0].data(Qt.UserRole)[0] subcategory = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1] dlg = EditConceptDialog(self, concept, subcategory) if dlg.exec_(): concept, subcategory = dlg.getValue() self.db.update_concept(concept) self.db.update_subcategory(subcategory) self.search() def delete(self, something): """This universal method for deleting something from the list and database. "something" parameter needs to be any of this types: Concept, Subcategory, Relation """ if something == Concept: number = 0 target_list = self.concept_list elif something == Subcategory: number = 1 target_list = self.concept_list elif something == Relation: number = 2 target_list = self.relation_list if target_list.currentIndex().isValid(): something = target_list.selectedItems()[0].data(Qt.UserRole)[number] self.db.delete(something) self.search() def setRelationDescription(self): """This method retrieves information about relation, formats and sets it in description field. """ if self.relation_list.currentIndex().isValid(): relation = self.relation_list.selectedItems()[0].data(Qt.UserRole)[2] concept1 = "{}{}".format(relation.node1.concept.name, ", {}".format(relation.node1.subcategory) if relation.node1.subcategory else "") concept2 = "{}{}".format(relation.node2.concept.name, ", {}".format(relation.node2.subcategory) if relation.node2.subcategory else "") description = relation.description study = relation.study references = relation.reference # HTML is used for a better information formating text = "<b>Relation between </b> \"{}\" <b>and</b> \"{}\"<p>".format(concept1, concept2) text += r"<b>Description:</b>" + "<br> {} <p>".format(description) text += r"<b>Study:</b> {} <p>".format(study) text += r"<b>References:</b><ol>" for ref in references: text += " <li> {} </li>".format(ref.text) text += "</ol><br>" self.result_table.setText(text) else: self.result_table.clear() def setConceptDescription(self): """This method retrieves information about concept, formats and sets it in description field. """ concept = self.concept_list.selectedItems()[0].data(Qt.UserRole)[0] subcategory = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1] description = subcategory.description # HTML is used for a better information formating text = "<b>Concept:</b> {}<p>".format(concept.name) text += "<b>Subcategory:</b> {}<p>".format(subcategory.subcategory) text += "<b>Synonyms:</b> {}<p>".format(concept.synonyms) text += "<ol>" for des in description: text += "<li> {}".format("<b>Description:</b> <br>") text += " {} <p>".format(des.text) text += "<ol>" text += "<b>References: </b>" for ref in des.reference: text += "<li>" text += "{}".format(ref.text) text += "</li>" text += "</ol>" text += "</li>" text += "</ol>" self.result_table.setText(text) def setResult(self, result, list): """This is a universal method for showing information in a relation field or in a concept field. """ list.clear() for concept, subcategory, *other in result: item = QListWidgetItem() item.setData(Qt.UserRole, (concept, subcategory, *other)) item.setText("{}{} {}".format(concept.name, "" if subcategory.subcategory == "" else ", ", subcategory.subcategory)) list.insertItem(0, item) def search(self): parameters = self.getSearchData() result = self.db.search_nodes(parameters) self.setResult([], self.relation_list) self.setResult(result, self.concept_list) self.setResult([], self.relation_list) self.setRelationDescription() def _configWidgets(self): self.grid.setAlignment(Qt.AlignTop) self.grid.setSpacing(5) self.menu_bar = QMenuBar(self) self.database_menu = self.menu_bar.addMenu("Database") self.database_menu.addAction(self.new_db_action) self.database_menu.addSeparator() self.database_menu.addAction(self.exit_action) self.concept_menu = self.menu_bar.addMenu("Concept") self.concept_menu.addAction(self.edit_concept_action) self.concept_menu.addAction(self.delete_сoncept_action) self.concept_menu.addAction(self.delete_subcategory_action) self.relation_menu = self.menu_bar.addMenu("Relation") self.relation_menu.addAction(self.edit_relation_action) self.relation_menu.addAction(self.delete_relation_action) self.help_menu = self.menu_bar.addMenu("Help") self.help_menu.addAction(self.help_action) self.grid.setMenuBar(self.menu_bar) self.concept_box = QGroupBox("Concepts") self.concept_grid = QGridLayout() self.concept_grid.setContentsMargins(0, 10, 0, 0) self.concept_grid.addWidget(self.concept_list) self.concept_box.setLayout(self.concept_grid) self.relation_box = QGroupBox("Relations") self.relation_grid = QGridLayout() self.relation_grid.setContentsMargins(0, 10, 0, 0) self.relation_grid.addWidget(self.relation_list) self.relation_box.setLayout(self.relation_grid) self.description_box = QGroupBox("Description") self.description_grid = QGridLayout() self.description_grid.setContentsMargins(0, 10, 0, 0) self.description_grid.addWidget(self.result_table) self.description_box.setLayout(self.description_grid) self.concept_splitter = QSplitter(self) self.concept_splitter.addWidget(self.concept_box) self.concept_splitter.addWidget(self.relation_box) self.description_splitter = QSplitter(self) self.description_splitter.setOrientation(Qt.Vertical) self.description_splitter.addWidget(self.concept_splitter) self.description_splitter.addWidget(self.description_box) self.grid.addWidget(self.add_data_button, 1, 0, Qt.AlignLeft) self.grid.addWidget(self.search_box, 2, 0, 1, 2) self.grid.addWidget(self.description_splitter, 5, 0, 1, 2) self.setLayout(self.grid) def _bindWidgets(self): self.add_data_button.clicked.connect(self.addData) self.search_button.clicked.connect(self.search) self.search_line.returnPressed.connect(self.search) def addData(self): dlg = NewDataDialog(self.db) dlg.exec_() self.search() def getPath(self): dialog = NewDBDialog() if dialog.exec_(): print("EXEc") path = dialog.path with open("setting.py", "w") as f: f.write("{{ 'last': r'{0}' }}".format(path)) return path else: self.close() def openDatabase(self): if os.path.exists("setting.py"): with open("setting.py") as f: setting = eval(f.read()) if "last" in setting: if os.path.exists(setting["last"]): path = setting["last"] else: path = self.getPath() else: path = self.getPath() else: path = self.getPath() if path is None: self.close() exit(0) else: return Graph(path)
class book_search_result(QWidget): def __init__(self): super().__init__() self.db = None self.init() def set_db(self,db): self.db = db self.detail.set_db(db,'booklist') def init(self): self.index = '' self.keyword = '' self.mode = '' self.list = QListWidget() self.list.addItem("-----搜索-----") self.layout = QGridLayout() self.layout.addWidget(self.list,0,0,10,8) self.setLayout(self.layout) self.list.itemClicked.connect(self.book_detail) self.detail = book_detail.book_detail() def show_data(self,index,keyword,mode): self.index = index self.keyword = keyword self.mode = mode if len(keyword) == 0: print('没有关键词, 默认搜索全部') result = self.db.get_all_from_table('booklist') else: print("搜索关键词: ", keyword) result = self.db.get_search_from_table(index, keyword, 'booklist', mode) self.clear_data() print("开始显示...") if len(result) == 0: print('没有数据!') self.list.addItem("没有数据!") return self.numlist = System.set_book_list(self.list,result) QApplication.processEvents() print('显示完成') def clear_data(self): System.clear_data(self) def book_detail(self): print('book detail',System.func_name()) try: row = self.list.currentIndex().row() if row == 0: print("非item") return id = self.numlist[row-1] print("获取ID:",id) if System.is_item(id) == False: return self.detail._signal.connect(self.renew_item) self.detail.set_content(id) self.detail.exec() except Exception as e: print(e) def renew_item(self): self.show_data(self.index,self.keyword,self.mode) print('已刷新')
class Ui_Form(object): def setupUi(self, Form): self.form = Form self.O_answer = {} self.A_answer = {} self.file_list = os.listdir("Images") with open("count") as f: self.num = int(f.read()) self.add_a = True self.add_o = False self.A_extra = {} self.O_extra = {} f = open('Attribute', encoding='utf-8-sig') self.A_dict = {} for line in f.readlines(): temp = line[:-1].split(':') self.A_dict[temp[0]] = temp[1].split(',') print(self.A_dict) f.close() f = open('Object', encoding='utf-8-sig') self.O_dict = {} for line in f.readlines(): temp = line[:-1].split(':') self.O_dict[temp[0]] = temp[1].split(',') f.close() print(self.O_dict) Form.setObjectName("Form") Form.resize(1179, 803) self.label_16 = QtWidgets.QLabel(Form) self.label_16.setGeometry(QtCore.QRect(30, 40, 441, 331)) pixmap = QPixmap("./Images/" + self.file_list[self.num]) self.label_16.setPixmap(pixmap) self.label_16.setScaledContents(True) self.label_17 = QtWidgets.QLabel(Form) self.label_17.setGeometry(QtCore.QRect(610, 720, 111, 31)) pixmap = QPixmap("logo_iair.png") self.label_17.setPixmap(pixmap) self.label_17.setScaledContents(True) self.label_18 = QtWidgets.QLabel(Form) self.label_18.setGeometry(QtCore.QRect(400, 720, 201, 31)) pixmap = QPixmap("xjtu_logo.png") self.label_18.setPixmap(pixmap) self.label_18.setScaledContents(True) self.groupBox = QtWidgets.QGroupBox(Form) self.groupBox.setGeometry(QtCore.QRect(490, 10, 351, 411)) font = QtGui.QFont() font.setPointSize(18) self.groupBox.setFont(font) self.groupBox.setObjectName("groupBox") self.A_comboBox_list = [] self.A_label_list = [] with open('QListWidgetQSS.qss', 'r') as f: # 导入QListWidget的qss样式 self.list_style = f.read() font = QtGui.QFont() font.setPointSize(10) self.left_widget = QListWidget(self.groupBox) # 左侧选项列表 self.left_widget.setGeometry(QtCore.QRect(40, 40, 181, 360)) self.left_widget.setStyleSheet(self.list_style) self.right_widget = QStackedWidget(self.groupBox) self.right_widget.setGeometry(QtCore.QRect(190, 40, 181, 360)) with open('oQListWigetQSS.qss', 'r') as f: # 导入QListWidget的qss样式 self.olist_style = f.read() self.groupBox_5 = QtWidgets.QGroupBox(Form) self.groupBox_5.setGeometry(QtCore.QRect(850, 10, 291, 361)) font = QtGui.QFont() font.setPointSize(10) self.oleft_widget = QListWidget(self.groupBox_5) # 左侧选项列表 self.oleft_widget.setGeometry(QtCore.QRect(10, 40, 181, 300)) self.oleft_widget.setStyleSheet(self.olist_style) self.oright_widget = QStackedWidget(self.groupBox_5) self.oright_widget.setGeometry(QtCore.QRect(150, 40, 181, 300)) font = QtGui.QFont() font.setPointSize(18) self.groupBox_5.setFont(font) self.groupBox_5.setAutoFillBackground(False) self.groupBox_5.setObjectName("groupBox_5") self.O_comboBox_list = [] self.O_label_list = [] self.pushButton = QtWidgets.QPushButton(Form) font = QtGui.QFont() font.setPointSize(18) self.pushButton.setFont(font) self.pushButton.setGeometry(QtCore.QRect(570, 630, 551, 61)) self.pushButton.clicked.connect(self.btn_save) self.pushButton.setObjectName("pushButton") self.pushButton_2 = QtWidgets.QPushButton(Form) font = QtGui.QFont() font.setPointSize(18) self.pushButton_2.setFont(font) self.pushButton_2.setGeometry(QtCore.QRect(570, 560, 551, 61)) self.pushButton_2.clicked.connect(self.btn_add_class) self.pushButton_2.setObjectName("pushButton_2") self.comboBox_11 = QtWidgets.QComboBox(Form) self.comboBox_11.setGeometry(QtCore.QRect(40, 440, 241, 31)) font = QtGui.QFont() font.setPointSize(18) self.comboBox_11.setFont(font) self.comboBox_11.setEditable(False) self.comboBox_11.setObjectName("comboBox_11") for i, key in enumerate(self.A_dict.keys()): self.comboBox_11.addItem("") for i, key in enumerate(self.O_dict.keys()): self.comboBox_11.addItem("") self.lineEdit_2 = QtWidgets.QLineEdit(Form) self.lineEdit_2.setGeometry(QtCore.QRect(930, 480, 201, 21)) self.lineEdit_2.setObjectName("lineEdit_2") self.pushButton_3 = QtWidgets.QPushButton(Form) font = QtGui.QFont() font.setPointSize(18) self.pushButton_3.setFont(font) self.pushButton_3.setGeometry(QtCore.QRect(40, 530, 461, 61)) self.pushButton_3.clicked.connect(self.btn_add_val) self.pushButton_3.setObjectName("pushButton_3") self.radioButton = QtWidgets.QRadioButton(Form) self.radioButton.setGeometry(QtCore.QRect(580, 480, 100, 20)) self.radioButton.setChecked(True) self.radioButton.toggled.connect(self.radio_msg) self.radioButton.setObjectName("radioButton") self.radioButton_2 = QtWidgets.QRadioButton(Form) self.radioButton_2.setGeometry(QtCore.QRect(670, 480, 100, 20)) self.radioButton_2.toggled.connect(self.radio_msg) self.radioButton_2.setObjectName("radioButton_2") self.textEdit = QtWidgets.QTextEdit(Form) self.textEdit.setGeometry(QtCore.QRect(300, 440, 201, 81)) self.textEdit.setObjectName("textEdit") self.label_11 = QtWidgets.QLabel(Form) self.label_11.setGeometry(QtCore.QRect(40, 410, 60, 31)) font = QtGui.QFont() font.setPointSize(18) self.label_11.setFont(font) self.label_11.setObjectName("label_11") self.label_12 = QtWidgets.QLabel(Form) self.label_12.setGeometry(QtCore.QRect(850, 480, 61, 21)) font = QtGui.QFont() font.setPointSize(18) self.label_12.setFont(font) self.label_12.setObjectName("label_12") self.label_13 = QtWidgets.QLabel(Form) self.label_13.setGeometry(QtCore.QRect(300, 410, 141, 21)) font = QtGui.QFont() font.setPointSize(18) self.label_13.setFont(font) self.label_13.setObjectName("label_13") self.label_9 = QtWidgets.QLabel(Form) self.label_9.setGeometry(QtCore.QRect(30, 380, 551, 31)) font = QtGui.QFont() font.setPointSize(18) self.label_9.setFont(font) self.label_9.setObjectName("label_9") self.label_15 = QtWidgets.QLabel(Form) self.label_15.setGeometry(QtCore.QRect(860, 510, 71, 21)) font = QtGui.QFont() font.setPointSize(18) self.label_15.setFont(font) self.label_15.setObjectName("label_15") self.lineEdit_3 = QtWidgets.QLineEdit(Form) self.lineEdit_3.setGeometry(QtCore.QRect(930, 510, 201, 21)) self.lineEdit_3.setObjectName("lineEdit_3") self.checkBox = QtWidgets.QCheckBox(Form) self.checkBox.setGeometry(QtCore.QRect(580, 510, 87, 20)) self.checkBox.setObjectName("checkBox") self.pushButton_4 = QtWidgets.QPushButton(Form) font = QtGui.QFont() font.setPointSize(18) self.pushButton_4.setFont(font) self.pushButton_4.setGeometry(QtCore.QRect(930, 380, 211, 41)) self.pushButton_4.setObjectName("pushButton_4") self.pushButton_4.clicked.connect(self.btn4_back) self.pushButton_jump = QtWidgets.QPushButton(Form) self.pushButton_jump.setFont(font) self.pushButton_jump.setGeometry(QtCore.QRect(930, 430, 211, 41)) self.pushButton_jump.setObjectName("pushButton_4") self.pushButton_jump.clicked.connect(self.btn_jump) self.QTextEdit = QtWidgets.QTextEdit(Form) self.QTextEdit.setGeometry(QtCore.QRect(40, 610, 461, 91)) self.QTextEdit.setObjectName("QTextEdit") self.label_left = QtWidgets.QLabel(Form) self.label_left.setGeometry(QtCore.QRect(800, 700, 551, 31)) font = QtGui.QFont() font.setPointSize(18) self.label_left.setFont(font) self.label_left.setObjectName("label_left") self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): '''加载界面ui''' self.left_widget.currentRowChanged.connect( self.right_widget.setCurrentIndex) # list和右侧窗口的index对应绑定 self.oleft_widget.currentRowChanged.connect( self.oright_widget.setCurrentIndex) # list和右侧窗口的index对应绑定 # self.left_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 隐藏滚动条 self.left_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) for i, att_cl in enumerate(self.A_dict.keys()): self.item = QListWidgetItem(att_cl, self.left_widget) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.item.setFont(font) self.item.setSizeHint(QSize(15, 25)) self.item.setTextAlignment(Qt.AlignCenter) # 居中显示 locals()['stack' + str(i)] = QListWidget() # 左侧选项列表 locals()['stack' + str(i)].setGeometry(QtCore.QRect( 0, 0, 181, 360)) locals()['stack' + str(i)].setStyleSheet(self.list_style) for att_v in self.A_dict[att_cl]: self.ritem = QListWidgetItem(att_v, locals()['stack' + str(i)]) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.ritem.setFont(font) self.ritem.setSizeHint(QSize(15, 25)) self.ritem.setTextAlignment(Qt.AlignCenter) # 居中显示 self.right_widget.addWidget(locals()['stack' + str(i)]) self.A_comboBox_list.append(locals()["stack" + str(i)]) locals()['stack' + str(i)].currentRowChanged.connect( self.row_change) for i, obj_cl in enumerate(self.O_dict.keys()): self.oitem = QListWidgetItem(obj_cl, self.oleft_widget) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.oitem.setFont(font) self.oitem.setSizeHint(QSize(15, 25)) self.oitem.setTextAlignment(Qt.AlignCenter) # 居中显示 locals()['ostack' + str(i)] = QListWidget() # 左侧选项列表 locals()['ostack' + str(i)].setGeometry( QtCore.QRect(0, 0, 181, 360)) locals()['ostack' + str(i)].setStyleSheet(self.olist_style) for obj_v in self.O_dict[obj_cl]: self.oritem = QListWidgetItem(obj_v, locals()['ostack' + str(i)]) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.oritem.setFont(font) self.oritem.setSizeHint(QSize(15, 25)) self.oritem.setTextAlignment(Qt.AlignCenter) # 居中显示 self.oright_widget.addWidget(locals()['ostack' + str(i)]) self.O_comboBox_list.append(locals()["ostack" + str(i)]) locals()['ostack' + str(i)].currentRowChanged.connect( self.orow_change) _translate = QtCore.QCoreApplication.translate for i, key in enumerate(self.A_dict.keys()): self.comboBox_11.setItemText(i, _translate("Form", key)) for i, key in enumerate(self.O_dict.keys()): self.comboBox_11.setItemText(i + len(self.A_dict.keys()), _translate("Form", key)) Form.setWindowTitle(_translate("Form", "Anotation Tool")) self.groupBox.setTitle(_translate("Form", "属性")) self.groupBox_5.setTitle(_translate("Form", "对象")) self.pushButton_3.setText(_translate("Form", "完成添加")) self.radioButton.setText(_translate("Form", "属性")) self.radioButton_2.setText(_translate("Form", "对象")) self.label_11.setText(_translate("Form", "名称:")) self.label_12.setText(_translate("Form", "名称:")) self.label_13.setText(_translate("Form", "值:")) self.label_9.setText( _translate("Form", "文件名称:" + self.file_list[self.num])) self.label_left.setText( _translate( "Form", "图片已标注:" + str(len(os.listdir("Labels/"))) + ",还剩:" + str(len(self.file_list) - len(os.listdir("Labels/"))))) self.pushButton.setText(_translate("Form", "注释图片")) self.pushButton_2.setText(_translate("Form", "属性/对象完成添加")) self.label_15.setText(_translate("Form", "值:")) self.checkBox.setText(_translate("Form", "更新到图表")) self.pushButton_4.setText(_translate("Form", "上一张图片")) self.pushButton_jump.setText(_translate("Form", "跳过图片")) def btn_jump(self): self.num += 1 with open("count", "w") as f: f.write(str(self.num)) shutil.copy("./Images/" + self.file_list[self.num - 1], "./SkipImages/") if self.num > len(self.file_list) - 1: sys.exit(0) pixmap = QPixmap("./Images/" + self.file_list[self.num]) self.label_16.setPixmap(pixmap) self.label_16.setScaledContents(True) self.left_widget.reset() self.oleft_widget.reset() _translate = QtCore.QCoreApplication.translate self.label_9.setText( _translate("Form", "Image Name:" + self.file_list[self.num])) self.label_left.setText( _translate( "Form", "图片已标注:" + str(len(os.listdir("Labels/"))) + ",还剩:" + str(len(self.file_list) - len(os.listdir("Labels/"))))) for comboBox_i in self.A_comboBox_list: comboBox_i.reset() for comboBox_i in self.O_comboBox_list: comboBox_i.reset() self.A_answer = {} self.O_answer = {} self.QTextEdit.clear() def row_change(self): cv = self.left_widget.currentIndex().data() i = self.left_widget.currentIndex().row() j = self.A_comboBox_list[i].currentIndex().row() vv = self.A_comboBox_list[i].currentIndex().data() self.A_answer[cv] = vv self.QTextEdit.setPlainText( str("对象:\n") + str(self.O_answer) + "\n" + str("属性:\n") + str(self.A_answer) + "\n") def orow_change(self): cv = self.oleft_widget.currentIndex().data() i = self.oleft_widget.currentIndex().row() j = self.O_comboBox_list[i].currentIndex().row() vv = self.O_comboBox_list[i].currentIndex().data() self.O_answer[cv] = vv self.QTextEdit.setPlainText( str("对象:\n") + str(self.O_answer) + "\n" + str("属性:\n") + str(self.A_answer) + "\n") def btn_save(self): self.num += 1 with open("count", "w") as f: f.write(str(self.num)) text = self.QTextEdit.toPlainText() O_an = eval(text.split('\n')[1]) A_an = eval(text.split('\n')[3]) if os.path.exists("./Labels/" + self.file_list[self.num - 1] + ".json"): os.remove("./Labels/" + self.file_list[self.num - 1] + ".json") dic = {} dic['object'] = O_an A_an_list = [] for att in A_an.keys(): A_an_list.append({att: A_an[att]}) dic['attributes'] = A_an_list with open("./Labels/" + self.file_list[self.num - 1] + ".json", mode="a") as f: json.dump(dic, f, ensure_ascii=False) if self.num > len(self.file_list) - 1: sys.exit(0) pixmap = QPixmap("./Images/" + self.file_list[self.num]) self.label_16.setPixmap(pixmap) self.label_16.setScaledContents(True) self.left_widget.reset() self.oleft_widget.reset() _translate = QtCore.QCoreApplication.translate self.label_9.setText( _translate("Form", "Image Name:" + self.file_list[self.num])) self.label_left.setText( _translate( "Form", "图片已标注:" + str(len(os.listdir("Labels/"))) + ",还剩:" + str(len(self.file_list) - len(os.listdir("Labels/"))))) for comboBox_i in self.A_comboBox_list: comboBox_i.reset() for comboBox_i in self.O_comboBox_list: comboBox_i.reset() self.A_answer = {} self.O_answer = {} self.QTextEdit.clear() def btn_add_val(self): my_key = self.comboBox_11.currentText() text = self.textEdit.toPlainText() text_list = text.split(',') _translate = QtCore.QCoreApplication.translate for i, key in enumerate(self.A_dict.keys()): if key == my_key: lines = [] with open("Attribute", encoding='utf-8-sig') as f: for line in f.readlines(): temp = line[:-1].split(':') if temp[0] == my_key: lines.append(line[:-1] + ',' + text + '\n') else: lines.append(line) with open("Attribute", 'w', encoding='utf-8') as f: s = ''.join(lines) f.write(str(s)) for txt in text_list: self.item = QListWidgetItem( txt, self.A_comboBox_list[i]) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.item.setFont(font) self.item.setSizeHint(QSize(15, 25)) self.item.setTextAlignment(Qt.AlignCenter) # 居中显示 self.A_dict[key] += text_list for i, key in enumerate(self.O_dict.keys()): if key == my_key: lines = [] with open("Object", encoding="utf-8-sig") as f: for line in f.readlines(): temp = line[:-1].split(':') if temp[0] == my_key: lines.append(line[:-1] + ',' + text + '\n') else: lines.append(line) with open("Object", 'w', encoding='utf-8') as f: s = ''.join(lines) f.write(str(s)) for txt in text_list: self.oitem = QListWidgetItem( txt, self.O_comboBox_list[i]) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.oitem.setFont(font) self.oitem.setSizeHint(QSize(15, 25)) self.oitem.setTextAlignment(Qt.AlignCenter) # 居中显示 self.O_dict[key] += text_list print([my_key, text]) self.textEdit.setText("") def radio_msg(self): if self.radioButton.isChecked(): self.add_a = True self.add_o = False if self.radioButton_2.isChecked(): self.add_o = True self.add_a = False def btn_add_class(self): if self.add_a: self.radioButton.setChecked(True) my_key = self.lineEdit_2.text() my_val = self.lineEdit_3.text() my_val = my_val.split(",") _translate = QtCore.QCoreApplication.translate if self.checkBox.isChecked(): if len(my_key) != 0: i = len(self.A_comboBox_list) self.item = QListWidgetItem(my_key, self.left_widget) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.item.setFont(font) self.item.setSizeHint(QSize(15, 25)) self.item.setTextAlignment(Qt.AlignCenter) # 居中显示 locals()['stack' + str(i)] = QListWidget() # 左侧选项列表 locals()['stack' + str(i)].setGeometry( QtCore.QRect(0, 0, 181, 360)) locals()['stack' + str(i)].setStyleSheet(self.list_style) for att_v in my_val: self.ritem = QListWidgetItem( att_v, locals()['stack' + str(i)]) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.ritem.setFont(font) self.ritem.setSizeHint(QSize(15, 25)) self.ritem.setTextAlignment(Qt.AlignCenter) # 居中显示 self.right_widget.addWidget(locals()['stack' + str(i)]) self.A_comboBox_list.append(locals()["stack" + str(i)]) locals()['stack' + str(i)].currentRowChanged.connect( self.row_change) self.A_dict[my_key] = my_val lines = [] with open("Attribute", encoding="utf-8-sig") as f: for line in f.readlines(): lines.append(line) lines.append('\n' + my_key + ":" + ",".join(my_val)) with open("Attribute", 'w', encoding="utf-8") as f: s = ''.join(lines) f.write(str(s)) self.comboBox_11.addItem("") self.comboBox_11.setItemText( len(self.A_dict.keys()) + len(self.O_dict.keys()) - 1, _translate("Form", my_key)) else: text = self.QTextEdit.toPlainText() if len(text) != 0: self.A_answer = eval(text.split('\n')[3]) self.O_answer = eval(text.split('\n')[1]) else: self.A_answer = {} self.O_answer = {} # print(A_an) self.A_answer[my_key] = my_val[0] self.QTextEdit.setPlainText( str("对象:\n") + str(self.O_answer) + "\n" + str("属性:\n") + str(self.A_answer) + "\n") if self.add_o: self.add_o = False self.radioButton.setChecked(True) my_key = self.lineEdit_2.text() my_val = self.lineEdit_3.text() my_val = my_val.split(",") _translate = QtCore.QCoreApplication.translate if self.checkBox.isChecked(): if len(my_key) != 0: i = len(self.O_comboBox_list) self.oitem = QListWidgetItem(my_key, self.oleft_widget) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.oitem.setFont(font) self.oitem.setSizeHint(QSize(15, 25)) self.oitem.setSizeHint(QSize(15, 20)) self.oitem.setTextAlignment(Qt.AlignCenter) # 居中显示 locals()['ostack' + str(i)] = QListWidget() # 左侧选项列表 locals()['ostack' + str(i)].setGeometry( QtCore.QRect(0, 0, 181, 360)) locals()['ostack' + str(i)].setStyleSheet(self.olist_style) for obj_v in my_val: self.oritem = QListWidgetItem( obj_v, locals()['ostack' + str(i)]) # 左侧选项的添加 font = QtGui.QFont() font.setPointSize(15) self.oritem.setFont(font) self.oritem.setSizeHint(QSize(15, 25)) self.oritem.setTextAlignment(Qt.AlignCenter) # 居中显示 self.oright_widget.addWidget(locals()['ostack' + str(i)]) self.O_comboBox_list.append(locals()["ostack" + str(i)]) locals()['ostack' + str(i)].currentRowChanged.connect( self.orow_change) self.O_dict[my_key] = my_val lines = [] with open("Object", encoding="utf-8-sig") as f: for line in f.readlines(): lines.append(line) lines.append('\n' + my_key + ":" + ",".join(my_val)) with open("Object", 'w', encoding="utf-8") as f: s = ''.join(lines) f.write(str(s)) self.comboBox_11.addItem("") self.comboBox_11.setItemText( len(self.A_dict.keys()) + len(self.O_dict.keys()) - 1, _translate("Form", my_key)) else: text = self.QTextEdit.toPlainText() if len(text) != 0: self.A_answer = eval(text.split('\n')[3]) self.O_answer = eval(text.split('\n')[1]) else: self.A_answer = {} self.O_answer = {} self.O_answer[my_key] = my_val[0] self.QTextEdit.setPlainText( str("对象:\n") + str(self.O_answer) + "\n" + str("属性:\n") + str(self.A_answer) + "\n") self.radio_flag = False self.checkBox.setChecked(False) self.lineEdit_2.setText("") self.lineEdit_3.setText("") def btn4_back(self): if self.num < 1: sys.exit(0) self.num = self.num - 1 with open("count", "w") as f: f.write(str(self.num)) pixmap = QPixmap("./Images/" + self.file_list[self.num]) self.label_16.setPixmap(pixmap) self.label_16.setScaledContents(True) _translate = QtCore.QCoreApplication.translate self.label_9.setText( _translate("Form", "Image Name:" + self.file_list[self.num])) for comboBox_i in self.A_comboBox_list: comboBox_i.reset() for comboBox_i in self.O_comboBox_list: comboBox_i.reset() self.QTextEdit.clear()
class Window(QMainWindow): def __init__(self): super(Window, self).__init__() # Set size and centre window self.setGeometry(50, 50, 500, 400) qtRectangle = self.frameGeometry() centerPoint = QDesktopWidget().availableGeometry().center() qtRectangle.moveCenter(centerPoint) self.move(qtRectangle.topLeft()) self.setWindowTitle("Rthenticator") self.setWindowIcon(QIcon('icon.ico')) self.setStyleSheet("background-color: #2F3031") self.home() def home(self): # Init QSystemTrayIcon self.tray_icon = QSystemTrayIcon(self) self.tray_icon.setIcon(QIcon('icon.ico')) show_action = QAction("Show", self) quit_action = QAction("Exit", self) hide_action = QAction("Hide", self) show_action.triggered.connect(self.show) hide_action.triggered.connect(self.hide) quit_action.triggered.connect(qApp.quit) tray_menu = QMenu() tray_menu.addAction(show_action) tray_menu.addAction(hide_action) tray_menu.addAction(quit_action) self.tray_icon.setContextMenu(tray_menu) self.tray_icon.activated.connect(self.systemIcon) self.tray_icon.show() # Button Setup self.btnImport = QPushButton("Import", self) self.btnImport.move(50, 320) self.btnImport.setStyleSheet( "background-color: #737C7D; color: #E9E6E4") self.btnImport.clicked.connect(self.btnImportClicked) # Listbox Setup self.Listbox = QListWidget(self) self.Listbox.setAlternatingRowColors(True) self.Listbox.setFixedSize(220, 300) self.Listbox.move(10, 10) self.Listbox.setStyleSheet( "alternate-background-color: #3F4041; color: #E9E6E4;") self.Listbox.itemClicked.connect(self.listboxClicked) for key in sorted(secrets): self.Listbox.addItem(key) self.Listbox.setCurrentRow(0) self.Listbox.currentItem().setSelected(True) # Listview context menu self.Listbox.setContextMenuPolicy(Qt.CustomContextMenu) self.Listbox.customContextMenuRequested.connect(self.showMenu) self.Listbox.itemChanged.connect(self.listboxChanged) self.old_name = "" # Frame Setup self.Frame = QFrame(self) self.Frame.setFixedSize(220, 300) self.Frame.move(266, 10) self.Frame.setFrameShape(QFrame.Shape.Panel) self.Frame.setFrameShadow(QFrame.Shadow.Plain) self.Frame.setStyleSheet("color: #828790") # Progress Bar Setup self.progress = QProgressBar(self) self.progress.setGeometry(266, 325, 200, 20) self.progress.setTextVisible(False) self.progress.setStyleSheet( "QProgressBar::chunk { background: #6187CB; }") self.progress.setRange(1, 29) # Progress Bar Timer Setup self.timer = QTimer() self.timer.timeout.connect(self.progressTimer) self.timer.start(1000) # Label Setup self.label = QLabel(self) self.label.setGeometry(310, 220, 150, 40) self.label.setText("") self.label.setFont(QFont("Arial", 30, QFont.Bold)) self.label.setStyleSheet("color: #E9E6E4") self.label.setTextInteractionFlags(Qt.TextSelectableByMouse) self.image = QLabel(self) self.image.setGeometry(300, 40, 150, 150) self.Listbox.setFocus(True) self.listboxClicked() self.show() # Restore view when tray icon doubleclicked def systemIcon(self, reason): if reason == QSystemTrayIcon.DoubleClick: self.show() self.copy_auth_code() # Override closeEvent, to intercept the window closing event def closeEvent(self, event): event.ignore() self.hide() self.tray_icon.showMessage("Tray Program", "Application was minimized to Tray", QSystemTrayIcon.Information, 2000) def copy_auth_code(self): """ Copies Authentication code to the clipboard """ answer = self.Listbox.currentItem().text() totp = pyotp.TOTP(secrets[answer][0]) self.label.setText(str(totp.now())) pyperclip.copy(totp.now()) def progressTimer(self): """ Updates progress timer Copies authentication code to clipboard once timer has reached 0 and main window is not in system tray """ current_time = int(time.time() % 30) self.progress.setValue(current_time) if current_time == 0: if self.isVisible(): self.copy_auth_code() def setImage(self): """ Reads from the images directory to see if there is a matching logo and must be the same name Splits the text on a `:` png files only """ item = self.Listbox.currentItem().text().split(":")[0] fname = f"images/{item}.png" if os.path.isfile(fname): pixmap = QPixmap(fname).scaled(150, 150) self.image.setPixmap(pixmap) else: self.image.setPixmap(QPixmap()) def listboxClicked(self): """ Listbox has been clicked """ self.setImage() self.copy_auth_code() def btnImportClicked(self): """ Imports a QR-code png file and add its to secrets.json """ fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "All Files (*)") if fileName: test = unquote( decode(Image.open(fileName))[0].data.decode("utf-8")) query = urlsplit(test).query params = parse_qs(query) start = "/totp/" end = "\\?" test = re.search(f'{start}(.*){end}', test).group(1) secrets[test] = [params['secret'][0]] self.Listbox.addItem(test) with open('secrets.json', 'w') as fh: json.dump(secrets, fh, sort_keys=True, indent=4) def showMenu(self, pos): """ Displays right click context menu, with 2 options - Rename - Allows us to rename an entry - Delete - Aloows us to remove and entry """ menu = QMenu() renameAction = menu.addAction("Rename") deleteAction = menu.addAction("Delete") action = menu.exec_(self.Listbox.viewport().mapToGlobal(pos)) if action == renameAction: this_item = self.Listbox.currentItem() self.Listbox.blockSignals( True ) # Block signals so we dont trigger the listboxChanged function this_item.setFlags( this_item.flags() | Qt.ItemIsEditable) # Allows us to edit the item self.Listbox.blockSignals(False) # Re-enables signals self.old_name = this_item.text() self.Listbox.edit(self.Listbox.currentIndex()) if action == deleteAction: self.showMessageBox() def showMessageBox(self): """ Creates and displays a message box for delete confirmation """ box = QMessageBox() box.setIcon(QMessageBox.Question) box.setWindowTitle('Warning!') box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) box.setStyleSheet("background-color: #2F3031;") box.setText( "<FONT COLOR='#E9E6E4'>Do you really wish to delete this?</FONT>") btnYes = box.button(QMessageBox.Yes) btnYes.setStyleSheet("background-color: #737C7D; color: #E9E6E4") btnYes.setText('Yes') btnNo = box.button(QMessageBox.No) btnNo.setStyleSheet("background-color: #737C7D; color: #E9E6E4") btnNo.setText('No') box.exec_() if box.clickedButton() == btnYes: items = self.Listbox.selectedItems() for item in items: new_name = item.text() self.Listbox.takeItem(self.Listbox.row(item)) secrets.pop(new_name) with open('secrets.json', 'w') as fh: json.dump(secrets, fh, sort_keys=True, indent=4) def listboxChanged(self): """ Called when we have changed text of an item in the listbox """ new_name = self.Listbox.currentItem().text() self.Listbox.blockSignals( True) # Block signals so we dont trigger ourselves this_item = self.Listbox.currentItem() this_item.setFlags(this_item.flags() & ~Qt.ItemIsEditable) # Turn off the Editable flag self.Listbox.blockSignals(False) # Re-enables signals to be processed secrets[new_name] = secrets.pop(self.old_name) with open('secrets.json', 'w') as fh: json.dump(secrets, fh, sort_keys=True, indent=4)
class ConceptBox(QGroupBox): def __init__(self, db): super().__init__() self.db = db self.reference_list = [] # Concept field # ======================= self.concept_label = QLabel("Concept:", self) self.concept_filed = QLineEdit(self) # Subcategory field # ======================= self.subcategory_label = QLabel("Subcategory:", self) self.subcategory_field = QLineEdit(self) # Synonyms names field # ======================= self.synonyms_label = QLabel("Synonyms:", self) self.synonyms_field = QLineEdit(self) # Description field # ======================= self.description_label = QLabel("Description:", self) self.description_field = QTextEdit(self) # Reference field # ======================= self.reference_label = QLabel("Reference:", self) self.reference_field = QListWidget(self) # Study field # ======================== self.study_label = QLabel("Study:", self) self.study_field = QLineEdit(self) self.grid = QGridLayout() self.initActions() self._configWidgets() self._setCompleters() self.setLayout(self.grid) def _configWidgets(self): self.reference_field.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.reference_field.setContextMenuPolicy(Qt.CustomContextMenu) self.reference_field.customContextMenuRequested.connect( self.showContextMenu) self.grid.setAlignment(Qt.AlignTop) self.grid.setSpacing(5) self.grid.addWidget(self.concept_label, 1, 0) self.grid.addWidget(self.concept_filed, 1, 1) self.grid.addWidget(self.subcategory_label, 2, 0) self.grid.addWidget(self.subcategory_field, 2, 1) self.grid.addWidget(self.synonyms_label, 3, 0) self.grid.addWidget(self.synonyms_field, 3, 1) self.grid.addWidget(self.description_label, 4, 0, Qt.AlignTop) self.grid.addWidget(self.description_field, 4, 1) self.grid.addWidget(self.study_label, 5, 0) self.grid.addWidget(self.study_field, 5, 1) self.grid.addWidget(self.reference_label, 6, 0, Qt.AlignTop) self.grid.addWidget(self.reference_field, 6, 1) def _setCompleters(self): concepts = [[c.name, c.synonyms] for c in self.db.session.query(Concept).all()] subcategories = [[c.subcategory, c.study] for c in self.db.session.query(Subcategory).all()] if len(concepts) != 0: name, synonyms = zip(*concepts) concept_completer = QCompleter(name) concept_completer.setCaseSensitivity(Qt.CaseInsensitive) self.concept_filed.setCompleter(concept_completer) synonyms_completer = QCompleter(synonyms) synonyms_completer.setCaseSensitivity(Qt.CaseInsensitive) self.synonyms_field.setCompleter(synonyms_completer) if len(subcategories) != 0: subcategory, study = zip(*subcategories) subcategory_completer = QCompleter(subcategory) subcategory_completer.setCaseSensitivity(Qt.CaseInsensitive) self.subcategory_field.setCompleter(subcategory_completer) study_completer = QCompleter(study) study_completer.setCaseSensitivity(Qt.CaseInsensitive) self.study_field.setCompleter(study_completer) def showContextMenu(self, pos): global_position = self.reference_field.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.new_reference_action) my_menu.addAction(self.delete_reference_action) my_menu.addSeparator() my_menu.exec(global_position) def deleteReference(self): if self.reference_field.currentIndex().isValid(): item = self.reference_field.selectedItems()[0].data(Qt.UserRole) self.reference_list.remove(item) self.setReferences(self.reference_list) def setReferences(self, result): self.reference_field.clear() for reference in result: item = QListWidgetItem() item.setData(Qt.UserRole, reference) item.setText("{}".format(reference.text)) self.reference_field.insertItem(0, item) def createReference(self): dlg = NewReferenceDialog(self.parent().parent().parent().db, ConceptReference) if dlg.exec_(): self.reference_list += dlg.getValues() self.setReferences(self.reference_list) def initActions(self): self.delete_reference_action = QAction("Delete reference", self) self.delete_reference_action.triggered.connect(self.deleteReference) self.new_reference_action = QAction("New reference", self) self.new_reference_action.triggered.connect(self.createReference) def getData(self): concept_name = self.concept_filed.text() subcat = self.subcategory_field.text() syn = self.synonyms_field.text() description = Description(text=self.description_field.toPlainText()) description.reference = self.reference_list description = description if description.text != "" else None study = self.study_field.text() concept = Concept(name=concept_name, synonyms=syn) subcategory = Subcategory(subcategory=subcat, study=study) return concept, subcategory, description
class MainWindow(QWidget): def __init__(self): super().__init__() # Official Georgia Tech colors TechGold = QtGui.QColor(179,163,105) TechBlue = QtGui.QColor(0,38,58) BuzzGold = QtGui.QColor(234,179,0) left_box = QVBoxLayout() url = 'https://hamblen.ece.gatech.edu/ALTERA/onedge/gatech/images/gtbuzz.gif' data = urllib.request.urlopen(url).read() pixmap = QtGui.QPixmap() pixmap.loadFromData(data) buzz = QLabel() buzz.setPixmap(pixmap) left_box.addWidget(buzz) ta_box = QHBoxLayout() ta_label = QLabel() ta_label.setFont(QtGui.QFont("Arial", 33, QtGui.QFont.Black)) ta_label.setText("TA's On Duty:") self.ta_show = QLineEdit() self.ta_show.setFont(QtGui.QFont("Arial", 16, QtGui.QFont.Expanded)) self.ta_show.setPlaceholderText("There are no TA's Signed In") self.ta_show.setAlignment(Qt.AlignCenter) ta_box.addWidget(ta_label) ta_box.addWidget(self.ta_show) left_box.addLayout(ta_box) timer = QTimer(self) timer.timeout.connect(self.showDateTime) timer.start(1000) self.date_label = QLabel() self.date_label.setFont(QtGui.QFont("Arial", 25, QtGui.QFont.Black, QtGui.QFont.Expanded)) self.date_label.setAlignment(Qt.AlignCenter) self.time_label = QLabel() self.time_label.setFont(QtGui.QFont("Arial", 25, QtGui.QFont.Black, QtGui.QFont.Expanded)) self.time_label.setAlignment(Qt.AlignCenter) left_box.addWidget(self.date_label) left_box.addWidget(self.time_label) wrapper_box = QHBoxLayout() wrapper_box.setAlignment(Qt.AlignCenter) self.is_open = QCheckBox('Open') self.is_open.setFont(QtGui.QFont("Arial", 25, QtGui.QFont.Expanded)) self.is_open.toggle() self.is_open.setStyleSheet("margin-left:50%; margin-right:50%;") self.is_open.stateChanged.connect(self.close_queue) wrapper_box.addWidget(self.is_open) left_box.addLayout(wrapper_box) self.is_open.setStyleSheet("margin-left:50%; margin-right:50%;") self.student_count = QLabel() self.student_count.setFont(QtGui.QFont("Arial", 25)) self.student_count.setAlignment(Qt.AlignCenter) left_box.addWidget(self.student_count) left_box.setAlignment(Qt.AlignCenter) student_box = QVBoxLayout() student_label = QLabel() student_label.setFont(QtGui.QFont("Arial", 33, QtGui.QFont.Black)) student_label.setText("Student Queue:") self.student_show = QListWidget() self.student_show.setFont(QtGui.QFont("Arial", 18)) self.student_in = QLineEdit() self.student_in.setFont(QtGui.QFont("Arial", 16, QtGui.QFont.Expanded)) self.student_in.setPlaceholderText("Your Name Here") self.student_in.setAlignment(Qt.AlignCenter) self.student_add = QPushButton() self.student_add.setText('Add') self.student_add.setFont(QtGui.QFont("Arial", 16)) student_rem = QPushButton() student_rem.setText('Remove') student_rem.setFont(QtGui.QFont("Arial", 16)) student_box.addWidget(student_label) student_box.addWidget(self.student_show) student_box.addWidget(self.student_in) student_box.addWidget(self.student_add) student_box.addWidget(student_rem) self.student_count.setText("Queue Count: " + str(self.student_show.count())) self.student_add.clicked.connect(self.add_student) student_rem.clicked.connect(self.rem_student) hbox = QHBoxLayout() hbox.addLayout(left_box) hbox.addLayout(student_box) hbox.setAlignment(Qt.AlignCenter) p = self.palette() p.setColor(self.backgroundRole(), TechGold) self.setPalette(p) self.setLayout(hbox) self.setWindowTitle('CS2316 Help Desk Queue') self.showFullScreen() def add_student(self): if all(char.isalpha() or char.isspace() for char in str(self.student_in.text())) and len(str(self.student_in.text())) and self.student_add.isEnabled(): time_in = QTime.currentTime() self.student_show.addItem(" "+self.student_in.text() + ' ('+time_in.toString(Qt.DefaultLocaleLongDate)+')') self.student_in.clear() self.student_count.setText("Queue Count: " + str(self.student_show.count())) else: self.student_in.clear() def rem_student(self): self.student_show.takeItem(self.student_show.currentIndex().row()) self.student_count.setText("Queue Count: " + str(self.student_show.count())) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() elif e.key() == Qt.Key_Return or e.key() == Qt.Key_Enter: self.add_student() elif e.key() == Qt.Key_Delete: self.student_rem() elif e.key() == Qt.Key_Alt: self.showNormal() def showDateTime(self): self.time_label.setText(QTime.currentTime().toString(Qt.DefaultLocaleLongDate)) self.date_label.setText(QDate.currentDate().toString(Qt.DefaultLocaleLongDate)) def close_queue(self): if self.is_open.isChecked(): self.student_add.setEnabled(True) else: self.student_add.setEnabled(False)
class history_search_result(QWidget): def __init__(self): super().__init__() self.db = None self.result = None self.init() def set_db(self, db): self.db = db self.detail.set_db(db, 'history') def init(self): self.index = '' self.keyword = '' self.mode = '' self.list = QListWidget() self.list.addItem("-----搜索-----") self.layout = QGridLayout() self.layout.addWidget(self.list, 0, 0, 10, 8) self.setLayout(self.layout) self.list.itemClicked.connect(self.item_detail) self.detail = item_detail.item_detail() def show_data(self, index, keyword, mode): self.index = index self.keyword = keyword self.mode = mode if len(keyword) == 0: print('没有关键词, 默认搜索全部') self.result = self.db.get_all_from_table('history') else: print("搜索关键词: ", keyword) self.result = self.db.get_search_from_table( index, keyword, 'history', mode) self.clear_data() print("开始显示...") if len(self.result) == 0: print('没有数据!') self.list.addItem("没有数据!") return System.set_historylist(self.list, self.result, "日期", "标题", "正文") QApplication.processEvents() print('显示完成') def clear_data(self): System.clear_data(self) def item_detail(self): print('item detail') index = self.list.currentIndex().row() if index == 0: print('非item') return else: print("是item") item = self.result[index - 1] id = item[0] print(item[1]) title = str(item[1].encode('latin-1').decode('gbk')).strip() article = str(item[2].encode('latin-1').decode('gbk')).strip() # print(date) self.detail._signal.connect(self.renew_item) self.detail.set_content(str(id), title, article) self.detail.exec() def renew_item(self): self.show_data(self.index, self.keyword, self.mode) print('已刷新')
class Controles(QMainWindow): def __init__(self, parent=None): super(Controles, self).__init__(parent) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setWindowTitle("Controles") self.Reproduciendo = False self.strButtonShow = " Ver Reproductor" self.strButtonHide = "Ocultar Reproductor" self.videoVentana = VideoWindow() self.videoVentana.setControles(self) self.videoVentana.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint) self.videoVentana.resize(640, 480) self.listwidget = QListWidget() self.listwidget.clicked.connect(self.listclicked) self.playButton = QPushButton() self.playButton.setEnabled(True) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.stopButton = QPushButton() self.stopButton.setEnabled(True) self.stopButton.setIcon(self.style().standardIcon(QStyle.SP_MediaStop)) self.stopButton.clicked.connect(self.stop) self.anadirButton = QPushButton() self.anadirButton.setEnabled(True) self.anadirButton.setText("+") self.anadirButton.setIcon(self.style().standardIcon( QStyle.SP_FileIcon)) self.anadirButton.clicked.connect(self.addFile) self.removeButton = QPushButton() self.removeButton.setEnabled(True) self.removeButton.setText("-") self.removeButton.setIcon(self.style().standardIcon( QStyle.SP_FileIcon)) self.removeButton.clicked.connect(self.removeFile) self.abrirListaButton = QPushButton() self.abrirListaButton.setEnabled(True) self.abrirListaButton.setText(" ") self.abrirListaButton.setIcon(self.style().standardIcon( QStyle.SP_FileDialogNewFolder)) self.abrirListaButton.clicked.connect(self.openList) self.guardarListaButton = QPushButton() self.guardarListaButton.setEnabled(True) self.guardarListaButton.setText(" ") self.guardarListaButton.setIcon(self.style().standardIcon( QStyle.SP_DialogSaveButton)) self.guardarListaButton.clicked.connect(self.saveList) self.quitarButton = QPushButton() self.quitarButton.setEnabled(True) self.quitarButton.setText("-") self.quitarButton.setIcon(self.style().standardIcon( QStyle.SP_FileIcon)) self.quitarButton.clicked.connect(self.removeFile) self.showPlayerButton = QPushButton() self.showPlayerButton.setEnabled(True) self.showPlayerButton.setText(self.strButtonShow) self.showPlayerButton.clicked.connect(self.showPlayer) self.maxButton = QPushButton() self.maxButton.setEnabled(True) self.maxButton.setText("Maximizar") self.maxButton.clicked.connect(self.maximizePlayer) self.minButton = QPushButton() self.minButton.setEnabled(True) self.minButton.setText("Normal") self.minButton.clicked.connect(self.minimizePlayer) self.screensButton = QPushButton() self.screensButton.setEnabled(True) self.screensButton.setText("Cambiar pantalla") self.screensButton.clicked.connect(self.elegirPantalla) self.sigScreenButton = QPushButton() self.sigScreenButton.setEnabled(True) self.sigScreenButton.setText(">") self.sigScreenButton.setIcon(self.style().standardIcon( QStyle.SP_ComputerIcon)) self.sigScreenButton.clicked.connect(self.sigPantalla) self.antScreenButton = QPushButton() self.antScreenButton.setEnabled(True) self.antScreenButton.setText("<") self.antScreenButton.setIcon(self.style().standardIcon( QStyle.SP_ComputerIcon)) self.antScreenButton.clicked.connect(self.antPantalla) self.lblMediaActual = QLabel() self.lblMediaActual.setText("Media actual: No seleccionado.") self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) self.errorLabel = QLabel() self.errorLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) # Create a widget for window contents wid = QWidget(self) self.setCentralWidget(wid) # Create layouts to place inside widget #controlLayout = QHBoxLayout() controlLayout = QGridLayout() #controlLayout.setContentsMargins(0, 0, 0, 0) # row, col, rowspan, colspan# controlLayout.addWidget(self.maxButton, 0, 0, 1, 2) controlLayout.addWidget(self.minButton, 0, 2, 1, 2) controlLayout.addWidget(self.showPlayerButton, 0, 4, 1, 2) controlLayout.addWidget(self.screensButton, 0, 6, 1, 2) controlLayout.addWidget(self.positionSlider, 1, 0, 1, 8) controlLayout.addWidget(self.listwidget, 2, 0, 6, 4) controlLayout.addWidget(self.playButton, 2, 4, 1, 1) controlLayout.addWidget(self.stopButton, 3, 4, 1, 1) controlLayout.addWidget(self.anadirButton, 4, 4, 1, 1) controlLayout.addWidget(self.quitarButton, 4, 5, 1, 1) controlLayout.addWidget(self.lblMediaActual, 5, 4, 1, 4) controlLayout.addWidget(self.abrirListaButton, 2, 5, 1, 1) controlLayout.addWidget(self.sigScreenButton, 2, 7, 1, 1) controlLayout.addWidget(self.antScreenButton, 3, 7, 1, 1) controlLayout.addWidget(self.guardarListaButton, 3, 5, 1, 1) controlLayout.addWidget(self.errorLabel, 8, 0, 1, 8) layout = QVBoxLayout() layout.addLayout(controlLayout) #Eventos del reproductor self.videoVentana.mediaPlayer.stateChanged.connect( self.mediaStateChanged) self.videoVentana.mediaPlayer.positionChanged.connect( self.positionChanged) self.videoVentana.mediaPlayer.durationChanged.connect( self.durationChanged) self.videoVentana.mediaPlayer.error.connect(self.handleError) self.videoVentana.mediaPlayer.currentMediaChanged.connect( self.currentMediaChanged) # Set widget to contain window contents wid.setLayout(layout) #Server, receives commands to player self.server = Server(self.videoVentana) self.startServer() def startServer(self): import threading try: threading.Thread(target=self.server.start_server, args=(puerto, )).start() print("Server on port " + str(puerto)) #QMessageBox.question(self, 'Info', "Opening server on port "+str(800), QMessageBox.Ok) except Exception as err: print(str(err)) def reload(self): self.listwidget.clear() for x in range(0, self.videoVentana.count()): try: newUrl = str(self.videoVentana.mediaPlayer.playlist().media( x).canonicalUrl().toLocalFile()) self.listwidget.insertItem( self.listwidget.count(), os.path.splitext(os.path.basename(newUrl))[0]) except Exception as err: print(str(err)) #List functions def listclicked(self, qmodelindex): #item = self.listwidget.currentItem() #print(item.text()) #print(item.row()) item = self.listwidget.currentIndex() def openList(self): try: fileName, _ = QFileDialog.getOpenFileName(self, "Seleccionar lista", QDir.homePath()) #f = open(fileName,"r") self.listwidget.clear() for line in open(fileName, 'r'): self.addFile(line) except Exception as err: QMessageBox.question(self, 'Alerta', "Error" + str(err), QMessageBox.Ok) def saveList(self): try: fileName, _ = QFileDialog.getOpenFileName(self, "Seleccionar lista", QDir.homePath()) f = open(fileName, "w+") for i in range(0, self.listwidget.count()): newUrl = str(self.videoVentana.mediaPlayer.playlist().media( i).canonicalUrl().toLocalFile()) f.write(newUrl + "\n") f.close() except Exception as err: QMessageBox.question(self, 'Alerta', "Error" + str(err), QMessageBox.Ok) def addFile(self, fileName=''): try: if fileName == '' or fileName == False: fileName, _ = QFileDialog.getOpenFileName( self, "Seleccionar video", QDir.homePath() + "\\Videos") except: fileName, _ = QFileDialog.getOpenFileName(self, "Seleccionar video", QDir.homePath()) if fileName == '' or fileName == False: return for x in range(0, self.listwidget.count() ): #Valida que no exista el archivo a agregar try: if self.listwidget.itemAt(x, 0).text() == os.path.splitext( os.path.basename(fileName))[0]: QMessageBox.question(self, 'Alerta', "Video ya en la lista", QMessageBox.Ok) return except Exception as err: print(err) return self.listwidget.insertItem( self.listwidget.count(), os.path.splitext(os.path.basename(fileName))[0]) try: self.videoVentana.addFile(fileName) except Exception as err: #Si hay un error, vuelve a abrir la ventana de video y carga la lista self.listwidget.removeItemWidget( self.listwidget.itemAt(self.listwidget.count() - 1)) self.Reproduciendo = False self.videoVentana = VideoWindow() self.videoVentana.resize(640, 480) for x in range(0, self.listwidget.count()): self.videoVentana.addFile(self.listwidget.itemAt(x).text()) print(err) def removeFile(self): index = self.listwidget.currentRow() if index != -1: try: cantPlayList = self.videoVentana.count() self.videoVentana.removeFile(index) #Elimina del playlist #self.videoVentana.mediaPlayer.playlist().removeMedia(index) if cantPlayList != self.videoVentana.count( ): #Si se borro de la playlist self.listwidget.takeItem(index) #Elimina del comboBox print( str(self.listwidget.count()) + "<-listWidget playlist->" + str(self.videoVentana.count())) except Exception as err: print(str(err)) #Media functions def play(self): item = self.listwidget.currentRow() self.videoVentana.play(item) #play/pause def stop(self): self.videoVentana.stop() #play/pause #Window functions def elegirPantalla(self): self.seleccionarP = SeleccionPantalla() self.seleccionarP.AsignarVideoWidget(self.videoVentana) self.seleccionarP.resize(400, 300) self.seleccionarP.show() def sigPantalla(self): self.videoVentana.sigPantalla() def antPantalla(self): self.videoVentana.antPantalla() def showPlayer(self): if self.showPlayerButton.text() == self.strButtonShow: self.videoVentana.show() self.showPlayerButton.setText(self.strButtonHide) else: self.videoVentana.hide() self.showPlayerButton.setText(self.strButtonShow) def maximizePlayer(self): self.videoVentana.showFullScreen() self.showPlayerButton.setText(self.strButtonHide) def minimizePlayer(self): self.videoVentana.showNormalS() self.showPlayerButton.setText(self.strButtonHide) def playerVisible(self): return self.showPlayerButton.text() != self.strButtonShow #Events def closeEvent(self, event): buttonReply = QMessageBox.question( self, 'Question', "¿Close? Will close video window too.", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.Yes: try: self.server.stop() except Exception as err: print("Error at closing Thread: " + str(err)) self.videoVentana.close() self.close() else: print('No clicked.') event.ignore() return def currentMediaChanged(self, actualMedia): titulo = str(actualMedia.canonicalUrl().fileName()) self.videoVentana.setWindowTitle(titulo) self.lblMediaActual.setText("Media actual: \n" + titulo) def mediaStateChanged(self, state): if self.videoVentana.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) self.Reproduciendo = True else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.Reproduciendo = False def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) def setPosition(self, position): self.videoVentana.mediaPlayer.setPosition(position) def handleError(self): #self.playButton.setEnabled(False) self.errorLabel.setText("Error: " + self.videoVentana.mediaPlayer.errorString())
class Player(QMainWindow): """A simple Media Player using VLC and Qt """ def __init__(self, master=None): if '--clear' in sys.argv: os.remove('.cache') # Read Data if not os.path.exists('AllChannel.json'): print('Reffering channel info from server.') print( 'If you want to customize channel data, generate AllChannel.json file by generate_SKB_channels.py.', file=sys.stderr) from generate_SKB_channels import get_channels channels = dict([(_['ServiceId'], _) for _ in get_channels()]) else: print('Using AllChannel.json for referring channel info.') with open('AllChannel.json', encoding='UTF8') as f: channels = dict([(_['ServiceId'], _) for _ in json.loads(f.read())]) new_stream_db = read_m3u(sys.argv[1]) old_stream_db = read_m3u(sys.argv[2]) stream_urls = [_['multicast'] for _ in new_stream_db] if os.path.exists('.cache'): with open('.cache', 'rb') as f: cache = pickle.loads(f.read()) else: cache = {} # Checking broken stream global vlc_error_count, vlc_error_check, vlc_handle_mode instance = vlc.Instance("--verbose=-1") instance.log_set(vlc_log_callback, None) mediaplayer = instance.media_player_new() mediaplayer.video_set_scale(0.1) print('Checking broken stream...') for url in tqdm.tqdm(stream_urls): if not url in cache: vlc_error_count = 0 vlc_error_check = False mediaplayer.set_media(instance.media_new(url)) mediaplayer.play() time.sleep(3) cache[url] = vlc_error_check with open('.cache', 'wb') as f: f.write(pickle.dumps(cache)) mediaplayer.stop() self.stream_verify = cache vlc_handle_mode = 1 ############################## playlist = remove_unmapped_channel(old_stream_db, stream_urls) playlist = fill_unmapped_channel(playlist, channels) self.channel_info = channels self.playlist = playlist self.stream_urls = stream_urls import pprint #pprint.pprint(update_db) print(len(old_stream_db), len(playlist), len(new_stream_db), len(channels)) # QT Initialize QMainWindow.__init__(self, master) self.setWindowTitle("Media Player") # creating a basic vlc instance self.instance = vlc.Instance("--verbose=-1") self.instance.log_set(vlc_log_callback, None) # creating an empty vlc media player self.mediaplayer = self.instance.media_player_new() self.createUI() def createUI(self): """Set up the user interface, signals & slots """ self.widget = QWidget(self) self.setCentralWidget(self.widget) # In this widget, the video will be drawn if sys.platform == "darwin": # for MacOS from PyQt5.QtWidgets import QMacCocoaViewContainer self.videoframe = QMacCocoaViewContainer(0) else: self.videoframe = QFrame() self.palette = self.videoframe.palette() self.palette.setColor(QPalette.Window, QColor(0, 0, 0)) self.videoframe.setPalette(self.palette) self.videoframe.setAutoFillBackground(True) self.videoframe.setMinimumWidth(720) self.videoframe.setMinimumHeight(480) #self.hbuttonbox = QHBoxLayout() #self.openchannel = QPushButton("Open Channel Data") #self.hbuttonbox.addWidget(self.openchannel) #self.openchannel.clicked.connect(self.PlayPause) self.hcontrolbox = QHBoxLayout() self.hinfobox = QHBoxLayout() self.icon = QLabel() self.icon.setFixedSize(200, 60) self.icon.setAlignment(Qt.AlignCenter) self.hinfobox.addWidget(self.icon) self.vinfobox = QVBoxLayout() self.ch_name = QLabel("Loading...") font = QFont() font.setBold(True) font.setFamily('Malgun Gothic') font.setPointSize(16) self.ch_name.setFont(font) self.vinfobox.addWidget(self.ch_name) self.hservicebox = QHBoxLayout() self.hservicebox.addWidget(QLabel('Service ID ')) self.service_id = QLabel("[#]") self.hservicebox.addWidget(self.service_id) self.vinfobox.addLayout(self.hservicebox) self.hinfobox.addLayout(self.vinfobox) self.hcontrolbox.addLayout(self.hinfobox) self.hcontrolbox.addStretch(1) self.volumeslider = QSlider(Qt.Horizontal, self) self.volumeslider.setMaximum(100) self.volumeslider.setValue(self.mediaplayer.audio_get_volume()) self.volumeslider.setToolTip("Volume") self.hcontrolbox.addWidget(self.volumeslider) self.volumeslider.valueChanged.connect(self.setVolume) # self.channelbox = QVBoxLayout() self.channellist = QListWidget() self.channellist.setFixedWidth(320) self.channellist.itemClicked.connect(self.selectChannel) self.channelbox.addWidget(self.channellist) self.channelfilter = QLineEdit() self.channelfilter.setFixedWidth(320) self.channelfilter.textChanged.connect(self.find_channel) self.channelbox.addWidget(self.channelfilter) self.streambox = QVBoxLayout() self.streamlist = QListWidget() self.streamlist.setFixedWidth(320) self.streamlist.itemClicked.connect(self.selectStream) self.streambox.addWidget(self.streamlist) self.mapbutton = QPushButton("Map") self.mapbutton.clicked.connect(self.map) self.streambox.addWidget(self.mapbutton) self.vboxlayout = QVBoxLayout() self.vboxlayout.addWidget(self.videoframe) self.vboxlayout.addLayout(self.hcontrolbox) self.hboxlayout = QHBoxLayout() self.hboxlayout.addLayout(self.vboxlayout) self.hboxlayout.addLayout(self.channelbox) self.hboxlayout.addLayout(self.streambox) self.widget.setLayout(self.hboxlayout) export = QAction("&Export", self) export.triggered.connect(self.ExportFile) exit = QAction("E&xit", self) exit.triggered.connect(sys.exit) menubar = self.menuBar() filemenu = menubar.addMenu("&File") filemenu.addAction(export) filemenu.addSeparator() filemenu.addAction(exit) self.updatePlaylist() def ExportFile(self): print(os.path.expanduser('~')) #filename = QFileDialog.getSaveFileName(self, "Save File", os.path.expanduser('~'),)[0] filename = QFileDialog.getSaveFileName( self, "Export Playlist File", 'playlist.m3u', "M3U Playlist (*.m3u *.m3u8)", )[0] if not filename: return with open(filename, 'wt', encoding='UTF8') as f: f.write('#EXTM3U\n') for item in [ self.channellist.item(_) for _ in range(self.channellist.count()) ]: if item.checkState(): data = item.data(Qt.UserRole) f.write( f"#EXTINF:-1 tvg-id=\"{data['tvg-id']}\" tvg-logo=\"{data['tvg-logo']}\" tvg-chno=\"{data['tvh-chnum']}\" tvh-chnum=\"{data['tvh-chnum']}\", {data['ch-name']}\n" ) f.write(f"{data['multicast']}\n") filename = QFileDialog.getSaveFileName( self, "Export Channel File", 'Channel.json', "JSON File (*.json)", )[0] if not filename: return channels = [] for item in [ self.channellist.item(_) for _ in range(self.channellist.count()) ]: if item.checkState(): data = item.data(Qt.UserRole) channels.append(self.channel_info[data['tvg-id']]) with open(filename, 'wt', encoding='UTF8') as f: f.write(json.dumps(channels, indent=2)) def setVolume(self, Volume): """Set the volume """ self.mediaplayer.audio_set_volume(Volume) def find_channel(self, text): if text: for item in [ self.channellist.item(_) for _ in range(self.channellist.count()) ]: if item.text().lower().find(text.lower()) >= 0: item.setHidden(False) else: item.setHidden(True) else: for item in [ self.channellist.item(_) for _ in range(self.channellist.count()) ]: item.setHidden(False) def map(self, *args, **kwargs): item = self.channellist.currentItem() item.setCheckState(Qt.Checked) channel = item.data(Qt.UserRole) sitem = self.streamlist.currentItem() radio = self.streamlist.itemWidget(sitem) channel['multicast'] = radio.text() item.setData(Qt.UserRole, channel) self.updateMappedInfo() def playStream(self, stream_url): global vlc_error_count, vlc_error_check vlc_error_count = 0 vlc_error_check = False self.media = self.instance.media_new(stream_url) # put the media in the media player self.mediaplayer.set_media(self.media) # parse the metadata of the file self.media.parse() # set the title of the track as window title self.setWindowTitle(self.media.get_meta(0)) # the media player has to be 'connected' to the QFrame # (otherwise a video would be displayed in it's own window) # this is platform specific! # you have to give the id of the QFrame (or similar object) to # vlc, different platforms have different functions for this if sys.platform.startswith('linux'): # for Linux using the X Server self.mediaplayer.set_xwindow(self.videoframe.winId()) elif sys.platform == "win32": # for Windows self.mediaplayer.set_hwnd(self.videoframe.winId()) elif sys.platform == "darwin": # for MacOS self.mediaplayer.set_nsobject(int(self.videoframe.winId())) self.mediaplayer.play() def selectChannel(self, item): global vlc_error_count, vlc_error_check vlc_error_count = 0 vlc_error_check = False channel = item.data(Qt.UserRole) print(channel) if 'multicast' in channel and channel['multicast']: streams = dict([(item.data(Qt.UserRole), item) for item in [ self.streamlist.item(_) for _ in range(self.streamlist.count()) ]]) if channel['multicast'] in streams: self.selectStream(streams[channel['multicast']]) else: item.setCheckState(Qt.Unchecked) else: item.setCheckState(Qt.Unchecked) self.ch_name.setText(channel['ch-name']) frame = self.getIcon(channel['tvg-logo']) pixmap = QPixmap() pixmap.loadFromData(frame) self.icon.setPixmap( pixmap.scaled(self.icon.width(), self.icon.height(), Qt.KeepAspectRatio)) self.service_id.setText(f"[{channel['tvg-id']}]") def updateStreamRadioState(self, state): if state: found = False for item in [ self.streamlist.item(_) for _ in range(self.streamlist.count()) ]: radio = self.streamlist.itemWidget(item) if radio.isChecked(): self.channellist.currentItem().setCheckState(Qt.Checked) item.setText("") self.streamlist.setCurrentItem(item) self.streamlist.update(self.streamlist.currentIndex()) self.selectStreamImpl(item) found = True break if not found: item = self.streamlist.item(0) self.streamlist.setCurrentItem(item) self.selectStreamImpl(item) def selectStream(self, item): stream_info = item.data(Qt.UserRole) radio = self.streamlist.itemWidget(item) radio.setChecked(True) def selectStreamImpl(self, item): global vlc_error_count, vlc_error_check vlc_error_count = 0 vlc_error_check = False radio = self.streamlist.itemWidget(item) url = radio.text() item.setData(Qt.UserRole, url) print('URL from Radio :', url) if url: self.playStream(url) #citem = self.channellist.currentItem() #data = citem.data(Qt.UserRole) #data['multicast'] = url #citem.setData(Qt.UserRole, data) #print('Saved URL :', url) else: pass #self.mediaplayer.pause() #citem = self.channellist.currentItem() #data = citem.data(Qt.UserRole) #data['multicast'] = None #citem.setData(Qt.UserRole, data) #print('Saved URL :', None) self.updateMappedInfo() def getMappedDict(self): mapped_dict = {} for item in [ self.channellist.item(_) for _ in range(self.channellist.count()) ]: data = item.data(Qt.UserRole) if data['multicast']: if data['multicast'] in mapped_dict: mapped_dict[data['multicast']].append(data['ch-name']) else: mapped_dict[data['multicast']] = [data['ch-name']] return mapped_dict def updateMappedInfo(self): print('UpdateMappedInfo') mapped_dict = self.getMappedDict() for item in [ self.streamlist.item(_) for _ in range(self.streamlist.count()) ]: url = item.data(Qt.UserRole) if url == '__BROKEN__': item.setText("*** BROKEN ***") elif url in mapped_dict: item.setText(f"[{','.join(mapped_dict[url])}]" if mapped_dict[url] else "") else: item.setText("") self.streamlist.update(self.streamlist.indexFromItem(item)) def disableChannel(self): self.channellist.currentItem().setCheckState(Qt.Unchecked) self.channellist.update(self.channellist.currentIndex()) data = self.channellist.currentItem().data(Qt.UserRole) data['multicast'] = None self.channellist.currentItem().setData(Qt.UserRole, data) self.streamlist.update(self.streamlist.currentIndex()) self.streamlist.currentItem().setData(Qt.UserRole, '__BROKEN__') self.updateMappedInfo() #app.processEvents() @functools.lru_cache(maxsize=None) def getIcon(self, url): req = request.Request(url) req.add_header( 'User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0' ) frame = None for _ in range(3): try: resp = request.urlopen(req) frame = resp.read() break except: time.sleep(1) return frame def attachIcon(self, item): channel = item.data(Qt.UserRole) url = channel['tvg-logo'] pixmap = QPixmap() pixmap.loadFromData(self.getIcon(url)) item.setIcon(QIcon(pixmap)) def asyncCacheIcon(self): def asyncThread(listwidget): for item in [ listwidget.item(_) for _ in range(listwidget.count()) ]: channel = item.data(Qt.UserRole) self.attachIcon(item) listwidget.update(listwidget.indexFromItem(item)) threading.Thread(target=asyncThread, args=(self.channellist, ), daemon=True).start() def updatePlaylist(self): self.channellist.clear() for channel in self.playlist: item = QListWidgetItem() item.setData(Qt.UserRole, channel) item.setText(f"[{channel['tvh-chnum']}] {channel['ch-name']}") item.setCheckState(Qt.Checked if channel['multicast'] and not self.stream_verify[channel['multicast']] else Qt.Unchecked) self.channellist.addItem(item) item = QListWidgetItem() item.setData(Qt.UserRole, '') self.streamlist.addItem(item) radio = QRadioButton('Unbound Stream URL') radio.toggled.connect(self.updateStreamRadioState) self.streamlist.setItemWidget(item, radio) for url in self.stream_urls: item = QListWidgetItem() item.setTextAlignment(Qt.AlignRight) item.setData(Qt.UserRole, '__BROKEN__' if self.stream_verify[url] else url) self.streamlist.addItem(item) radio = QRadioButton(url) radio.toggled.connect(self.updateStreamRadioState) self.streamlist.setItemWidget(item, radio) self.updateMappedInfo() self.asyncCacheIcon() def delayedSelectChannel(n): time.sleep(n) self.channellist.setCurrentRow(0) self.selectChannel(self.channellist.currentItem()) threading.Thread(target=delayedSelectChannel, args=(3, ), daemon=True).start()
class EditRelationDialog(QDialog): def __init__(self, parent, relation): super().__init__(parent=parent, flags=Qt.WindowCloseButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowMinimizeButtonHint) self.relation = relation self.commit_button = QPushButton("Commit changes", self) self.relation_label = QLabel("Relation", self) self.relation_line = QTextEdit(self) self.study_label = QLabel("Study", self) self.study_line = QLineEdit(self) self.references_label = QLabel("Reference", self) self.references_line = QListWidget(self) self._setValue() self.grid = QGridLayout() self._configWidgets() self.setLayout(self.grid) def _configWidgets(self): self.setWindowTitle("Edit relation") self.resize(600, 10) # Binding self.commit_button.clicked.connect(self._commitChanges) self.references_line.setContextMenuPolicy(Qt.CustomContextMenu) self.references_line.customContextMenuRequested.connect( self._showReferenceMenu) self.grid.setSizeConstraint(QGridLayout.SetMinimumSize) # Grid Layout self.grid.addWidget(self.relation_label, 2, 0, Qt.AlignTop) self.grid.addWidget(self.relation_line, 2, 1) self.grid.addWidget(self.study_label, 3, 0) self.grid.addWidget(self.study_line, 3, 1) self.grid.addWidget(self.references_label, 4, 0, Qt.AlignTop) self.grid.addWidget(self.references_line, 4, 1) self.grid.addWidget(self.commit_button, 7, 1, Qt.AlignRight) def _addReference(self): dialog = NewReferenceDialog(self.parent().db, RelationReference) if dialog.exec_(): references = dialog.getValues() for reference in references: reference.relation_id = self.relation.id self.parent().db.commit(reference) item = QListWidgetItem() item.setData(Qt.UserRole, reference) item.setText("{}".format(reference.text)) self.references_line.insertItem(0, item) def _editReference(self): if self.references_line.currentIndex().isValid(): reference = self.references_line.selectedItems()[0].data( Qt.UserRole) dlg = EditReferenceOrDescription(reference) if dlg.exec_(): reference = dlg.getValue() self.references_line.selectedItems()[0].data( Qt.UserRole).text = reference.text self.references_line.selectedItems()[0].setText(reference.text) self.parent().db.update_reference(reference) def _deleteReference(self): if self.references_line.currentIndex().isValid(): reference = self.references_line.selectedItems()[0].data( Qt.UserRole) self.parent().db.delete(reference) item = self.references_line.selectedItems()[0] self.references_line.takeItem(self.references_line.row(item)) def _showReferenceMenu(self, pos): edit_reference_action = QAction("&Edit", self) edit_reference_action.triggered.connect(self._editReference) delete_reference_action = QAction("&Delete", self) delete_reference_action.triggered.connect(self._deleteReference) add_reference_action = QAction("&Add new", self) add_reference_action.triggered.connect(self._addReference) global_position = self.references_line.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(edit_reference_action) my_menu.addAction(delete_reference_action) my_menu.addAction(add_reference_action) my_menu.exec(global_position) def _setValue(self): self.relation_line.setText(self.relation.description) self.study_line.setText(self.relation.study) references = self.relation.reference for ref in references: item = QListWidgetItem() item.setData(Qt.UserRole, ref) item.setText("{}".format(ref.text)) self.references_line.insertItem(0, item) def getValue(self): description = self.relation_line.toPlainText() study = self.study_line.text() return Relation(id=self.relation.id, description=description, study=study) def _commitChanges(self): self.accept()
class EditConceptDialog(QDialog): def __init__(self, parent, concept, subcategory): super().__init__(parent=parent, flags=Qt.WindowCloseButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowMinimizeButtonHint) self.concept = concept self.subcategory = subcategory self.commit_button = QPushButton("Commit changes", self) self.concept_label = QLabel("Concept", self) self.concept_field = QLineEdit(self) self.subcategory_label = QLabel("Subcategory", self) self.subcategory_field = QLineEdit(self) self.synonyms_label = QLabel("Synonyms", self) self.synonyms_field = QLineEdit(self) self.description_label = QLabel("Description", self) self.description_field = QListWidget(self) self.study_label = QLabel("Study", self) self.study_field = QLineEdit(self) self.references_label = QLabel("References", self) self.references_field = QListWidget(self) self.grid = QGridLayout() self._configWidgets() self.setValue() def _configWidgets(self): self.resize(600, 80) self.setWindowTitle("Edit concept") self.description_field.itemClicked.connect(self.showReferences) self.references_field.setContextMenuPolicy(Qt.CustomContextMenu) self.references_field.customContextMenuRequested.connect( self._showReferenceMenu) self.description_field.setContextMenuPolicy(Qt.CustomContextMenu) self.description_field.customContextMenuRequested.connect( self.showDescriptionMenu) self.commit_button.clicked.connect(self.commitChanges) self.grid.addWidget(self.commit_button, 1, 1, Qt.AlignRight) self.grid.addWidget(self.concept_label, 2, 0) self.grid.addWidget(self.concept_field, 2, 1) self.grid.addWidget(self.subcategory_label, 3, 0) self.grid.addWidget(self.subcategory_field, 3, 1) self.grid.addWidget(self.synonyms_label, 4, 0) self.grid.addWidget(self.synonyms_field, 4, 1) self.grid.addWidget(self.description_label, 5, 0) self.grid.addWidget(self.description_field, 5, 1) self.grid.addWidget(self.study_label, 6, 0) self.grid.addWidget(self.study_field, 6, 1) self.grid.addWidget(self.commit_button, 7, 1, Qt.AlignRight) self.grid.addWidget(self.references_label, 7, 0, Qt.AlignTop) self.grid.addWidget(self.references_field, 7, 1) self.grid.setSizeConstraint(QGridLayout.SetMinimumSize) self.setLayout(self.grid) def showReferences(self): if self.description_field.currentIndex().isValid(): description = self.description_field.selectedItems()[0].data( Qt.UserRole) self.setReferenceList(description.reference) def setReferenceList(self, result): self.references_field.clear() for ref in result: item = QListWidgetItem() item.setData(Qt.UserRole, ref) item.setText("{}".format(ref.text)) self.references_field.insertItem(0, item) def setValue(self): self.concept_field.setText(self.concept.name) self.synonyms_field.setText(self.concept.synonyms) self.subcategory_field.setText(self.subcategory.subcategory) self.study_field.setText(self.subcategory.study) descriptions = self.subcategory.description for des in descriptions: item = QListWidgetItem() item.setData(Qt.UserRole, des) item.setText("{}".format(des.text)) self.description_field.insertItem(0, item) def addReference(self): if self.description_field.currentIndex().isValid(): description_id = self.description_field.selectedItems()[0].data( Qt.UserRole).id dialog = NewReferenceDialog(self.parent().db, ConceptReference) if dialog.exec_(): references = dialog.getValues() for reference in references: reference.node_id = description_id self.parent().db.commit(reference) item = QListWidgetItem() item.setData(Qt.UserRole, reference) item.setText("{}".format(reference.text)) self.references_field.insertItem(0, item) def editReference(self): if self.references_field.currentIndex().isValid(): reference = self.references_field.selectedItems()[0].data( Qt.UserRole) dlg = EditReferenceOrDescription(reference) if dlg.exec_(): reference = dlg.getValue() self.references_field.selectedItems()[0].data( Qt.UserRole).text = reference.text self.references_field.selectedItems()[0].setText( reference.text) self.parent().db.update_reference(reference) def deleteReference(self): if self.references_field.currentIndex().isValid(): reference = self.references_field.selectedItems()[0].data( Qt.UserRole) self.parent().db.delete(reference) item = self.references_field.selectedItems()[0] self.references_field.takeItem(self.references_field.row(item)) def addDescription(self): dlg = EditReferenceOrDescription( Description(text="", subcategory_id=self.subcategory.id)) dlg.setWindowTitle("Edit description") if dlg.exec_(): description = dlg.getValue() self.parent().db.update_description(description) item = QListWidgetItem() item.setData(Qt.UserRole, description) item.setText("{}".format(description.text)) self.description_field.insertItem(0, item) self.references_field.clear() def editDescription(self): if self.description_field.currentIndex().isValid(): description = self.description_field.selectedItems()[0].data( Qt.UserRole) dlg = EditReferenceOrDescription(description) dlg.setWindowTitle("Edit description") if dlg.exec_(): description = dlg.getValue() self.description_field.selectedItems()[0].data( Qt.UserRole).text = description.text self.description_field.selectedItems()[0].setText( description.text) self.parent().db.update_description(description) def deleteDescription(self): if self.description_field.currentIndex().isValid(): description = self.description_field.selectedItems()[0].data( Qt.UserRole) self.parent().db.delete(description) item = self.description_field.selectedItems()[0] self.description_field.takeItem(self.description_field.row(item)) self.references_field.clear() def _showReferenceMenu(self, pos): edit_reference_action = QAction("&Edit", self) edit_reference_action.triggered.connect(self.editReference) delete_reference_action = QAction("&Delete", self) delete_reference_action.triggered.connect(self.deleteReference) add_reference_action = QAction("&Add new", self) add_reference_action.triggered.connect(self.addReference) global_position = self.references_field.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(edit_reference_action) my_menu.addAction(delete_reference_action) my_menu.addAction(add_reference_action) my_menu.exec(global_position) def showDescriptionMenu(self, pos): edit_description_action = QAction("&Edit", self) edit_description_action.triggered.connect(self.editDescription) delete_description_action = QAction("&Delete", self) delete_description_action.triggered.connect(self.deleteDescription) add_description_action = QAction("&Add new", self) add_description_action.triggered.connect(self.addDescription) global_position = self.description_field.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(edit_description_action) my_menu.addAction(delete_description_action) my_menu.addAction(add_description_action) my_menu.exec(global_position) def getValue(self): concept_name = self.concept_field.text() synonyms = self.synonyms_field.text() subcategory = self.subcategory_field.text() study = self.study_field.text() return (Concept(id=self.concept.id, name=concept_name, synonyms=synonyms), Subcategory(id=self.subcategory.id, subcategory=subcategory, study=study)) def commitChanges(self): self.accept()
class ListEntry(BaseParamWidget): def __init__(self, layout_dir: str, title: str, initial_value: List[List[str]], new_id_func: Callable): super().__init__(layout_dir) self.choices = [] self.text_list = [] lab_title = QLabel(text=title) layout = QHBoxLayout() self.central_layout.addWidget(lab_title) self.on_check_callback = None self.list_widget = QListWidget() self.set_value(initial_value) layout_tools = QVBoxLayout() self.button_add_item = QPushButton('+') self.button_delete_item = QPushButton('-') self.button_delete_item.clicked.connect(self.delete_row) self.button_add_item.clicked.connect(self.add_row) self.button_add_item.setMaximumWidth(20) self.button_delete_item.setMaximumWidth(20) layout_tools.addWidget(self.button_add_item) layout_tools.addWidget(self.button_delete_item) layout.addLayout(layout_tools) layout.addWidget(self.list_widget) self.central_layout.addLayout(layout) self.data = initial_value self.new_id_func = new_id_func def new_id(self): if callable(self.new_id_func): return self.new_id_func() else: return None def add_row(self): self.data[0].append(self.new_id()) self.data[1].append('Unnamed') self.set_value(self.data) def delete_row(self): # item = self.list_widget.currentItem() index = self.list_widget.currentIndex().row() self.data[0].pop(index) self.data[1].pop(index) self.set_value(self.data) def on_listwidget_double_cicked(self): print('edit') item = self.list_widget.currentItem() self.list_widget.editItem(item) def get_value(self): text = [] for i in range(self.list_widget.count()): text.append(self.list_widget.item(i).text()) self.data[1] = text return self.data def set_value(self, data: List[List[str]]): self.list_widget.clear() self.list_widget.addItems(data[1]) self.data = data for index in range(self.list_widget.count()): item = self.list_widget.item(index) item.setFlags(item.flags() | Qt.ItemIsEditable)
class RelationBox(QGroupBox): def __init__(self): super().__init__() self.reference_list = [] # Relation field # ======================= self.relation_label = QLabel("Relation", self) self.relation_field = QTextEdit(self) # Reference field # ======================= self.reference_label = QLabel("Reference:", self) self.reference_field = QListWidget(self) # Study field # ======================= self.study_label = QLabel("Study:", self) self.study_field = QLineEdit(self) self.grid = QGridLayout(self) # Initialization self._initActions() self._configWidgets() def _configWidgets(self): # Reference config self.reference_field.setMinimumWidth(70) self.reference_field.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.reference_field.setContextMenuPolicy(Qt.CustomContextMenu) self.reference_field.customContextMenuRequested.connect( self._showContextMenu) # Grid layout self.grid.setAlignment(Qt.AlignTop) self.grid.addWidget(self.relation_label, 1, 0, Qt.AlignTop) self.grid.addWidget(self.relation_field, 1, 1) self.grid.addWidget(self.study_label, 2, 0) self.grid.addWidget(self.study_field, 2, 1) self.grid.addWidget(self.reference_label, 3, 0, Qt.AlignTop) self.grid.addWidget(self.reference_field, 3, 1) self.grid = QGridLayout() self.grid.setSpacing(5) self.setLayout(self.grid) def _showContextMenu(self, pos): global_position = self.reference_field.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.new_reference_action) my_menu.addAction(self.delete_reference_action) my_menu.addSeparator() my_menu.exec(global_position) def deleteReference(self): if self.reference_field.currentIndex().isValid(): item = self.reference_field.selectedItems()[0].data(Qt.UserRole) self.reference_list.remove(item) self._setReferences(self.reference_list) def _setReferences(self, result): self.reference_field.clear() for reference in result: item = QListWidgetItem() item.setData(Qt.UserRole, reference) item.setText("{}".format(reference.text)) self.reference_field.insertItem(0, item) def createReference(self): dlg = NewReferenceDialog(self.parent().parent().db, RelationReference) if dlg.exec_(): self.reference_list += dlg.getValues() self._setReferences(self.reference_list) def _initActions(self): self.delete_reference_action = QAction("Delete reference", self) self.delete_reference_action.triggered.connect(self.deleteReference) self.new_reference_action = QAction("New reference", self) self.new_reference_action.triggered.connect(self.createReference) def getData(self): relation = self.relation_field.toPlainText() study = self.study_field.text() return Relation(description=relation, study=study), self.reference_list
class PlayoffInputWidget(QWidget): def __init__(self, parent, model): super().__init__(parent) self.model = model self.model.teams_split.connect(self.create_pair_widgets) layout = QVBoxLayout(self) self.setLayout(layout) self.label = QLabel(config.ROUND_STRINGS[1]) self.label.setAlignment(QtCore.Qt.AlignCenter) self.pairs_list = QListWidget(self) self.pairs_list.setStyleSheet( "QListWidget::item { border-bottom: 0.5px solid }") self.pairs_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.pairs_list.customContextMenuRequested.connect( self.list_context_menu) self.teams_left_list = QListView(self) self.teams_left_list.setModel(self.model.teams_left_model) self.teams_left_list.doubleClicked.connect(self.team_clicked) self.button = QPushButton("Finish Pairing") self.button.clicked.connect(self.finish_pairing) self.button.setDisabled(True) layout.addWidget(self.label) layout.addWidget(self.pairs_list) layout.addWidget(self.teams_left_list) layout.addWidget(self.button) self.playoff_assign_index = 0 def create_pair_widgets(self): for ppm in self.model.pairs: pr_widget = PlayoffPairWidget(ppm) item = QListWidgetItem(self.pairs_list) item.setSizeHint(pr_widget.sizeHint()) self.pairs_list.addItem(item) self.pairs_list.setItemWidget(item, pr_widget) def team_clicked(self, model_index: QtCore.QModelIndex): index = model_index.row() self.model.assign_team(index) if len(self.model.teams_left) == 0: self.button.setDisabled(False) def finish_pairing(self): self.layout().removeWidget(self.teams_left_list) self.teams_left_list.deleteLater() self.button.setText("Finish Playoff") for ppm in self.model.pairs: ppm.edit = True self.button.clicked.disconnect(self.finish_pairing) self.button.clicked.connect(self.finish_playoff) def finish_playoff(self): self.model.finish() self.pairs_list.setContextMenuPolicy(QtCore.Qt.NoContextMenu) self.layout().removeWidget(self.button) self.button.deleteLater() self.finished_label = QLabel("Playoff Finished") self.finished_label.setAlignment(QtCore.Qt.AlignCenter) self.layout().addWidget(self.finished_label) self.parent().finish_playoff() def list_context_menu(self, pos): self.listMenu = QMenu() current_index = self.pairs_list.currentIndex() model = self.pairs_list.indexWidget(current_index).model name1, name2 = model.get_name(0), model.get_name(1) team_1_won = self.listMenu.addAction(f"{name1} Won") team_1_won.triggered.connect(lambda: model.set_draw_state(-1)) team_1_won.setDisabled(not model.is_draw()) team_1_plus1 = self.listMenu.addAction(f"{name1} +1 ") team_1_plus1.triggered.connect(lambda: model.set_draw_state(-2)) team_1_plus1.setDisabled(not model.is_draw()) draw = self.listMenu.addAction(f"Draw") draw.triggered.connect(lambda: model.set_draw_state(0)) draw.setDisabled(not model.is_draw()) team_2_won = self.listMenu.addAction(f"{name2} Won") team_2_won.triggered.connect(lambda: model.set_draw_state(1)) team_2_won.setDisabled(not model.is_draw()) team_2_plus1 = self.listMenu.addAction(f"{name2} +1 ") team_2_plus1.triggered.connect(lambda: model.set_draw_state(2)) team_2_plus1.setDisabled(not model.is_draw()) parentPosition = self.pairs_list.mapToGlobal(QtCore.QPoint(0, 0)) self.listMenu.move(parentPosition + pos) self.listMenu.show()
class MediaPlayer(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(300, 300, 400, 300) self.setWindowTitle('MediaPlayer') # Создание центрального виджета и настройка лайоута для поддержания формы интерфейса self.centerWindow = QWidget() self.mainGridLayout = QGridLayout() self.setCentralWidget(self.centerWindow) self.centralWidget().setLayout(self.mainGridLayout) # кнопки добавления и удаления трека self.addBtn = QPushButton('Add File', self) self.addBtn.clicked.connect(self.addFile) self.removeBtn = QPushButton('Remove File', self) self.removeBtn.clicked.connect(self.removeFile) self.mainGridLayout.addWidget(self.addBtn, 1, 0) self.mainGridLayout.addWidget(self.removeBtn, 1, 1) # Кнопка prev self.prevBtn = QPushButton('', self) prevIcon = QIcon() prevIcon.addFile('prev.png') # Назначаем иконку кнопке self.prevBtn.setIcon(prevIcon) # Размещаем кнопку на макете (лайоуте) self.mainGridLayout.addWidget(self.prevBtn, 3, 0) self.prevBtn.clicked.connect(self.PreviousTrack) # Кнопка play self.playBtn = QPushButton('', self) playIcon = QIcon() playIcon.addFile('play.png') self.playBtn.setIcon(playIcon) self.mainGridLayout.addWidget(self.playBtn, 3, 1) self.playBtn.clicked.connect(self.PlayMusic) # Кнопка pause self.pause = QPushButton('', self) pauseIcon = QIcon() pauseIcon.addFile('pause.png') self.pause.setIcon(pauseIcon) self.mainGridLayout.addWidget(self.pause, 3, 2) self.pause.clicked.connect(self.PauseMusic) # Кнопка next self.nextBtn = QPushButton('', self) nextIcon = QIcon() nextIcon.addFile('next.png') self.nextBtn.setIcon(nextIcon) self.mainGridLayout.addWidget(self.nextBtn, 3, 3) self.nextBtn.clicked.connect(self.NextTrack) # создание и настройка таймера и слайдеров self.timer = QTimer() self.timer.setInterval(100) self.timer.timeout.connect(self.Timercheck) self.timer.start() # Таймлайн self.TimeLine = QSlider(Qt.Horizontal, self) self.mainGridLayout.addWidget(self.TimeLine, 2, 0, 1, 4) self.TimeLine.sliderPressed.connect(self.TLPress) self.TimeLine.sliderReleased.connect(self.TLRelease) # Громкость self.Volume = QSlider(Qt.Vertical, self) self.Volume.setValue(50) self.mainGridLayout.addWidget(self.Volume, 1, 4, 3, 1) self.Volume.valueChanged[int].connect(self.changeVolume) # создаем экземпляр медиаплеера self.player = QMediaPlayer() self.player.stateChanged.connect(self.media_status_changed) # Создаем QListWidget() в котором будут хранится имена фалов self.listbox = QListWidget() self.listbox.doubleClicked.connect(self.PlayMusic) # Добавляем наш листбокс в макет addWidget(ОБЪЕКТ, СТРОКА, СТОЛБЕЦ, в высоту, в ширину ) self.mainGridLayout.addWidget(self.listbox, 0, 0, 1, 0) self.LoopCheckbox = QCheckBox('Зациклить', self) self.mainGridLayout.addWidget(self.LoopCheckbox, 1, 2) self.LoopCheckbox.stateChanged.connect(self.CheckboxState) # Создаем список в котором будут хранится имена и пути файлов в список будем добавлять объекты типа plItem self.playList = [] # Признак зацикленности плейлиста и флаг изменения состояния плеера self.loop = True self.IgnoreStateChange = False def CheckboxState(self, state): if state == Qt.Checked: self.IgnoreStateChange = True else: self.IgnoreStateChange = False # функционал таймера, кнопок и ползунков def addFile(self): # Получаем полное имя (с путём) fullFileName = QFileDialog.getOpenFileName( self, 'Add File', '', "Music files (*.mp3 *.ogg)")[0] # Разбиваем на части, используя re.split(r'[\\/]') из библиотеки работы с регулярными выражениями # регулярное выражение r'[\\/]' для того, что бы и виндовс и линукс нормально разбивало путь вин \, лин / splittedFileName = re.split(r'[\\/]', fullFileName) # Получаем имя файла shortFileName = splittedFileName[splittedFileName.__len__() - 1] # Добавляем в плейлист (который список) имя и соответсвующий ему полый путь с именем self.playList.append(plItem(fullFileName, shortFileName)) # Добавляем в listbox только имя файла self.listbox.addItem(shortFileName) # Удаление файла из листбокса def removeFile(self): if self.listbox.selectedItems(): self.playList.pop(self.listbox.currentIndex().row()) self.listbox.takeItem(self.listbox.currentIndex().row()) # Зависимости таймера и таймлайна def TLPress(self): self.timer.stop() self.player.setPosition( (self.player.duration() / 100) * self.TimeLine.value()) def TLRelease(self): self.player.setPosition( (self.player.duration() / 100) * self.TimeLine.value()) self.timer.start() def TLMoved(self): self.player.setPosition( (self.player.duration() / 100) * self.TimeLine.value()) def Timercheck(self): if self.player.duration() != 0: pos = self.player.position() / (self.player.duration() / 100) self.TimeLine.setValue(pos.__int__()) # Предыдущий трэк def PreviousTrack(self): if self.listbox.selectedItems() and (self.listbox.currentRow() != 0): self.IgnoreStateChange = True self.listbox.setCurrentRow(self.listbox.currentIndex().row() - 1) self.PlayMusic() self.IgnoreStateChange = False elif self.listbox.selectedItems() and (self.listbox.currentRow() == 0): self.IgnoreStateChange = True self.listbox.setCurrentRow(self.listbox.__len__() - 1) self.PlayMusic() self.IgnoreStateChange = False # Следующий трэк def NextTrack(self): if self.listbox.selectedItems() and (self.listbox.currentRow() != self.listbox.__len__() - 1): self.IgnoreStateChange = True self.listbox.setCurrentRow(self.listbox.currentIndex().row() + 1) self.PlayMusic() self.IgnoreStateChange = False elif self.listbox.selectedItems() and (self.listbox.currentRow() == self.listbox.__len__() - 1): self.IgnoreStateChange = True self.listbox.setCurrentRow(0) self.PlayMusic() self.IgnoreStateChange = False # громкость, play, pause def changeVolume(self, value): self.player.setVolume(value) def PauseMusic(self): self.player.pause() def PlayMusic(self): if self.listbox.selectedItems(): file = QUrl.fromLocalFile( self.playList[self.listbox.currentIndex().row()].fPath) content = QMediaContent(file) self.player.setMedia(content) self.player.setVolume(self.Volume.value()) self.player.play() elif self.listbox.__len__() > 0: self.listbox.setCurrentRow(0) file = QUrl.fromLocalFile( self.playList[self.listbox.currentIndex().row()].fPath) content = QMediaContent(file) self.player.setMedia(content) self.player.setVolume(self.Volume.value()) self.player.play() # Переход на след трек def media_status_changed(self, status): if not self.IgnoreStateChange: if status == QMediaPlayer.StoppedState: if (self.listbox.currentIndex().row() == self.listbox.__len__() - 1) and self.loop: self.listbox.setCurrentRow(0) file = QUrl.fromLocalFile( self.playList[self.listbox.currentIndex().row()].fPath) content = QMediaContent(file) self.player.setMedia(content) self.player.play() elif self.listbox.currentIndex().row( ) < self.listbox.__len__() - 1: self.listbox.setCurrentRow( self.listbox.currentIndex().row() + 1) file = QUrl.fromLocalFile( self.playList[self.listbox.currentIndex().row()].fPath) content = QMediaContent(file) self.player.setMedia(content) self.player.play() if self.IgnoreStateChange: self.player.play()
class GUI(QWidget): def __init__(self): super(GUI, self).__init__() self.title = "server" self.icon_name = "icon.ico" self.thread_pool = QThreadPool() self.all_ip = [] self.all_text = {} # {ip:{process_name : text}} self.cur_ip = "" self.cur_proc = "" self.InitUI() self.load_data() def InitUI(self): # 기본 설정 self.setWindowTitle(self.title) self.setWindowIcon(QIcon(self.icon_name)) self.setGeometry(200, 200, 1000, 700) # 레이아웃 선언부 mainbox = QVBoxLayout() vbox1 = QVBoxLayout() vbox2 = QVBoxLayout() hbox = QHBoxLayout() underbox = QHBoxLayout() # element 선언부 self.ip_label = QLabel("연결된 IP 목록", self) self.ip_list = QListWidget(self) self.ip_list.clicked.connect(self.ip_listview_clicked) self.proc_label = QLabel("연결된 프로세스 목록", self) self.proc_list = QListWidget(self) self.proc_list.clicked.connect(self.proc_listview_clicked) self.textarea = QPlainTextEdit(self) self.textarea.setReadOnly(True) self.statusbar = QStatusBar() self.check_label = QLabel('현재 프로세스 추적', self) self.checkbox = QCheckBox(self) self.checkbox.setChecked(True) # 위젯 & 레이아웃 정렬 vbox1.addWidget(self.ip_label) vbox1.addWidget(self.ip_list) vbox2.addWidget(self.proc_label) vbox2.addWidget(self.proc_list) hbox.addLayout(vbox1, stretch=4) hbox.addLayout(vbox2, stretch=8) hbox.addWidget(self.textarea, stretch=15) underbox.addWidget(self.statusbar) underbox.addWidget(self.check_label) underbox.addWidget(self.checkbox) mainbox.addLayout(hbox) mainbox.addLayout(underbox) self.setLayout(mainbox) @pyqtSlot() def ip_listview_clicked(self): """ ip리스뷰 클릭시 """ item = self.ip_list.currentIndex() item = str(item.text()) self.all_text[self.cur_ip][self.cur_proc] = self.textarea.toPlainText() self.cur_ip = item if self.all_ip[self.cur_ip]: self.cur_proc = next(iter( self.all_ip[self.cur_ip])) # 가장 처음 시작된 프로세스로 else: self.cur_proc = None self.textarea.clear() if self.all_text[self.cur_ip][self.cur_proc]: self.append_message(self.all_text[self.cur_ip][self.cur_proc]) def listview_update(self, ips): try: self.ip_list.clear() self.ip_list.addItems(ips) if self.cur_ip not in ips: self.statusbar.showMessage("연결된 ip가 없습니다") return except: self.statusbar.showMessage("Except!!") @pyqtSlot() def proc_listview_clicked(self): """ process 리스트뷰 클릭시""" item = self.ip_list.currentIndex() item = str(item.text()) self.all_text[self.cur_ip][self.cur_proc] = self.textarea.toPlainText() self.cur_proc = item self.textarea.clear() if self.all_text[self.cur_ip][self.cur_proc]: self.append_message(self.all_text[self.cur_ip][self.cur_proc]) def load_data(self): """ 기존에 연결된 ip 데이터 로드""" for (path, dirc, files) in os.walk(os.getcwd() + "\\log"): for filename in files: ext = os.path.splitext(filename)[-1] if ext == '.log': ip = path.split("\\")[-1] pname = filename with open(path + '\\' + filename, 'rt') as f: if not ip in self.all_text: self.all_text[ip] = dict() self.all_text[ip][pname] = "".join(f.readlines()) def save_data(self): """ 연결되었던 ip 파일에 로그 저장 """ now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') for ip in self.all_ip: for pname in self.all_text[ip]: path = os.getcwd() + '\\log\\' + ip + '\\' + pname with open(path, 'wt') as f: f.writelines(self.all_text[ip][pname] + now + '\n' + '=' * 40 + '\n\n') def append_message(self, message): """ 메세지를 추가함 """ self.textarea.appendPlainText( message) # insert vs append "\n"이 없냐 있냐 & 자동 스크롤이 안되냐 되냐 차이 self.textarea.viewport().update() def closeEvent(self, event): """ 종료시 모든 데이터 저장 """ close = QMessageBox.question(self, "QUIT", "정말 나가시겠습니까??", QMessageBox.Yes | QMessageBox.No) if close == QMessageBox.Yes: self.hide() # 화면을 숨기고 데이터를 저장후 종료 self.save_data() event.accept() else: event.ignore()
class TimelineWindow(QWidget): def __init__(self): super().__init__() timeline_bk_path = './source/pic/timeline_bk.png' hgzy_font_path = './source/font/HGZYT_CNKI.TTF' rem_ico_path = './source/pic/rem.png' fontId = QFontDatabase.addApplicationFont(hgzy_font_path) fontName = QFontDatabase.applicationFontFamilies(fontId)[0] self.index = -1 self.pix = QPixmap(timeline_bk_path) self.resize(self.pix.width(),self.pix.height()) self.pix = self.pix.scaled(int(self.pix.width()),int(self.pix.height())) self.setMask(self.pix.mask()) screen = QDesktopWidget().screenGeometry() self.move((screen.width() - self.pix.width()) / 2, (screen.height() - self.pix.height()) / 2) self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.FramelessWindowHint) rem_icon = QIcon(QPixmap(rem_ico_path)) self.setWindowIcon(rem_icon) self.m_DragPosition = None self.m_drag = False self.animelist = QListWidget(self) self.animelist.setObjectName('AnimeList') self.animelist.setStyleSheet('#AnimeList{background:transparent}') self.animelist.setGeometry(200,165,310,350) self.animelist.setFont(QFont(fontName,11,QFont.Light)) self.detail = Detail(self.x()+50,self.y()-15) self.detail_show = False self.animelist.itemDoubleClicked.connect(self.DetailBt) self.TimeLabels_path = [] self.TimeLabels_clicked_path = [] self.weekanime = TimeLine().get_week_anime() for time in range(1,8): self.TimeLabels_path.append('./source/pic/week_day_%d.png' % time) self.TimeLabels_clicked_path.append('./source/pic/week_day_%d_clicked.png' % time) self.TimeLabels = [] for time in range(7): self.TimeLabels.append(QDlabel(self)) self.setTimeLabel() self.daylabel = QLabel(self) self.daylabel.setObjectName('DayLabel') self.daylabel.setGeometry(290,110,200,40) self.daylabel.setFont(QFont(fontName,13,QFont.Bold)) self.setDaytext() self.timelineshow = False def paintEvent(self, event): paint = QPainter(self) paint.drawPixmap(0,0,self.pix.width(),self.pix.height(),self.pix) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.m_drag = True self.m_DragPosition = event.globalPos() - self.pos() if self.detail_show == True: self.detail.raise_() event.accept() elif event.button() == Qt.RightButton: if self.detail_show == True: self.detail.close() self.detail_show = False self.hide() self.timelineshow = False event.accept() def mouseMoveEvent(self, event): if Qt.LeftButton and self.m_drag: self.move(event.globalPos() - self.m_DragPosition) self.detail.move(self.x()+50 - self.detail.pix.width(),self.y()-15) event.accept() def mouseReleaseEvent(self, event): self.m_drag = False def closeEvent(self, event): self.detail.close() self.detail_show = False self.timelineshow = False def setTimeLabel(self): label_between = 60 week_animes = self.weekanime start = week_animes[0]['day_of_week']-1 for time in range(start,start+7): time_mod = time % 7 self.TimeLabels[time_mod].setObjectName('DayLabel%d' % (time_mod+1)) self.TimeLabels[time_mod].setStyleSheet('#DayLabel%d{border-image:url(%s)}' % (time_mod+1,self.TimeLabels_path[time_mod])) self.TimeLabels[time_mod].setGeometry(100,120 + label_between * (time-start),57,24) self.labelclick = week_animes[0]['day_of_week'] self.TimeLabels[self.labelclick-1].setStyleSheet('#DayLabel%d{border-image:url(%s)}' % (self.labelclick,self.TimeLabels_clicked_path[self.labelclick-1])) def setLabelClick(self, time_n): self.TimeLabels[self.labelclick-1].setStyleSheet( '#DayLabel%d{border-image:url(%s)}' % (self.labelclick, self.TimeLabels_path[self.labelclick-1])) self.TimeLabels[time_n].setStyleSheet('#DayLabel%d{border-image:url(%s)}' % (time_n+1,self.TimeLabels_clicked_path[time_n])) def setDaytext(self): for animes in self.weekanime: if animes['day_of_week'] == self.labelclick: date = animes['date'] day_of_week = self.labelclick self.animelist.clear() for anime in animes['seasons']: item_text = '' if anime['delay'] == 1: item_text += anime['pub_time'] + ' ' + anime['delay_index'] + ' ' + anime['delay_reason'] + '\n' + anime['title'] else: item_text += anime['pub_time'] + ' ' + anime['pub_index'] + '\n' + anime['title'] self.animelist.addItem(item_text) break week_day = ['周一','周二','周三','周四','周五','周六','周日'] daytext = date + ' ' + week_day[day_of_week - 1] self.daylabel.setText(daytext) def GetDetail(self,title): dbsql = AnimeData() infos = dbsql.SqliteInfoSearch({'title':title}) resinfo = [] if infos: for info in infos: resinfo.append(info[0]) resinfo.append(info[1]) resinfo.append(info[2]) resinfo.append(info[3]) resinfo.append(info[4]) resinfo.append(info[5]) resinfo.append(info[6]) resinfo.append(info[7]) return resinfo def DelDetail(self): self.detail.animetitle.setParent(None) self.detail.animeintro.setParent(None) self.detail.animetags.setParent(None) self.detail.animeorder.setParent(None) self.detail.animeindexshow.setParent(None) self.detail.animeindexshowtext.setParent(None) self.detail.animetagstext.setParent(None) self.detail.animeordertext.setParent(None) self.detail.animetitletext.setParent(None) self.detail.animetagstext.setParent(None) self.detail.pic_label.setParent(None) def DetailBt(self): if self.detail_show == False: title = self.animelist.currentItem().text().split('\n')[1] info = self.GetDetail(title) self.detail.setInfo(info) self.index = self.animelist.currentIndex() self.detail.show() self.detail_show = True elif self.detail_show == True and self.index != self.animelist.currentIndex(): self.detail.close() self.DelDetail() title = self.animelist.currentItem().text().split('\n')[1] info = self.GetDetail(title) self.index = self.animelist.currentIndex() self.detail.setInfo(info) self.detail.show() else: self.detail.close() self.DelDetail() self.index = -1 self.detail_show = False
class Demo(QWidget): # 1 def __init__(self): super(Demo, self).__init__() self.stack1 = QWidget() self.stack2 = QWidget() self.stack3 = QTextEdit() self.stack1_init() self.stack2_init() self.stacked_widget = QStackedWidget(self) # 2 self.stacked_widget.addWidget(self.stack1) self.stacked_widget.addWidget(self.stack2) self.stacked_widget.addWidget(self.stack3) self.stacked_widget.currentChanged.connect( lambda: print(self.stacked_widget.currentIndex())) self.list_widget = QListWidget(self) # 3 self.list_widget.addItem('Basic Info') self.list_widget.addItem('Contact Info') self.list_widget.addItem('More Info') self.list_widget.clicked.connect(self.change_func) self.h_layout = QHBoxLayout() self.h_layout.addWidget(self.list_widget) self.h_layout.addWidget(self.stacked_widget) self.setLayout(self.h_layout) def stack1_init(self): name_label = QLabel('Name:', self.stack1) gender_label = QLabel('Gender:', self.stack1) bd_label = QLabel('Birth Date:', self.stack1) name_line = QLineEdit(self.stack1) items = ['Please choose your gender', 'Female', 'Male'] gender_combo = QComboBox(self.stack1) gender_combo.addItems(items) bd_dateedit = QDateEdit(self.stack1) g_layout = QGridLayout() g_layout.addWidget(name_label, 0, 0, 1, 1) g_layout.addWidget(name_line, 0, 1, 1, 1) g_layout.addWidget(gender_label, 2, 0, 1, 1) g_layout.addWidget(gender_combo, 2, 1, 1, 1) g_layout.addWidget(bd_label, 3, 0, 1, 1) g_layout.addWidget(bd_dateedit, 3, 1, 1, 1) self.stack1.setLayout(g_layout) def stack2_init(self): tel_label = QLabel('Tel:', self.stack2) mobile_label = QLabel('Mobile:', self.stack2) add_label = QLabel('Address:', self.stack2) tel_line = QLineEdit(self.stack2) mobile_line = QLineEdit(self.stack2) add_line = QLineEdit(self.stack2) g_layout = QGridLayout() g_layout.addWidget(tel_label, 0, 0, 1, 1) g_layout.addWidget(tel_line, 0, 1, 1, 1) g_layout.addWidget(mobile_label, 1, 0, 1, 1) g_layout.addWidget(mobile_line, 1, 1, 1, 1) g_layout.addWidget(add_label, 2, 0, 1, 1) g_layout.addWidget(add_line, 2, 1, 1, 1) self.stack2.setLayout(g_layout) def change_func(self): self.stacked_widget.setCurrentIndex( self.list_widget.currentIndex().row())
class SessionViewer(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setMinimumSize(1100, 400) main_layout = QHBoxLayout() main_layout.setSpacing(5) self.setLayout(main_layout) list_column = QVBoxLayout() main_layout.addLayout(list_column, stretch=1) refresh_button = QPushButton('🔄 Refresh') refresh_button.setFont(cn.EMOJI_FONT) refresh_button.clicked.connect(self.refresh_list) list_column.addWidget(refresh_button) self.session_list = QListWidget() self.session_list.currentItemChanged.connect(self.show_session) list_column.addWidget(self.session_list) self.refresh_list() self.info_column = QVBoxLayout() main_layout.addLayout(self.info_column, stretch=1) self.info_column.addWidget(QLabel('Selected session info:')) self.session_info_table = QTableWidget() self.session_info_table.setColumnCount(2) self.session_info_table.horizontalHeader().setStretchLastSection(True) self.info_column.addWidget(self.session_info_table) self.info_column.addWidget(QLabel('Contained gestures:')) self.gesture_list = QListWidget() self.gesture_list.currentItemChanged.connect(self.show_gesture) self.info_column.addWidget(self.gesture_list) self.data_column = QVBoxLayout() self.data_column.setContentsMargins(0, 0, 0, 0) main_layout.addLayout(VerticalScrollableExtension( self.data_column, direction=QBoxLayout.TopToBottom, scrolled_spacing=10), stretch=3) self.current_session_data = None self.current_gesture_names = None @staticmethod def load_session_data(session_name): file = f'data/gestures/{session_name}' with open(file, 'rb') as f: data = pickle.load(f) gesture_keys = [ item for item in data if type(data[item]) == np.ndarray ] return data, sorted(gesture_keys, key=lambda x: str(x).zfill(5)) @staticmethod def load_session_list(): return sorted( filter( lambda x: x.startswith('s-') and x.count(cn.FILE_NAME_SEPARATOR ) == 2, os.listdir(cn.DATA_FOLDER))) def refresh_list(self): self.session_list.clear() self.session_list.addItems(SessionViewer.load_session_list()) def cleanup_shown_session(self): self.session_info_table.clear() self.gesture_list.clearSelection() self.gesture_list.clear() for i in range(self.data_column.count()): self.data_column.itemAt(i).widget().plot_data(None) def show_session(self, current_item): if not current_item: return self.cleanup_shown_session() session_name = current_item.text() self.current_session_data, self.current_gesture_names = SessionViewer.load_session_data( session_name) self.session_info_table.setRowCount(2 + len(self.current_session_data) - len(self.current_gesture_names)) row = 0 for info in self.current_session_data: if info in self.current_gesture_names: continue self.session_info_table.setItem(row, 0, QTableWidgetItem(info)) self.session_info_table.setItem( row, 1, QTableWidgetItem(str(self.current_session_data[info]))) row += 1 self.session_info_table.setItem(row, 0, QTableWidgetItem('Gestures')) self.session_info_table.setItem( row, 1, QTableWidgetItem(str(len(self.current_gesture_names)))) self.session_info_table.setItem(row + 1, 0, QTableWidgetItem('Instances')) self.session_info_table.setItem( row + 1, 1, QTableWidgetItem( str( sum( map(lambda name: len(self.current_session_data[name]), self.current_gesture_names))))) self.gesture_list.addItems( map( lambda name: f'{name} ({len(self.current_session_data[name])} inst.)', self.current_gesture_names)) def show_gesture(self): current_gesture_data = self.current_session_data[ self.current_gesture_names[self.gesture_list.currentIndex().row()]] new_count = len(current_gesture_data) old_count = self.data_column.count() for i in range(old_count, new_count): self.data_column.addWidget(StaticSignalWidget()) for i in range(new_count, old_count): self.data_column.itemAt(i).widget().plot_data(None) for i, instance in enumerate(current_gesture_data): # We use a function here, to create a temporary scope for index & data w = self.data_column.itemAt(i).widget() w.plot_data(instance)
class MainWindowApp(QMainWindow, QWidget): def __init__(self, parent=None): # 执行当前函数的初始化函数 super(MainWindowApp, self).__init__(parent) self.init_name() # 设置位置,以及显示大小 self.init_size_position() # 状态栏 self.statusbar = StatusBar() self.setStatusBar(self.statusbar.statusbar) # 设置整体容器的布局为水平布局 self.main_layout = QHBoxLayout() # 设置容器的外边距 self.main_layout.setContentsMargins(0, 0, 0, 0) self.init_sidebar() """ 右侧面--堆栈式组件 """ self.right_widget = QStackedWidget() # ***************************** 创建项目管理面板实例 self.manager_panel = Manager() self.manager_panel = Manager() # 创建线程 self.manager_panel.signal.connect(self.updateStatusBarStatus) # 连接信号 self.manager_panel.start() # 开始线程 # 右侧面板中添加项目管理组件, !!!!! 注意, 一定要放置在监听start的后面, 否则不能起作用 self.right_widget.addWidget(self.manager_panel.Qwidgetlayout) # *************************** 关于我们 面板 self.aboutmepanel = AboutMePanel() self.right_widget.addWidget(self.aboutmepanel.main) # -------------------------------- 整体布局容器中添加右侧面板 self.main_layout.addWidget(self.right_widget) # ------------------------------- 整体的布局容器 self.main_frame = QWidget() self.main_frame.setLayout(self.main_layout) self.setCentralWidget(self.main_frame) # 界面创建函数 self._setup_left_panel() def init_name(self): # 设置窗口名称 self.setObjectName('智能实验报告生成工具') # 设置窗口图标 self.setWindowIcon(QIcon('favicon.ico')) # 设置窗口显示的名称 self.setWindowTitle('智能实验报告生成工具') def init_size_position(self): """ 获取电脑的尺寸,实现自适应宽度, 高度,以及位置 :return: """ self.available_geometry = QDesktopWidget().availableGeometry() # 设置窗口的宽度为电脑屏幕的0.45 倍 init_width = self.available_geometry.width() * 0.8 # 设置窗口的高度为电脑屏幕的0.45 倍 init_height = self.available_geometry.height() * 0.8 # 设置宽度与高度 self.resize(int(init_width), int(init_height)) def init_sidebar(self): """ 设置侧边栏 :return: """ with open('style/QListWidgetQss.qss', 'r') as f: list_style = f.read() # 创建列表组件 self.left_widget = QListWidget() # 设置列表组件的css样式 self.left_widget.setStyleSheet(list_style) self.left_widget.setFocus() # 将侧边栏组件添加到容器中 self.main_layout.addWidget(self.left_widget) def leftsidebar_change(self): """ 左边侧边栏点击后响应事件 :return: """ # 获取当前点击的左侧侧边栏的序号 i = self.left_widget.currentIndex().row() if i == 0: pass elif i == 1: # 当为采集结果显示面板时, 先清空面板,然后写入数据 self.result_panel.clearTable() self.result_panel.selectionchange(0) elif i == 2: self.update() else: pass # # 更新ceche的配置参数 # self.manager_panel.update_cache() # 右侧的堆叠面板的设置为第i个显示 self.right_widget.setCurrentIndex(i) def _setup_left_panel(self): """ 构建左侧侧边栏QList面板 :return: """ # 去掉边框 self.left_widget.setFrameShape(QListWidget.NoFrame) self.left_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.left_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) nav_list = ['信息录入', '关于我们'] nav_list_icons = ["collection.png", "aboutme.png"] for nav, icon_name in zip(nav_list, nav_list_icons): # 左侧选项的添加 self.item = QListWidgetItem(QIcon("./img/{}".format(icon_name)), nav, self.left_widget) self.item.setSizeHint(QSize(20, 60)) # 居中显示 # self.item.setTextAlignment(Qt.AlignCenter) self.left_widget.setIconSize(QSize(22, 22)) self.left_widget.itemClicked.connect(self.leftsidebar_change) def updateStatusBarStatus(self, text): """ 更新状态栏 :param text: 状态栏上显示的txt :return: """ self.statusbar.statusbar.showMessage(text) self.statusbar.statusbar.update()