def _create_model(parent, serialized_bookmarks): result = QStandardItemModel(0, 1, parent) last_folder_item = None for entry in serialized_bookmarks: if len(entry) == 1: last_folder_item = _create_folder_item(entry[0]) result.appendRow(last_folder_item) else: url = QUrl.fromUserInput(entry[0]) title = entry[1] icon = QIcon(entry[2]) if len(entry) > 2 and entry[2] else None last_folder_item.appendRow(_create_item(url, title, icon)) return result
def create_combo_box_items(self): model = QStandardItemModel() self.ui.combo_classes.setModel(model) self.ui.combo_functions.setModel(model) for k, v in self.data.items(): cls = QStandardItem(k) model.appendRow(cls) for value in v: func = QStandardItem(value) cls.appendRow(func) def update_combo_box(index): ind = model.index(index, 0, self.ui.combo_classes.rootModelIndex()) self.ui.combo_functions.setRootModelIndex(ind) self.ui.combo_functions.show() self.ui.combo_functions.setCurrentIndex(0) self.ui.config_label.setText('') self.ui.combo_classes.currentIndexChanged.connect(update_combo_box)
def create_itemview_tabwidget(self): result = QTabWidget() init_widget(result, "bottomLeftTabWidget") result.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored) tree_view = QTreeView() init_widget(tree_view, "treeView") filesystem_model = QFileSystemModel(tree_view) filesystem_model.setRootPath(QDir.rootPath()) tree_view.setModel(filesystem_model) table_widget = QTableWidget() init_widget(table_widget, "tableWidget") table_widget.setRowCount(10) table_widget.setColumnCount(10) list_model = QStandardItemModel(0, 1, result) list_model.appendRow(QStandardItem(QIcon(DIR_OPEN_ICON), "Directory")) list_model.appendRow(QStandardItem(QIcon(COMPUTER_ICON), "Computer")) list_view = QListView() init_widget(list_view, "listView") list_view.setModel(list_model) icon_mode_listview = QListView() init_widget(icon_mode_listview, "iconModeListView") icon_mode_listview.setViewMode(QListView.IconMode) icon_mode_listview.setModel(list_model) result.addTab(embed_into_hbox_layout(tree_view), "Tree View") result.addTab(embed_into_hbox_layout(table_widget), "Table") result.addTab(embed_into_hbox_layout(list_view), "List") result.addTab(embed_into_hbox_layout(icon_mode_listview), "Icon Mode List") return result
class Table(QWidget): def __init__(self, arg=None): super(Table, self).__init__(arg) # 设置窗体的标题和初始大小 self.setWindowTitle("QTableView表格视图控件的例子") self.resize(500, 300) # 准备数据模型,设置数据层次结构为5行4列 self.model = QStandardItemModel(5, 4) # 设置数据栏名称 self.model.setHorizontalHeaderLabels(['标题1', '标题2', '标题3', '标题4']) for row in range(5): for column in range(4): item = QStandardItem("row %s, column %s" % (row, column)) self.model.setItem(row, column, item) # 实例化表格视图,设置模型为自定义的模型 self.tableView = QTableView() self.tableView.setModel(self.model) # 下面代码让表格 100% 的填满窗口 self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 下面代码让表格禁止编辑 self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) # 下面代码让表格设置选中背景色 self.tableView.setStyleSheet("selection-background-color:lightblue;") # 下面代码要限定只能选择整行 # self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) # 设置只能选中整行 # self.tableView.setSelectionMode(QAbstractItemView.SingleSelection) # 设置只能选中一行 # 下面代码可以选中表格的多行 self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) # 设置只能选中整行 self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection) # 设置只能选中多行 # 下面代码可以打印表格的1行2列数据 data = self.tableView.model().index(1, 2).data() print(data) # 下面代码去掉左边表格的行号 # headerView = self.tableView.verticalHeader() # headerView.setHidden(True) # 局部布局 vboxLayout = QVBoxLayout() vboxLayout.addWidget(self.tableView) self.add_btn = QPushButton("添加记录") # 连接信号槽,点击按钮 add_btn 绑定槽事件 self.add_btn.clicked.connect(self.add_records_btn_click) self.del_btn = QPushButton("删除多行记录") # 连接信号槽,点击按钮 del_btn 绑定槽事件 self.del_btn.clicked.connect(self.del_records_btn_click) # 局部布局 hboxLayout = QHBoxLayout() hboxLayout.addWidget(self.add_btn) hboxLayout.addWidget(self.del_btn) # 全局布局 wl = QVBoxLayout(self) wl.addLayout(vboxLayout) wl.addLayout(hboxLayout) # 点击删除按钮响应方法, 删除选中的单行数据 def del_record_btn_click(self): # 第一种方法: 删除单行数据 indices = self.tableView.selectionModel().selectedRows() for index in sorted(indices): self.model.removeRow(index.row()) # 第二种方法: 删除单行数据 # index = self.tableView.currentIndex() # 取得当前选中行的index # if -1 == index.row(): # return # self.model.removeRow(index.row()) # 通过index的row()操作得到行数进行删除 # 点击删除按钮响应方法, 删除选中的多行数据 def del_records_btn_click(self): # 第一种方法:删除多行数据 index_list = [] for model_index in self.tableView.selectionModel().selectedRows(): index = QtCore.QPersistentModelIndex(model_index) index_list.append(index) if index_list: for index in index_list: self.model.removeRow(index.row()) else: MessageBox = QMessageBox() MessageBox.information(self.tableView, "标题", "没有选中表格中要删除的行") # 第二种方法:删除多行数据 # indexs = self.tableView.selectionModel().selectedRows() # temp_list = [] # 创建一个空队列用于存放需要删除的行号 # for index in indexs: # temp_list.append(index.row()) # 队列中保存需要删除的行号 # temp_list.sort(key=int, reverse=True) # 用sort方法将队列进行降序排列 # print(temp_list) # # if temp_list: # for i in temp_list: # 按照队列删除对应的行 # self.model.removeRow(i) # else: # MessageBox = QMessageBox() # MessageBox.information(self.tableView, "标题", "没有选中表格中要删除的行") # 点击添加按钮相应方法,添加数据 def add_records_btn_click(self): self.model.appendRow([ QStandardItem("row %s, column %s" % (5, 0)), QStandardItem("row %s, column %s" % (6, 1)), QStandardItem("row %s, column %s" % (7, 2)), QStandardItem("row %s, column %s" % (8, 3)), ])
class KeyMgrDialog(QDialog, UIKeyMgrDialog): def __init__(self, parent=None, model=True) -> None: super().__init__() self.parent = parent self.setupUi(self) self.setWindowTitle('密钥管理') self.setModal(model) self.key_list = key_cache.get_key_list() self.list_model = None self.setup_key_list(self.key_list) self.tbCreate.clicked.connect(self.create_key_action) self.tbCreate.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.tbCreate.setIcon( qta.icon('ei.file-new', color=icon_color['color'], color_active=icon_color['active'])) self.tbAdd.clicked.connect(self.add_key_action) self.tbAdd.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.tbAdd.setIcon( qta.icon('fa.plus', color=icon_color['color'], color_active=icon_color['active'])) self.tbRemove.clicked.connect(self.remove_key_action) self.tbRemove.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.tbRemove.setIcon( qta.icon('fa.minus', color=icon_color['color'], color_active=icon_color['active'])) add_key_invalidate_callback(self.key_invalidate) def setup_key_list(self, key_list): self.keyListView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.list_model = QStandardItemModel(self.keyListView) for key in key_list: item = self.make_item(key) self.list_model.appendRow(item) self.keyListView.setModel(self.list_model) self.keyListView.setContextMenuPolicy(Qt.CustomContextMenu) self.keyListView.customContextMenuRequested[QPoint].connect( self.context_menu) def key_invalidate(self, invalidate_key: Key): for i in range(self.list_model.rowCount()): key = self.list_model.item(i).data() if key.id == invalidate_key.id: #self.list_model.item(i).setIcon(qta.icon('fa.warning', color=icon_color)) self.update_key_icon(self.list_model.item(i)) return def update_key_icon(self, item): key = item.data() if key.timeout: item.setIcon( qta.icon('fa.warning', scale_factor=0.8, color=icon_color['color'], color_active=icon_color['active'])) elif key_cache.is_cur_key(key): item.setIcon( qta.icon('fa.check', scale_factor=0.8, color=icon_color['color'], color_active=icon_color['active'])) else: item.setIcon( QIcon( qta.icon('fa5s.key', scale_factor=0.7, color=icon_color['color'], color_active=icon_color['active']))) def make_item(self, key): item = QStandardItem(key.name) item.setData(key) #item.setIcon(QIcon(qta.icon('fa5s.key', color=icon_color))) self.update_key_icon(item) return item def get_selected_item(self): selected = self.keyListView.selectedIndexes() if not selected: return index = selected[0] item = self.list_model.item(index.row()) return item def context_menu(self, point): selected = self.keyListView.selectedIndexes() if not selected: return index = selected[0] item = self.list_model.item(index.row()) key = item.data() pop_menu = QMenu() _set_default_key_action = pop_menu.addAction( qta.icon('fa.check', color=icon_color['color'], color_active=icon_color['active']), '设为默认') if key_cache.is_cur_key(key) or key.timeout: _set_default_key_action.setEnabled(False) pop_menu.addSeparator() _encrypt_files_action = pop_menu.addAction( qta.icon('ei.lock', color=icon_color['color'], color_active=icon_color['active']), "加密文件") _decrypt_files_action = pop_menu.addAction( qta.icon('ei.unlock', color=icon_color['color'], color_active=icon_color['active']), "解密文件") pop_menu.addSeparator() _reload_key_action = pop_menu.addAction( qta.icon('fa.refresh', color=icon_color['color'], color_active=icon_color['active']), "重新加载") _reload_key_action.setEnabled(key.timeout) selected_action = pop_menu.exec_(QCursor.pos()) if selected_action == _encrypt_files_action: self.encrypt_files_action() elif selected_action == _set_default_key_action: self.set_default_key_action() elif selected_action == _reload_key_action: self.reload_key_action() elif selected_action == _decrypt_files_action: self.decrypt_files_action() def set_default_key_action(self, item=None): item = self.get_selected_item() self._set_default_key(item) for i in range(self.list_model.rowCount()): self.update_key_icon(self.list_model.item(i)) #self.list_model.item(i).setIcon(qta.icon('fa5s.key', color=icon_color)) def create_key_action(self): dialog = KeyCreateDialog(parent=self) dialog.activateWindow() dialog.exec() key = dialog.key if key is None: return item = self.make_item(key) self._add_key(item, key) def _add_key(self, item, key): self.list_model.appendRow(item) key_cache.add_key(key) def _remove_key(self, index): self.list_model.removeRow(index) key_cache.remove_key(index) def _set_default_key(self, item): key_cache.set_current_key(item.data()) self.update_key_icon(item) def add_key_action(self): file_name, _ = QFileDialog.getOpenFileName(self, '选择密钥文件') if len(file_name.strip()) == 0: return password = None if Key.need_password(file_name): ok_pressed = True while ok_pressed: password, ok_pressed = QInputDialog.getText( self, "需要密码", "输入密码:", QLineEdit.Password, "") if ok_pressed: illegal, msg = Key.is_password_illegal(password) if illegal: QMessageBox.information(self, '错误', msg) continue break else: return key = Key() try: key.load(file_name, password) except Exception as e: QMessageBox.critical(self, '错误', '不是有效的密钥文件<br/>' + str(e)) return row_len = self.list_model.rowCount() for i in range(0, row_len): item: QStandardItem = self.list_model.item(i, 0) k: Key = item.data() if k.id == key.id: QMessageBox.information(self, '信息', '相同的密钥已经加载') return item = self.make_item(key) self._add_key(item, key) return def remove_key_action(self): selected = self.keyListView.selectedIndexes() if not selected: return index = selected[0] self._remove_key(index.row()) QMessageBox.information(self, '信息', '密钥已经移除') def encrypt_files_action(self): item = self.get_selected_item() key = item.data() ef_dialog = EncryptFileDialog(self) ef_dialog.set_key(key) ef_dialog.exec() def decrypt_files_action(self): item = self.get_selected_item() key = item.data() ef_dialog = EncryptFileDialog( self, win_title='解密文件', before_process=is_encrypt_data, processor=decrypt_data, success_msg='解密完成', select_file_dlg_title='选择需要解密的文件', ) ef_dialog.set_key(key) ef_dialog.exec() def reload_key_action(self): item = self.get_selected_item() key: Key = item.data() password = None if Key.need_password(key.path): ok_pressed = True while ok_pressed: password, ok_pressed = QInputDialog.getText( self, "需要密码", "输入密码:", QLineEdit.Password, "") if ok_pressed: illegal, msg = Key.is_password_illegal(password) if illegal: QMessageBox.information(self, '错误', msg) continue break else: return try: key.load(key.path, password) except Exception as e: QMessageBox.critical(self, '错误', '不是有效的密钥文件<br/>' + str(e)) return self.update_key_icon(item)
class MainWindow(QMainWindow): def __init__(self, parent=None, flags=Qt.WindowFlags()): super(MainWindow, self).__init__(parent, flags) self.dayWidth = 70 self.ui = Ui_MainWindow() self.ui.setupUi(self) self.initModel() self.initActions() self.initItemDelegate() self.initGrid() leftView = self.ui.ganttView.leftView() leftView.setColumnHidden(1, True) leftView.setColumnHidden(2, True) leftView.setColumnHidden(3, True) leftView.setColumnHidden(4, True) leftView.setColumnHidden(5, True) leftView.header().setStretchLastSection(True) self.ui.ganttView.leftView().customContextMenuRequested.connect( self.showContextMenu) self.ui.ganttView.selectionModel().selectionChanged.connect( self.enableActions) self.ui.ganttView.graphicsView().clicked.connect(self.slotClicked) self.ui.ganttView.graphicsView().qrealClicked.connect( self.slotDoubleClicked) def initModel(self): self.model = QStandardItemModel(0, 6, self) self.model.setHeaderData(0, Qt.Horizontal, "Task") self.ui.ganttView.setModel(self.model) self.l = QWidget(self) self.l.setWindowTitle("Legend") self.l.show() ##self.l.setModel(self.model) self.constraintModel = ConstraintModel(self) self.ui.ganttView.setConstraintModel(self.constraintModel) def initActions(self): self.newEntryAction = QAction("New entry", self) self.newEntryAction.setShortcut(QKeySequence.New) self.newEntryAction.triggered.connect(self.addNewEntry) self.removeEntryAction = QAction("Remove entry", self) self.removeEntryAction.setShortcut(QKeySequence.Delete) self.removeEntryAction.triggered.connect(self.removeEntry) self.demoAction = QAction("Demo entry", self) self.demoAction.triggered.connect(self.addDemoEntry) self.printAction = QAction("Print Preview...", self) self.printAction.triggered.connect(self.printPreview) self.zoomInAction = QAction("Zoom In", self) self.zoomInAction.setShortcut(QKeySequence.ZoomIn) self.zoomInAction.triggered.connect(self.zoomIn) self.zoomOutAction = QAction("Zoom Out", self) self.zoomOutAction.setShortcut(QKeySequence.ZoomOut) self.zoomOutAction.triggered.connect(self.zoomOut) self.ui.ganttView.leftView().setContextMenuPolicy(Qt.CustomContextMenu) self.ui.ganttView.leftView().addAction(self.newEntryAction) self.ui.ganttView.leftView().addAction(self.removeEntryAction) menuBar = QMenuBar(self) self.setMenuBar(menuBar) entryMenu = menuBar.addMenu("Entry") entryMenu.addAction(self.newEntryAction) entryMenu.addAction(self.removeEntryAction) entryMenu.addSeparator() entryMenu.addAction(self.demoAction) entryMenu.addSeparator() entryMenu.addAction(self.printAction) zoomMenu = menuBar.addMenu("Zoom") zoomMenu.addAction(self.zoomInAction) zoomMenu.addAction(self.zoomOutAction) ##self.enableActions(QItemSelection()) def initItemDelegate(self): delegate = EntryDelegate(self.constraintModel, self) self.ui.ganttView.leftView().setItemDelegate(delegate) def initGrid(self): self.grid = DateTimeGrid() self.grid.setDayWidth(self.dayWidth) self.ui.ganttView.setGrid(self.grid) def showContextMenu(self, pos): if not self.ui.ganttView.leftView().indexAt(pos).isValid(): self.ui.ganttView.selectionModel().clearSelection() menu = QMenu(self.ui.ganttView.leftView()) menu.addAction(self.newEntryAction) menu.addAction(self.removeEntryAction) menu.exec_(self.ui.ganttView.leftView().viewport().mapToGlobal(pos)) def enableActions(self, selected): if len(selected.indexes()) == 0: self.newEntryAction.setEnabled(True) self.removeEntryAction.setEnabled(False) return selectedIndex = selected.indexes()[0] dataType = self.model.data(self.model.index(selectedIndex.row(), 1)) if dataType in [KDGantt.TypeEvent, KDGantt.TypeTask]: self.newEntryAction.setEnabled(False) self.removeEntryAction.setEnabled(True) return self.newEntryAction.setEnabled(True) self.removeEntryAction.setEnabled(True) def addNewEntry(self): dialog = EntryDialog(self.model) dialog.setWindowTitle("New Entry") if dialog.exec_() == QDialog.Rejected: dialog = None return selectedIndexes = self.ui.ganttView.selectionModel().selectedIndexes() if len(selectedIndexes) > 0: parent = selectedIndexes[0] else: parent = QModelIndex() if not self.model.insertRow(self.model.rowCount(parent), parent): return row = self.model.rowCount(parent) - 1 if row == 0 and parent.isValid(): self.model.insertColumns(self.model.columnCount(paren), 5, parent) self.model.setData(self.model.index(row, 0, parent), dialog.name()) self.model.setData(self.model.index(row, 1, parent), dialog.type()) if dialog.type() != KDGantt.TypeSummary: self.model.setData(self.model.index(row, 2, parent), dialog.startDate(), KDGantt.StartTimeRole) self.model.setData(self.model.index(row, 3, parent), dialog.endDate(), KDGantt.EndTimeRole) self.model.setData(self.model.index(row, 4, parent), dialog.completion()) self.model.setData(self.model.index(row, 5, parent), dialog.legend()) self.addConstraint(dialog.depends(), self.model.index(row, 0, parent)) self.setReadOnly(self.model.index(row, 0, parent), dialog.readOnly()) dialog = None def setReadOnly(self, index, readOnly): row = index.row() parent = index.parent() for column in range(0, 5): item = self.model.itemFromIndex( self.model.index(row, column, parent)) flags = None if readOnly: flags = item.flags() & ~Qt.ItemIsEditable else: flags = item.flags() | Qt.ItemIsEditable item.setFlags(flags) def addConstraint(self, index1, index2): if not index1.isValid() or not index2.isValid(): return c = Constraint(index1, index2) self.ui.ganttView.constraintModel().addConstraint(c) def addConstraintFromItem(self, item1, item2): self.addConstraint(self.model.indexFromItem(item1), self.model.indexFromItem(item2)) def removeEntry(self): selectedIndexes = self.ui.ganttView.selectionModel().selectedIndexes() if len(selectedIndexes) > 0: index = selectedIndexes[0] else: index = QModelIndex() if not index.isValid(): return self.model.removeRow(index.row(), index.parent()) def addDemoEntry(self): softwareRelease = MyStandardItem("Software Release") codeFreeze = MyStandardItem("Code Freeze") codeFreeze.setData(KDGantt.TextPositionRole, StyleOptionGanttItem.Right) packaging = MyStandardItem("Packaging") upload = MyStandardItem("Upload") testing = MyStandardItem("Testing") updateDocumentation = MyStandardItem("Update Documentation") now = QDateTime.currentDateTime() softwareRelease.appendRow([ codeFreeze, MyStandardItem(KDGantt.TypeEvent), MyStandardItem(now, KDGantt.StartTimeRole) ]) softwareRelease.appendRow([ packaging, MyStandardItem(KDGantt.TypeTask), MyStandardItem(now.addDays(5), KDGantt.StartTimeRole), MyStandardItem(now.addDays(10), KDGantt.EndTimeRole) ]) softwareRelease.appendRow([ upload, MyStandardItem(KDGantt.TypeTask), MyStandardItem( now.addDays(10).addSecs(2 * 60 * 60), KDGantt.StartTimeRole), MyStandardItem(now.addDays(11), KDGantt.EndTimeRole) ]) softwareRelease.appendRow([ testing, MyStandardItem(KDGantt.TypeTask), MyStandardItem(now.addSecs(3 * 60 * 60), KDGantt.StartTimeRole), MyStandardItem(now.addDays(5), KDGantt.EndTimeRole) ]) softwareRelease.appendRow([ updateDocumentation, MyStandardItem(KDGantt.TypeTask), MyStandardItem(now.addSecs(3 * 60 * 60), KDGantt.StartTimeRole), MyStandardItem(now.addDays(3), KDGantt.EndTimeRole) ]) self.model.appendRow( [softwareRelease, MyStandardItem(KDGantt.TypeSummary)]) self.addConstraintFromItem(codeFreeze, packaging) self.addConstraintFromItem(codeFreeze, testing) self.addConstraintFromItem(codeFreeze, updateDocumentation) self.addConstraintFromItem(packaging, upload) self.addConstraintFromItem(testing, packaging) self.addConstraintFromItem(updateDocumentation, packaging) def zoomIn(self): self.dayWidth += 10 if self.dayWidth > 400: self.grid.setScale(DateTimeGrid.ScaleHour) self.grid.setDayWidth(self.dayWidth) def zoomOut(self): self.dayWidth -= 10 if self.dayWidth < 10: self.dayWidth = 10 if self.dayWidth <= 400: self.grid.setScale(DateTimeGrid.ScaleDay) self.grid.setDayWidth(self.dayWidth) def printPreview(self): preview = QLabel(self, Qt.Window) preview.setAttribute(Qt.WA_DeleteOnClose) preview.setScaledContents(True) preview.setWindowTitle("Print Preview") pix = QPixmap(1000, 300) pix.fill(Qt.white) p = QPainter(pix) p.setRenderHints(QPainter.Antialiasing) self.ui.ganttView.print_(p, pix.rect()) preview.setPixmap(pix) preview.show() def slotClicked(self, index): self.statusBar().showMessage( "(%d,%d,_,%s) clicked" % (index.row(), index.column(), index.model())) def slotDoubleClicked(self, index): self.statusBar().showMessage( "(%d,%d,_,%s) qreal clicked" % (index.row(), index.column(), index.model()))
class XDFStreamsDialog(QDialog): def __init__(self, parent, rows, selected=None, disabled=None): super().__init__(parent) self.setWindowTitle("Select XDF Stream") self.model = QStandardItemModel() self.model.setHorizontalHeaderLabels( ["ID", "Name", "Type", "Channels", "Format", "Sampling Rate"]) for index, stream in enumerate(rows): items = [] for item in stream: tmp = QStandardItem() tmp.setData(item, Qt.DisplayRole) items.append(tmp) for item in items: item.setEditable(False) if disabled is not None and index in disabled: item.setFlags(Qt.NoItemFlags) self.model.appendRow(items) self.view = QTableView() self.view.setModel(self.model) self.view.verticalHeader().setVisible(False) self.view.horizontalHeader().setStretchLastSection(True) self.view.setShowGrid(False) self.view.setSelectionMode(QAbstractItemView.SingleSelection) self.view.setSelectionBehavior(QAbstractItemView.SelectRows) if selected is not None: self.view.selectRow(selected) self.view.setSortingEnabled(True) self.view.sortByColumn(0, Qt.AscendingOrder) vbox = QVBoxLayout(self) vbox.addWidget(self.view) hbox = QHBoxLayout() self._effective_srate = QCheckBox("Use effective sampling rate") self._effective_srate.setChecked(True) hbox.addWidget(self._effective_srate) self._prefix_markers = QCheckBox("Prefix markers with stream ID") self._prefix_markers.setChecked(False) if not disabled: self._prefix_markers.setEnabled(False) hbox.addWidget(self._prefix_markers) vbox.addLayout(hbox) self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) vbox.addWidget(self.buttonbox) self.buttonbox.accepted.connect(self.accept) self.buttonbox.rejected.connect(self.reject) self.resize(775, 650) self.view.setColumnWidth(0, 90) self.view.setColumnWidth(1, 200) self.view.setColumnWidth(2, 140) @property def effective_srate(self): return self._effective_srate.isChecked() @property def prefix_markers(self): return self._prefix_markers.isChecked()
class MyWidget(QWidget): def __init__(self): super(MyWidget, self).__init__(None) self.view = View() self.grid = DateTimeGrid() self.slider = QSlider() self.model = QStandardItemModel() self.cmodel = ConstraintModel() for h in range(0, 19): topitem = MyStandardItem("Top Item " + str(h)) for i in range(0, 19): item = MyStandardItem("Multi Item " + str(i)) for j in range(0, 29, 3): item.appendRow([ MyStandardItem("Item " + str(j)), MyStandardItem(KDGantt.TypeTask), MyStandardItem(QDateTime.currentDateTime().addDays(j), KDGantt.StartTimeRole), MyStandardItem( QDateTime.currentDateTime().addDays(j + 1 + i / 7), KDGantt.EndTimeRole), MyStandardItem(50) ]) item.appendRow([ MyStandardItem("Event"), MyStandardItem(KDGantt.TypeEvent), MyStandardItem(QDateTime.currentDateTime(), KDGantt.StartTimeRole), MyStandardItem(QDateTime(), KDGantt.EndTimeRole), MyStandardItem("") ]) topitem.appendRow([ item, MyStandardItem(KDGantt.TypeMulti), MyStandardItem(""), MyStandardItem(""), MyStandardItem("") ]) self.model.appendRow([ topitem, MyStandardItem(KDGantt.TypeMulti), MyStandardItem(""), MyStandardItem(""), MyStandardItem("") ]) self.model.appendRow([MyStandardItem("No data")]) ##cmodel.addConstraint( KDGantt::Constraint( proxyModel.index( 0, 3 ), proxyModel.index( 10, 3 ) ) ); ##cmodel.addConstraint( KDGantt::Constraint( proxyModel.index( 10, 3 ), proxyModel.index( 5, 3 ) ) ); pidx = self.model.index(0, 0) pidx = self.model.index(0, 0, pidx) self.cmodel.addConstraint( Constraint(self.model.index(0, 0, pidx), self.model.index(1, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(0, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(10, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(3, 0, pidx), self.model.index(5, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(7, 0, pidx), self.model.index(4, 0, pidx))) self.slider.setOrientation(Qt.Horizontal) self.slider.setRange(1, 10000) self.slider.setValue(100) l = QVBoxLayout(self) l.addWidget(self.view) l.addWidget(self.slider) self.grid.setStartDateTime(QDateTime.currentDateTime().addDays(-3)) self.grid.setDayWidth(100) ##grid.setNoInformationBrush( Qt::NoBrush ); self.view.setGrid(self.grid) self.view.setModel(self.model) ##view.setConstraintModel( &cmodel ); self.slider.valueChanged.connect(self.slotZoom) pb1 = QPushButton("Print Preview...", self) pb2 = QPushButton("Print...", self) l.addWidget(pb1) l.addWidget(pb2) pb1.clicked.connect(self.slotPrintPreview) pb2.clicked.connect(self.slotPrint) gv = self.view.graphicsView() gv.setHeaderContextMenuPolicy(Qt.CustomContextMenu) gv.headerContextMenuRequested.connect(self.slotHeaderMenu) def slotZoom(self, z): self.grid.setDayWidth(z) def slotPrintPreview(self): pix = QPixmap(1000, 200) pix.fill(Qt.white) painter = QPainter(pix) view.print(painter, pix.rect()) painter.end() label = QLabel(this) label.setPixmap(pix) label.show() def slotPrint(self): printer = QPrinter(QPrinter.HighResolution) pd = QPrintDialog(printer, self) if pd.exec_() == QDialog.Accepted: r = self.view.graphicsView().mapToScene( self.view.graphicsView().viewport().rect()).boundingRect() self.view.print(printer, r.left(), r.right()) def slotHeaderMenu(self, pt): menu = QMenu() menu.addAction("This") menu.addAction("is") menu.addAction("just") menu.addAction("a") menu.addAction("test") menu.exec_(pt)
class XDFChunksDialog(QDialog): def __init__(self, parent, chunks, fname): super().__init__(parent) self.setWindowTitle(f"XDF Chunks ({fname})") self.chunks = chunks TAGS = { 1: "FileHeader", 2: "StreamHeader", 3: "Samples", 4: "ClockOffset", 5: "Boundary", 6: "StreamFooter" } self.model = QStandardItemModel() self.model.setHorizontalHeaderLabels( ["#", "Bytes", "Tag", "Stream ID"]) for i, chunk in enumerate(chunks, start=1): row = [] row.append(_add_item(i)) row.append(_add_item(chunk["nbytes"])) row.append(_add_item(f"{chunk['tag']} ({TAGS[chunk['tag']]})")) row.append(_add_item(chunk.get("stream_id", ""))) self.model.appendRow(row) self.view = QTableView() self.view.setModel(self.model) self.view.verticalHeader().setVisible(False) self.view.horizontalHeader().setStretchLastSection(True) self.view.setShowGrid(False) self.view.setSelectionMode(QAbstractItemView.SingleSelection) self.view.setSelectionBehavior(QAbstractItemView.SelectRows) self.view.setSortingEnabled(True) self.view.sortByColumn(0, Qt.AscendingOrder) self.view.setEditTriggers(QTableView.NoEditTriggers) self.view.setFixedWidth(450) self.details = QPlainTextEdit("") self.details.setFixedWidth(450) self.details.setReadOnly(True) self.details.setTabStopDistance(30) font = QFont() font.setFamily("monospace") font.setStyleHint(QFont.Monospace) self.details.setFont(font) self.details.setLineWrapMode(QPlainTextEdit.NoWrap) hbox = QHBoxLayout() hbox.addWidget(self.view) hbox.addWidget(self.details) vbox = QVBoxLayout(self) vbox.addLayout(hbox) self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok) vbox.addWidget(self.buttonbox) self.buttonbox.accepted.connect(self.accept) self.view.clicked.connect(self._update_details) self.setFixedSize(980, 650) self.view.setColumnWidth(0, 70) self.view.setColumnWidth(1, 80) self.view.setColumnWidth(2, 150) self.view.setColumnWidth(3, 70) @Slot() def _update_details(self): selection = self.view.selectionModel() if selection.hasSelection(): n = int(selection.selectedIndexes()[0].data()) self.details.setPlainText(self.chunks[n - 1].get("content", ""))
class MyWidget(QWidget): def __init__(self, parent=None): super(MyWidget, self).__init__(parent) self.view = View() self.grid = DateTimeGrid() self.slider = QSlider(self) self.model = QStandardItemModel(self) self.cmodel = ConstraintModel() ## proxyModel.setSourceModel( &model ); for i in range(0, 10): item = MyStandardItem("Multi Item " + str(i)) for j in range(0, 20, 3): item.appendRow([ MyStandardItem("Item " + str(j)), MyStandardItem(KDGantt.TypeTask), MyStandardItem(QDateTime.currentDateTime().addDays(j), KDGantt.StartTimeRole), MyStandardItem( QDateTime.currentDateTime().addDays(j + 1 + i / 7), KDGantt.EndTimeRole), MyStandardItem(50) ]) item.appendRow([ MyStandardItem("Event"), MyStandardItem(KDGantt.TypeEvent), MyStandardItem(QDateTime.currentDateTime(), KDGantt.StartTimeRole), MyStandardItem(QDateTime(), KDGantt.EndTimeRole), MyStandardItem("") ]) self.model.appendRow([ item, MyStandardItem(KDGantt.TypeMulti), MyStandardItem(""), MyStandardItem(""), MyStandardItem("") ]) pidx = self.model.index(0, 0) pidx = self.model.index(0, 0, pidx) self.cmodel.addConstraint( Constraint(self.model.index(0, 0, pidx), self.model.index(1, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(0, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(1, 0, pidx), self.model.index(10, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(3, 0, pidx), self.model.index(5, 0, pidx))) self.cmodel.addConstraint( Constraint(self.model.index(7, 0, pidx), self.model.index(4, 0, pidx))) self.slider.setOrientation(Qt.Horizontal) self.slider.setRange(1, 1000) self.slider.setValue(100) l = QVBoxLayout(self) l.addWidget(self.view) l.addWidget(self.slider) self.grid.setStartDateTime(QDateTime.currentDateTime().addDays(-3)) self.grid.setDayWidth(100) self.grid.setFreeDays([Qt.Saturday, Qt.Sunday]) self.grid.setFreeDaysBrush(QBrush(Qt.red)) lv = MyListView(self) self.view.setLeftView(lv) self.view.setRowController( ListViewRowController(lv, self.view.ganttProxyModel())) self.view.setGrid(self.grid) self.view.setModel(self.model) ##view.setConstraintModel( &cmodel ); self.slider.valueChanged.connect(self.slotZoom) def slotZoom(self, z): self.grid.setDayWidth(z)
class Window(QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.createTrayIcon() self.createProgramsList() self.createCodeEditPage() self.logsPage = QTextBrowser() self.documentation = QTextBrowser() self.tabWidget = QTabWidget() self.tabWidget.setIconSize(QSize(64, 64)) self.tabWidget.addTab(self.programsListPage, QIcon(":/images/Adventure-Map-icon.png"), "Programs") self.tabWidget.addTab(self.codeEditPage, QIcon(":/images/Sword-icon.png"), "Edit Program") self.tabWidget.addTab(self.logsPage, QIcon(":/images/Spell-Scroll-icon.png"), "Logs") self.tabWidget.addTab(self.documentation, QIcon(":/images/Spell-Book-icon.png"), "Documentation") self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.tabWidget) self.setLayout(self.mainLayout) self.setWindowTitle(APP_NAME) self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.Dialog) self.resize(800, 600) self.systrayHintMsgShowed = False self.firstShow = True self.fromQuit = False def createProgramsList(self): self.programsListModel = QStandardItemModel(0, 1, self) self.programsList = QListView() self.programsList.setModel(self.programsListModel) self.programsListPage = QWidget() self.programsListLayout = QVBoxLayout() self.programsListButtons = QHBoxLayout() self.programsListButtonNew = QPushButton("New") self.programsListButtonDelete = QPushButton("Delete") self.programsListButtonEdit = QPushButton("Edit") self.programsListButtonSet = QPushButton("Set") self.programsListButtons.addWidget(self.programsListButtonNew) self.programsListButtons.addWidget(self.programsListButtonSet) self.programsListButtons.addWidget(self.programsListButtonEdit) self.programsListButtons.addWidget(self.programsListButtonDelete) self.programsListLayout.addLayout(self.programsListButtons) self.programsListLayout.addWidget(self.programsList) self.programsListPage.setLayout(self.programsListLayout) self.programsListButtonNew.clicked.connect(self.newProgram) self.programsListButtonEdit.clicked.connect(self.editProgram) self.programsListButtonDelete.clicked.connect(self.deleteProgram) self.programsListButtonSet.clicked.connect(self.setProgram) def createCodeEditPage(self): self.codeEditPage = QWidget() self.codeEditLayout = QVBoxLayout() self.codeEditNameBox = QHBoxLayout() self.codeEditNameBoxNameLabel = QLabel("Name:") self.codeEditNameBoxNameInput = QLineEdit() self.codeEditNameBoxSaveButton = QPushButton("Save") self.codeEditNameBoxCancelButton = QPushButton("Cancel") self.codeEditNameBox.addWidget(self.codeEditNameBoxNameLabel) self.codeEditNameBox.addWidget(self.codeEditNameBoxNameInput) self.codeEditNameBox.addWidget(self.codeEditNameBoxSaveButton) self.codeEditNameBox.addWidget(self.codeEditNameBoxCancelButton) self.codeEdit = QTextEdit() self.codeEditLayout.addLayout(self.codeEditNameBox) self.codeEditLayout.addWidget(self.codeEdit) self.codeEditPage.setLayout(self.codeEditLayout) self.codeEditLastCode = '' self.codeEditNameBoxSaveButton.clicked.connect(self.saveEditProgram) self.codeEditNameBoxCancelButton.clicked.connect(self.cancelEditProgram) def showEvent(self, event): super().showEvent(event) if self.firstShow: self.firstShow = False self.createWaitDialog() self.findKeyboard() def closeWaitDialog(self): time.sleep(1) self.waitDialog.close() @Slot() def newProgram(self): self.showNormal() self.tabWidget.setCurrentWidget(self.codeEditPage) self.codeEdit.setPlainText("") self.codeEditLastCode = '' self.codeEditNameBoxNameInput.setText("") @Slot() def editProgram(self): selected = self.programsList.selectedIndexes() if not selected: return selected = selected[0].data() loadProgram = LoadProgram(self.cmdSocket, selected) loadProgram.loaded.connect(self.programLoaded) loadProgram.start() self.showWaitDialog("Loading program ...") @Slot() def saveEditProgram(self): name = self.codeEditNameBoxNameInput.text() program = self.codeEdit.toPlainText() if not name: return editProgramWorker = EditProgram(self.cmdSocket, name, program) editProgramWorker.edited.connect(self.programSaved) editProgramWorker.start() self.showWaitDialog("Saving program ...") @Slot() def cancelEditProgram(self): self.codeEdit.setPlainText(self.codeEditLastCode) @Slot() def deleteProgram(self): selected = self.programsList.selectedIndexes() if not selected: return selected = selected[0].data() deleteWorker = DeleteProgram(self.cmdSocket, selected) deleteWorker.deleted.connect(self.programDeleted) deleteWorker.start() self.showWaitDialog("Deleting program ...") @Slot() def setProgram(self): selected = self.programsList.selectedIndexes() if not selected: return selected = selected[0].data() setWorker = SetProgram(self.cmdSocket, selected) setWorker.setDone.connect(self.programSet) setWorker.start() self.showWaitDialog("Setting program ...") @Slot(str, str) def programLoaded(self, name, program): self.closeWaitDialog() self.tabWidget.setCurrentWidget(self.codeEditPage) self.codeEdit.setPlainText(program) self.codeEditLastCode = program self.codeEditNameBoxNameInput.setText(name) @Slot(str) def programDeleted(self, name): self.updateProgramsList() @Slot(str) def programSet(self, name): self.updateProgramsList() @Slot(str) def programSaved(self, name): self.updateProgramsList() self.tabWidget.setCurrentWidget(self.programsListPage) def createWaitDialog(self): self.waitDialog = QDialog(self) self.waitDialogLayout = QHBoxLayout() self.waitDialogLabel = QLabel() self.waitDialogLayout.addWidget(self.waitDialogLabel) self.waitDialog.setLayout(self.waitDialogLayout) self.waitDialog.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint) def showWaitDialog(self, text='Please wait...'): self.waitDialogLabel.setText(text) self.waitDialog.exec_() def findKeyboard(self): find = ConnectKeyboard() find.connected.connect(self.keyboardConnected) find.start() self.showWaitDialog('Finding and connecting Fruit2Pi Keyboard ...') @Slot(BluetoothSocket) def keyboardConnected(self, socket): self.cmdSocket = socket self.updateProgramsList() def updateProgramsList(self): self.listProgram = ListProgram(self.cmdSocket) self.listProgram.listed.connect(self.programListUpdated) self.listProgram.start() @Slot(list, str) def programListUpdated(self, programs, current_program): print(programs) print(current_program) self.closeWaitDialog() self.programsListModel.clear() for p in programs: item = QStandardItem(p) if p == current_program: item.setForeground(QBrush(QColor(0, 0, 255, 127))) self.programsListModel.appendRow(item) def setVisible(self, visible): super().setVisible(visible) def closeEvent(self, event): if self.fromQuit: return if not event.spontaneous() or not self.isVisible(): return if not self.systrayHintMsgShowed: self.systrayHintMsgShowed = True icon = QIcon(":/images/yammi-banana-icon.png") self.trayIcon.showMessage(APP_NAME, "Running on background" "To quit, choose <b>Quit</b> in the icon menu", icon, 5000 ) self.hide() event.ignore() @Slot(str) def iconActivated(self, reason): print(reason) if reason == QSystemTrayIcon.Trigger: self.showNormal() if reason == QSystemTrayIcon.DoubleClick: self.showNormal() @Slot() def showProgramsPage(self): self.showNormal() self.tabWidget.setCurrentWidget(self.programsListPage) @Slot() def showLogsPage(self): self.showNormal() self.tabWidget.setCurrentWidget(self.logsPage) @Slot() def showDocumentation(self): self.showNormal() self.tabWidget.setCurrentWidget(self.documentation) @Slot() def quit(self): self.fromQuit = True qApp.quit() def createTrayIcon(self): self.showProgramsAction = QAction("Programs", self) self.showProgramsAction.triggered.connect(self.showProgramsPage) self.showNewProgramAction = QAction("New Program", self) self.showNewProgramAction.triggered.connect(self.newProgram) self.showSetProgramAction = QAction("Logs", self) self.showSetProgramAction.triggered.connect(self.showLogsPage) self.showDocumentationAction = QAction("Documentation", self) self.showDocumentationAction.triggered.connect(self.showDocumentation) self.quitAction = QAction("Quit", self) self.quitAction.triggered.connect(self.quit) self.trayIconMenu = QMenu(self) self.trayIconMenu.addAction(self.showProgramsAction) self.trayIconMenu.addAction(self.showSetProgramAction) self.trayIconMenu.addAction(self.showNewProgramAction) self.trayIconMenu.addAction(self.showDocumentationAction) self.trayIconMenu.addSeparator() self.trayIconMenu.addAction(self.quitAction) self.trayIcon = QSystemTrayIcon(self) self.trayIcon.setContextMenu(self.trayIconMenu) self.trayIcon.activated.connect(self.iconActivated) self.trayIcon.setIcon(QIcon(":/images/yammi-banana-icon.png")) self.trayIcon.show()