def __generateItem(self, status, path): """ Private method to generate a status item in the status list. @param status status indicator (string) @param path path of the file or directory (string) """ statusText = self.status[status] itm = QTreeWidgetItem(self.statusList, [ "", statusText, path, ]) itm.setTextAlignment(1, Qt.AlignHCenter) itm.setTextAlignment(2, Qt.AlignLeft) if status in "AMR": itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable) if statusText not in self.__statusFilters: self.__statusFilters.append(statusText)
def refresh(self): """ Public method to refresh the tree. """ QApplication.setOverrideCursor(Qt.WaitCursor) self.__itemChangingBlock = True self.clear() boldFont = QFont() boldFont.setBold(True) self.__topItem = QTreeWidgetItem(self) self.__topItem.setText(0, self.__subscription.title()) self.__topItem.setFont(0, boldFont) self.addTopLevelItem(self.__topItem) allRules = self.__subscription.allRules() index = 0 for rule in allRules: item = QTreeWidgetItem(self.__topItem) item.setText(0, rule.filter()) item.setData(0, Qt.UserRole, index) if self.__subscription.canEditRules(): item.setFlags(item.flags() | Qt.ItemIsEditable) self.__adjustItemFeatures(item, rule) index += 1 self.expandAll() self.showRule(None) self.__itemChangingBlock = False QApplication.restoreOverrideCursor() QApplication.processEvents()
def generate_tree_model(self, data_dict): """Generate a tree model for specified dictionary :param data_dict: A dictionary :type data_dict: dict :return: list of QTreeWidgetItem :rtype list: """ widget_items = [] font = QFont() font.setBold(True) for key in data_dict.keys(): entry = data_dict[key] key_item = QTreeWidgetItem() key_item.setText(0, str(key)) key_item.setFont(0, font) if isinstance(entry, dict): items = self.generate_tree_model(entry) key_item.addChildren(items) else: # value_item = QTreeWidgetItem() key_item.setText(1, str(entry)) key_item.setFlags(key_item.flags() | Qt.ItemIsEditable) # key_item.addChild(key_item) widget_items.append(key_item) return widget_items
def _populate_repo_tree(self): """ Initialize the tree widget of repos and volumes. """ self._repo_treewidget.clear() if self._repos_info is None: return for repo_uuid, repo_info in sorted(self._repos_info.items()): if repo_info is None: continue repo_column_dict = collections.defaultdict(str) repo_column_dict["Alias"] = repo_info["Alias"] repo_column_dict["Details"] = "Created: " + repo_info["Created"] repo_column_dict["UUID"] = repo_uuid repo_column_values = [repo_column_dict[k] for k in TREEVIEW_COLUMNS] repo_item = QTreeWidgetItem( self._repo_treewidget, repo_column_values ) repo_item.setData( 0, Qt.UserRole, (repo_uuid, "", "") ) for data_name, data_info in repo_info["DataInstances"].items(): data_instance_dict = collections.defaultdict(str) data_instance_dict["Alias"] = data_name typename = data_info["Base"]["TypeName"] data_instance_dict["TypeName"] = typename is_voxels = (typename in VOXEL_TYPENAMES) if is_voxels: start_coord = data_info["Extended"]["MinPoint"] if start_coord: start_coord = tuple(start_coord) stop_coord = data_info["Extended"]["MaxPoint"] if stop_coord: stop_coord = tuple(x+1 for x in stop_coord) if start_coord and stop_coord: shape = tuple(b - a for a,b in zip(start_coord, stop_coord)) else: shape = None data_instance_dict["Details"] = "Size={} | Start={} | Stop={}".format( shape, start_coord, stop_coord ) data_column_values = [data_instance_dict[k] for k in TREEVIEW_COLUMNS] data_item = QTreeWidgetItem( repo_item, data_column_values ) data_item.setData( 0, Qt.UserRole, (repo_uuid, data_name, typename) ) # If we're in specify_new mode, only the # repo parent items are selectable. # Also, non-volume items aren't selectable. if self._mode == 'specify_new' or typename not in self._selectable_types: flags = data_item.flags() flags &= ~Qt.ItemIsSelectable flags &= ~Qt.ItemIsEnabled data_item.setFlags( flags ) self._repo_treewidget.collapseAll() self._repo_treewidget.setSortingEnabled(True) if self._hostname in self._default_nodes: self._select_node_uuid(self._default_nodes[self._hostname]) self._repo_treewidget.resizeColumnToContents(0) self._repo_treewidget.setFocus()
def addRule(self, filter=""): """ Public slot to add a new rule. @param filter filter to be added (string) """ if not self.__subscription.canEditRules(): return if not filter: filter = QInputDialog.getText( self, self.tr("Add Custom Rule"), self.tr("Write your rule here:"), QLineEdit.Normal) if filter == "": return from .AdBlockRule import AdBlockRule rule = AdBlockRule(filter, self.__subscription) offset = self.__subscription.addRule(rule) item = QTreeWidgetItem() item.setText(0, filter) item.setData(0, Qt.UserRole, offset) item.setFlags(item.flags() | Qt.ItemIsEditable) self.__itemChangingBlock = True self.__topItem.addChild(item) self.__itemChangingBlock = False self.__adjustItemFeatures(item, rule)
def createItem(self, text, parent, index): after = None if index != 0: after = self.childAt(parent, index - 1) if parent is not None: item = QTreeWidgetItem(parent, after) else: item = QTreeWidgetItem(self, after) item.setText(0, text) item.setFlags(item.flags() | Qt.ItemIsEditable) return item
def readSettings(self): entries = settings.readMarkColors() for name, color in entries.items(): item = QTreeWidgetItem(self.markColorWidget) item.setFlags(item.flags() | Qt.ItemIsEditable) widget = ColorVignette(self) widget.setColor(color) widget.setMargins(2, 2, 2, 2) widget.setMayClearColor(False) self.markColorWidget.setItemWidget(item, 0, widget) item.setText(1, name) if not len(entries): self.removeItemButton.setEnabled(False) loadRecentFile = settings.loadRecentFile() self.loadRecentFileBox.setChecked(loadRecentFile)
def propertyInserted(self, index, afterIndex): afterItem = self.m_indexToItem.get(afterIndex) parentItem = self.m_indexToItem.get(index.parent()) newItem = 0 if (parentItem): newItem = QTreeWidgetItem(parentItem, afterItem) else: newItem = QTreeWidgetItem(self.m_treeWidget, afterItem) self.m_itemToIndex[newItem] = index self.m_indexToItem[index] = newItem newItem.setFlags(newItem.flags() | Qt.ItemIsEditable) newItem.setExpanded(True) self.updateItem(newItem)
def _updateLayerAttributes(self, notification=None): self.layerSetWidget.clear() if self._font is None: return layerSet = self._font.layers if layerSet is None: return for layer in layerSet: item = QTreeWidgetItem(self.layerSetWidget) item.setFlags(item.flags() | Qt.ItemIsEditable) item.setText(0, layer.name) widget = ColorVignette(self) color = layer.color if color is not None: color = QColor.fromRgbF(*tuple(color)) widget.setColor(color) widget.setMargins(2, 2, 2, 2) widget.setMayClearColor(False) widget.colorChanged.connect(self.writeLayerColor) widget.setProperty("layer", layer) self.layerSetWidget.setItemWidget(item, 1, widget) self.layerSetWidget.setColumnWidth(1, 100)
def addItem(self): def mangleNewName(): name = self.tr("New") index = 0 while self.markColorWidget.findItems(name, Qt.MatchExactly, 1): index += 1 name = "{0} ({1})".format(name, index) return name # TODO: not DRY with ctor item = QTreeWidgetItem(self.markColorWidget) item.setFlags(item.flags() | Qt.ItemIsEditable) widget = ColorVignette(self) widget.setColor(QColor(Qt.white)) widget.setMargins(2, 2, 2, 2) widget.setMayClearColor(False) self.markColorWidget.setItemWidget(item, 0, widget) item.setText(1, mangleNewName()) self.markColorWidget.setCurrentItem(item) self.markColorWidget.editItem(item, 1) self.removeItemButton.setEnabled(True)
def __createItem(self, file, line, text, start, end, replTxt="", md5=""): """ Private method to create an entry in the file list. @param file filename of file (string) @param line line number (integer) @param text text found (string) @param start start position of match (integer) @param end end position of match (integer) @param replTxt text with replacements applied (string) @keyparam md5 MD5 hash of the file (string) """ if self.__lastFileItem is None: # It's a new file self.__lastFileItem = QTreeWidgetItem(self.findList, [file]) self.__lastFileItem.setFirstColumnSpanned(True) self.__lastFileItem.setExpanded(True) if self.__replaceMode: self.__lastFileItem.setFlags( self.__lastFileItem.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate)) # Qt bug: # item is not user checkable if setFirstColumnSpanned # is True (< 4.5.0) self.__lastFileItem.setData(0, self.md5Role, md5) itm = QTreeWidgetItem(self.__lastFileItem) itm.setTextAlignment(0, Qt.AlignRight) itm.setData(0, Qt.DisplayRole, line) itm.setData(1, Qt.DisplayRole, text) itm.setData(0, self.lineRole, line) itm.setData(0, self.startRole, start) itm.setData(0, self.endRole, end) itm.setData(0, self.replaceRole, replTxt) if self.__replaceMode: itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable)) itm.setCheckState(0, Qt.Checked) self.replaceButton.setEnabled(True)
def __init__(self,MainWindow, headers, apiKey,checkBoxState): super(Ui_OtherWindow,self).__init__() self.ScRate = GetSystemMetrics(0)/1920 self.mainWindow = MainWindow self.headers = headers self.mainWindow.setObjectName("MainWindow") self.mainWindow.resize(350*self.ScRate, 393*self.ScRate) self.mainWindow.setMinimumSize(QSize(350*self.ScRate, 393*self.ScRate)) self.mainWindow.setMaximumSize(QSize(350*self.ScRate, 393*self.ScRate)) self.mainWindow.setWindowFlags(self.mainWindow.windowFlags() & ~Qt.WindowCloseButtonHint) self.mainWindow.setWindowIcon(QIcon(Icons["Standart"])) self.mainWindow = MainWindow self.headers = headers self.centralwidget = QWidget(self.mainWindow) self.centralwidget.setObjectName("centralwidget") self.gridLayout = QGridLayout(self.centralwidget) self.gridLayout.setObjectName("gridLayout") self.verticalLayout = QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout_4 = QVBoxLayout() self.verticalLayout_4.setObjectName("verticalLayout_4") self.label = QLabel(self.centralwidget) font = QFont() font.setPointSize(10*self.ScRate) self.label.setFont(font) self.label.setObjectName("label") self.verticalLayout_4.addWidget(self.label) self.lineEdit = QLineEdit(self.centralwidget) self.lineEdit.setObjectName("lineEdit") self.verticalLayout_4.addWidget(self.lineEdit) self.verticalLayout.addLayout(self.verticalLayout_4) self.label_2 = QLabel(self.centralwidget) font = QFont() font.setPointSize(10*self.ScRate) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.verticalLayout.addWidget(self.label_2) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.treeWidget = QTreeWidget(self.centralwidget) self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.treeWidget.customContextMenuRequested.connect(self.on_context_menu) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.treeWidget.sizePolicy().hasHeightForWidth()) self.treeWidget.setSizePolicy(sizePolicy) self.treeWidget.setObjectName("treeWidget") for i in range(len(self.headers)): item_0 = QTreeWidgetItem(self.treeWidget) item_0.setFlags(item_0.flags() | Qt.ItemIsEditable) self.horizontalLayout.addWidget(self.treeWidget) self.verticalLayout_2 = QVBoxLayout() self.verticalLayout_2.setObjectName("verticalLayout_2") self.horizontalLayout.addLayout(self.verticalLayout_2) self.verticalLayout.addLayout(self.horizontalLayout) self.gridLayout.addLayout(self.verticalLayout, 0, 0, 3, 1) self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setContentsMargins(150, -1, -1, -1) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.pushButton_2 = QPushButton(self.centralwidget) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth()) self.pushButton_2.setSizePolicy(sizePolicy) self.pushButton_2.setObjectName("pushButton_2") self.horizontalLayout_2.addWidget(self.pushButton_2) self.pushButton = QPushButton(self.centralwidget) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth()) self.pushButton.setSizePolicy(sizePolicy) self.pushButton.setObjectName("pushButton") self.horizontalLayout_2.addWidget(self.pushButton) self.gridLayout.addLayout(self.horizontalLayout_2, 7, 0, 1, 1) spacerItem = QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(spacerItem, 4, 0, 1, 1) self.checkBox = QCheckBox(self.centralwidget) self.checkBox.setChecked(eval(checkBoxState)) font = QFont() font.setFamily("MS Shell Dlg 2") font.setPointSize(9) font.setItalic(False) self.checkBox.setFont(font) self.checkBox.setObjectName("checkBox") self.gridLayout.addWidget(self.checkBox, 3, 0, 1, 1) self.mainWindow.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(self.mainWindow) self.menubar.setGeometry(QRect(0, 0, 350*self.ScRate, 26*self.ScRate)) self.menubar.setObjectName("menubar") self.mainWindow.setMenuBar(self.menubar) self.statusbar = QStatusBar(self.mainWindow) self.statusbar.setObjectName("statusbar") self.mainWindow.setStatusBar(self.statusbar) self.create_popup_menu() self.pushButton.clicked.connect(self.saveBtn) self.pushButton_2.clicked.connect(self.cancel) self.mainWindow.keyPressEvent = self.keyPressEvent if type(apiKey) == list: try: self.lineEdit.setText(apiKey[0]) except IndexError: self.lineEdit.setText("") else: self.lineEdit.setText(apiKey) self.retranslateUi(self.mainWindow) self.treeWidget.resizeColumnToContents(0) root = self.treeWidget.invisibleRootItem() child_count = root.childCount() for i in range(child_count): item = root.child(i) url = item.text(0) if url == "İsim" or url == "Telefon No (Örn 9053xx..)": item.setFlags(item.flags() & ~Qt.ItemIsEditable) if url == "Mesaj Durumu": item.setHidden(True) QMetaObject.connectSlotsByName(self.mainWindow)
def handleDict(self, dict_data, tree, tree_dict={}, new=False): # We can actually have numerous structures, here. # Why not keep track of it, for now? # We want to do a reverse lookup #ddc = copy.copy(dict_data) #ddc = dict_data con = False oldKeyTree = None #for key, val in sorted(ddc.items(), key= lambda x: str(x)): od = {} # This sped it up quite a bit. try: #od = OrderedDict(sorted(ddc.items(), key= lambda i: self.parent.mpl_dict['keyOrder'].index(i[0]))) #od = OrderedDict(sorted(ddc.items(), key= lambda i: self.parent.mpl_dict['keyOrder'].index(i[0]))) od_keys = sorted( dict_data.keys(), key=lambda i: self.parent.mpl_dict['keyOrder'].index(i[0])) except: # Default to alphabetical order #od = OrderedDict(sorted(ddc.items(), key= lambda x: str(x))) od_keys = sorted(dict_data.keys(), key=lambda x: str(x)) for key in od_keys: val = dict_data[key] if type(key) == str and len(key) >= 6: #if key[0:7] != 'keyTree' and key[0:7] != 'valTree': if key not in self.parent.mpl_dict['hidden_keys']: con = True else: con = False else: con = True if con: try: keyTree = tree_dict['keyTree.{}'.format(key)] keyTree.setText(0, str(key)) except Exception: # This behavior ensures that we insert the new tree item at # the location specified in the abov dictionary. Seems to work. if oldKeyTree is not None: keyTree = QTreeWidgetItem(tree, oldKeyTree) keyTree.setText(0, str(key)) else: keyTree = QTreeWidgetItem(tree, [str(key)]) keyTree.oldValue = [str(key)] tree_dict['keyTree.{}'.format(key)] = keyTree '''if 'keyTree.{}'.format(key) not in tree_dict or new: keyTree = QTreeWidgetItem(tree, [str(key)]) keyTree.oldValue = [str(key)] tree_dict['keyTree.{}'.format(key)] = keyTree else: keyTree = tree_dict['keyTree.{}'.format(key)] keyTree.setText(0, str(key))''' oldKeyTree = keyTree if key == 'Figures': self.figures = keyTree if type(val) == h5py._hl.group.Group: #tree_dict[key] = # This is a normal HDF5 group. Treat it appropriately. if key not in tree_dict: tree_dict[key] = {} self.handleDict(val, keyTree, new=new, tree_dict=tree_dict[key]) if type(val) == dict: if key not in tree_dict: tree_dict[key] = {} self.handleDict(val, keyTree, new=new, tree_dict=tree_dict[key]) elif type(val) == h5py._hl.dataset.Dataset: # Let's handle 2 and 3 dimensional data for now. Anything more than that and it just... well, it won't plot anyway. # I know this shouldn't go into the handlDict function, but hey. At least rename it. sdict = {} if len(val.shape) == 2: # Assume time is the first dimension. for i in range(0, val.shape[1]): if val.dtype.names is not None: sdict[i] = {} for iv, v in enumerate(val.dtype.names): # Why the f**k is this so slow? sdict[i][v] = str(val.shape) else: sdict[i] = str(val.shape) if len(val.shape) == 3: # Assume time is the first dimension. for i in range(0, val.shape[1]): for j in range(0, val.shape[2]): if val.dtype.names is not None: sdict[(i, j)] = {} for iv, v in enumerate(val.dtype.names): # Why the f**k is this so slow? sdict[(i, j)][v] = str(val.shape) else: sdict[(i, j)] = str(val.shape) if key not in tree_dict: tree_dict[key] = {} self.handleDict(sdict, keyTree, new=new, tree_dict=tree_dict[key]) else: # We want this to be like rows, not columns if self.rows: if type(val) == list: for iv, v in enumerate(val): if self.editable: keyTree.setFlags( keyTree.flags() | QtCore.Qt.ItemIsEditable) keyTree.setText(iv + 1, str(v)) keyTree.oldValue.append((str(v))) self.col += iv else: if self.editable: keyTree.setFlags(keyTree.flags() | QtCore.Qt.ItemIsEditable) keyTree.setText(1, str(val)) keyTree.oldValue.append((str(val))) self.tree.setColumnCount(self.col)
def __generateItem(self, status, propStatus, locked, history, switched, lockinfo, uptodate, revision, change, author, path): """ Private method to generate a status item in the status list. @param status status indicator (string) @param propStatus property status indicator (string) @param locked locked indicator (string) @param history history indicator (string) @param switched switched indicator (string) @param lockinfo lock indicator (string) @param uptodate up to date indicator (string) @param revision revision string (string) @param change revision of last change (string) @param author author of the last change (string) @param path path of the file or directory (string) """ if (self.__nonverbose and status == " " and propStatus == " " and locked == " " and history == " " and switched == " " and lockinfo == " " and uptodate == " " and self.currentChangelist == ""): return if revision == "": rev = "" else: try: rev = int(revision) except ValueError: rev = revision if change == "": chg = "" else: try: chg = int(change) except ValueError: chg = change statusText = self.status[status] itm = QTreeWidgetItem(self.statusList) itm.setData(0, Qt.DisplayRole, "") itm.setData(1, Qt.DisplayRole, self.currentChangelist) itm.setData(2, Qt.DisplayRole, statusText) itm.setData(3, Qt.DisplayRole, self.propStatus[propStatus]) itm.setData(4, Qt.DisplayRole, self.locked[locked]) itm.setData(5, Qt.DisplayRole, self.history[history]) itm.setData(6, Qt.DisplayRole, self.switched[switched]) itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo]) itm.setData(8, Qt.DisplayRole, self.uptodate[uptodate]) itm.setData(9, Qt.DisplayRole, rev) itm.setData(10, Qt.DisplayRole, chg) itm.setData(11, Qt.DisplayRole, author) itm.setData(12, Qt.DisplayRole, path) itm.setTextAlignment(1, Qt.AlignLeft) itm.setTextAlignment(2, Qt.AlignHCenter) itm.setTextAlignment(3, Qt.AlignHCenter) itm.setTextAlignment(4, Qt.AlignHCenter) itm.setTextAlignment(5, Qt.AlignHCenter) itm.setTextAlignment(6, Qt.AlignHCenter) itm.setTextAlignment(7, Qt.AlignHCenter) itm.setTextAlignment(8, Qt.AlignHCenter) itm.setTextAlignment(9, Qt.AlignRight) itm.setTextAlignment(10, Qt.AlignRight) itm.setTextAlignment(11, Qt.AlignLeft) itm.setTextAlignment(12, Qt.AlignLeft) if status in "ADM" or propStatus in "M": itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable) self.hidePropertyStatusColumn = (self.hidePropertyStatusColumn and propStatus == " ") self.hideLockColumns = (self.hideLockColumns and locked == " " and lockinfo == " ") self.hideUpToDateColumn = self.hideUpToDateColumn and uptodate == " " self.hideHistoryColumn = self.hideHistoryColumn and history == " " self.hideSwitchedColumn = self.hideSwitchedColumn and switched == " " if statusText not in self.__statusFilters: self.__statusFilters.append(statusText)
class Waterfall(QWidget, waterfall.Ui_Waterfall): plot_settings_signal = QtCore.pyqtSignal( list) #send list of plotting params updated_rectangles_signal = QtCore.pyqtSignal( list) #send list of updated artists for redrawing def __init__(self, parent): super(Waterfall, self).__init__(parent) self.setupUi(self) self.get_settings() #Button functions self.btn_apply_general_settings.clicked.connect(self.send_settings) self.btn_apply_keys_and_colors_settings.clicked.connect( self.send_settings) self.patient_tree = self.create_patient_tree() self.data_viewer_container.addWidget(self.patient_tree) self.btn_color_test.clicked.connect(self.get_color) def get_color(self): self.color = QColorDialog.getColor() #returns a color object print(color) def get_settings(self): # try: # with shelve.open('WaterfallSettings') as shelfFile: # self.keys_and_colors = shelfFile['keys_and_colors'] # shelfFile.close() # except: # #set and use default settings # self.keys_and_colors = { # 'CR':'#03945D', # 'PR':'#B1EE97', # 'PD':'#FF6F69', # 'SD':'#707070', # 'a':'r', # 'b':'g', # 'c':'b' # } # with shelve.open('WaterfallSettings') as shelfFile: # shelfFile['keys_and_colors'] = self.keys_and_colors # shelfFile.close() self.keys_and_colors = { 'CR': '#03945D', 'PR': '#B1EE97', 'PD': '#FF6F69', 'SD': '#707070', 'a': '#FF0000', 'b': '#00FF00', 'c': '#0000FF' } def on_waterfall_data_signal(self, signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe def on_generated_rectangles_signal(self, signal): self.rectangles_received = signal[0] self.add_items() #display in table self.btn_apply_general_settings.setEnabled(True) self.btn_finalize_plot.setEnabled(True) self.btn_apply_keys_and_colors_settings.setEnabled(True) def send_settings(self): ''' Emit both general plot settings, and color labeling settings. These are the settings to be used when the plot is created. ''' self.general_settings = [ self.plot_title.text(), self.x_label.text(), self.y_label.text(), [ self.twenty_percent_line.isChecked(), self.thirty_percent_line.isChecked(), self.zero_percent_line.isChecked() ], [ self.display_responses_as_text.isChecked(), self.display_responses_as_color.isChecked(), self.use_custom_keys.isChecked() ], self.include_table.isChecked(), self.show_cancer_type.isChecked(), self.get_updated_color_coding() ] self.plot_settings_signal.emit(self.general_settings) def create_patient_tree(self): ''' Create QTreeWidget populated with a patient's data for the DataEntry dialog. Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog. ''' self.tree = QTreeWidget() self.root = self.tree.invisibleRootItem() self.headers = [ 'Patient #', 'Best response %', 'Response', 'Cancer', 'Color key', ] self.headers_item = QTreeWidgetItem(self.headers) self.tree.setColumnCount(len(self.headers)) self.tree.setHeaderItem(self.headers_item) self.root.setExpanded(True) self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) return self.tree def add_items(self): ''' Populate viewing tree ''' self.tree.clear() #clear prior to entering items, prevent aggregation i = 0 for rect in self.rectangles_received: #populate editable tree with rect data self.rect_item = QTreeWidgetItem(self.root) self.rect_params = [ self.waterfall_data['Patient number'][i], rect.get_height(), self.waterfall_data['Overall response'][i], self.waterfall_data['Cancer'][i] ] for col in range(0, 4): self.rect_item.setText(col, str(self.rect_params[col])) self.rect_item.setTextAlignment(col, 4) self.tree.setItemWidget( self.rect_item, 4, CustomCombo(self, self.keys_and_colors, rect.get_label())) self.rect_item.setFlags(self.rect_item.flags() | QtCore.Qt.ItemIsEditable) i += 1 def get_updated_color_coding(self): tmp_updated_color_coding = [] self.root = self.tree.invisibleRootItem() child_count = self.root.childCount() #return list of keys (children are iterated in order they were entered, which agrees with order of patient data in waterfall_data lists) return [ self.tree.itemWidget(self.root.child(i), 4).currentText() for i in range(child_count) ] def on_updated_tree_item(self): #update the rectangle which was edited pass
def populate_available_terms(self): """ Runs at start up and when volume is changed. Poulates the avaible annotation terms """ self.ui.treeWidgetAvailableTerms.clear() vol = self.controller.current_annotation_volume() if not vol or None in (vol.annotations.stage, vol.annotations.center): # info_dialog(self, 'Chose centre and stage', 'You must choose a centre and stage from the options tab') return self.ui.lineEditCentre.setText(vol.annotations.center) self.ui.lineEditStage.setText(vol.annotations.stage) def setup_option_box_signal(box_: QComboBox, child_: QTreeWidgetItem): """ Connect the Qcombobox to a slot """ box_.activated.connect(partial(self.update_annotation, child_, box_)) # Setup signal so when combobox is only opened, it sets the selection to that column box_.highlighted.connect(partial(self.on_box_highlight, child)) header_labels = QTreeWidgetItem(['', 'term', 'name', 'option', 'done?']) self.ui.treeWidgetAvailableTerms.setHeaderItem(header_labels) parent = QTreeWidgetItem(self.ui.treeWidgetAvailableTerms) parent.setText(0, '') parent.setFlags(parent.flags()) parent.setExpanded(True) header = self.ui.treeWidgetAvailableTerms.header() # Set root column to invisible self.ui.treeWidgetAvailableTerms.setColumnWidth(0, 0) header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) # For each annotation set an info row in the annotations table for i, ann in enumerate(sorted(vol.annotations, key=lambda an_: an_.order)): child = QTreeWidgetItem(parent) child.setText(1, ann.term) child.setText(3, ann.name) option = ann.selected_option # color = OPTION_COLOR_MAP[option] parent.addChild(child) # Set up the parameter option combobox and highlight the currently selected one options_box = QComboBox() options_box.setSizeAdjustPolicy(QComboBox.AdjustToContents) for opt in ann.options: options_box.addItem(opt) options_box.setCurrentIndex(options_box.findText(option)) # 060818 Louise's bug option is a bool not a str # Setup combobox selection signal setup_option_box_signal(options_box, child) self.ui.treeWidgetAvailableTerms.setItemWidget(child, 2, options_box) done_checkbox = QtWidgets.QCheckBox() done_checkbox.setChecked(ann.looked_at) done_checkbox.stateChanged.connect(partial(self.parameter_done_signal, child, done_checkbox)) self.ui.treeWidgetAvailableTerms.setItemWidget(child, 4, done_checkbox) # Set the roi coords to None self.roi_highlight_off_signal.emit()
def addChild(self, parent, title, data, flags=Qt.NoItemFlags): item = QTreeWidgetItem(parent, [title]) item.setFlags(item.flags() | Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable | flags) item.setData(self.colVALUE, Qt.DisplayRole, data) return item
class Waterfall(QWidget, waterfall.Ui_Waterfall): plot_settings_signal = QtCore.pyqtSignal(list) #send list of plotting params updated_rectangles_signal = QtCore.pyqtSignal(list) #send list of updated artists for redrawing def __init__(self, parent): super(Waterfall,self).__init__(parent) self.setupUi(self) self.test = {'a':'red','b':'green','c':'blue'} #Button functions self.btn_apply_general_settings.clicked.connect(self.send_settings) self.btn_apply_keys_and_colors_settings.clicked.connect(self.send_settings) self.patient_tree = self.create_patient_tree() self.data_viewer_container.addWidget(self.patient_tree) self.btn_color_test.clicked.connect(self.get_color) self.get_settings() def get_color(self): def get_settings(self): try: with shelve.open('WaterfallSettings') as shelfFile: self.keys_and_colors = shelfFile['keys_and_colors'] shelfFile.close() except: #default self.keys_and_colors = { 'CR':'#03945D', 'PR':'#B1EE97', 'PD':'#FF6F69', 'SD':'#707070'} def on_waterfall_data_signal(self,signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe def on_generated_rectangles_signal(self,signal): self.rectangles_received = signal[0] self.add_items() #display in table def send_settings(self,signal): ''' Emit both general plot settings, and color labeling settings. These are the settings to be used when the plot is created. ''' self.list_general_settings = [ self.plot_title.text(), self.x_label.text(), self.y_label.text(), self.twenty_percent_line.isChecked(), self.thirty_percent_line.isChecked(), self.zero_percent_line.isChecked(), self.display_responses_as_text.isChecked() ] self.plot_settings_signal.emit([self.list_general_settings,self.keys_and_colors_settings]) def create_patient_tree(self): ''' Create QTreeWidget populated with a patient's data for the DataEntry dialog. Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog. ''' self.tree = QTreeWidget() self.root = self.tree.invisibleRootItem() self.headers = [ 'Patient #', 'Best response %', 'Response', 'Cancer', 'Color key', ] self.headers_item = QTreeWidgetItem(self.headers) self.tree.setColumnCount(len(self.headers)) self.tree.setHeaderItem(self.headers_item) self.root.setExpanded(True) self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) return self.tree def add_items(self): ''' Populate viewing tree ''' self.tree.clear() #clear prior to entering items, prevent aggregation i=0 for rect in self.rectangles_received: #populate editable tree with rect data self.rect_item = QTreeWidgetItem(self.root) self.rect_params = [ self.waterfall_data['Patient number'][i], rect.get_height(), self.waterfall_data['Overall response'][i], self.waterfall_data['Cancer'][i] ] for col in range(0,4): self.rect_item.setText(col,str(self.rect_params[col])) self.rect_item.setTextAlignment(col,4) self.tree.setItemWidget(self.rect_item, 4, CustomCombo(self,self.keys_and_colors)) self.rect_item.setFlags(self.rect_item.flags() | QtCore.Qt.ItemIsEditable) i+=1 def on_updated_tree_item(self): #update the rectangle which was edited pass class WaterfallPlotter(QWidget): generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree def __init__(self,parent): super(WaterfallPlotter,self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas,self) self.btn_plot = QPushButton('Default Plot') self.btn_plot.clicked.connect(self.default_plot) self.layout = QVBoxLayout() self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.layout.addWidget(self.btn_plot) self.setLayout(self.layout) def on_waterfall_data_signal(self,signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe self.btn_plot.setEnabled(True) def on_general_settings_signal(self,signal): try: hasattr(self,'ax') self.ax.set_title(signal[0]) self.ax.set_xlabel(signal[1]) self.ax.set_ylabel(signal[2]) self.canvas.draw() except Exception as e: print(e) def default_plot(self): ''' Plot waterfall data ''' self.figure.clear() self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change'])) self.ax = self.figure.add_subplot(111) self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent') self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent') self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent') self.ax.grid(color = 'k', axis = 'y', alpha=0.25) self.rects = self.ax.bar(self.rect_locations,self.waterfall_data['Best response percent change']) self.auto_label_responses(self.ax, self.rects, self.waterfall_data) #self.plot_table() self.canvas.draw() self.ax.hold(False) #rewrite the plot when plot() called self.generated_rectangles_signal.emit([self.rects]) def plot_table(self): rows = ['%s' % x for x in self.waterfall_data.keys()] rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows columns = self.waterfall_data['Patient number'] #patient numbers cell_text = [] for row in rows: cell_text_temp = [] for col in range(len(columns)): cell_text_temp.append(self.waterfall_data[row][col]) cell_text.append(cell_text_temp) the_table = plt.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center') plt.subplots_adjust(bottom=0.15,left=0.5) self.ax.set_xlim(-0.5,len(columns)-0.5) plt.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='off', # ticks along the bottom edge are off top='off', # ticks along the top edge are off labelbottom='off' ) # labels along the bottom edge are off def update_plot(self): ''' TODO ''' pass def auto_label_responses(self, ax, rects, waterfall_data): '''Add labels above/below bars''' i = 0 for rect in rects: height = rect.get_height() if height >= 0: valign = 'bottom' else: valign = 'top' ax.text(rect.get_x() + rect.get_width()/2., height, '%s' % waterfall_data['Overall response'][i], ha='center', va=valign) i+=1
def loadStep(self): """Bring in a step file as a 'disposable' treelib.Tree() structure. Each node of the tree contains the following tuple: (Name, UID, ParentUID, {Data}) where the Data dictionary is: {'a': (isAssy?), 'l': (TopLoc_Location), 'c': (Quantity_Color), 's': (TopoDS_Shape)} This format makes it convenient to: 1. Build the assy, part, name and color dictionaries using uid keys, 2. Display the model with all its component parts correctly located and 3. Build the Part/Assy tree view GUI (QTreeWidget). Each QTreeWidgetItem is required to have a unique identifier. This means that multiple instances of the same CAD geometry will each have different uid's. """ prompt = 'Select STEP file to import' fnametuple = QFileDialog.getOpenFileName( None, prompt, './', "STEP files (*.stp *.STP *.step)") fname, _ = fnametuple logger.debug("Load file name: %s", fname) if not fname: print("Load step cancelled") return name = os.path.basename(fname).split('.')[0] nextUID = self._currentUID stepImporter = stepXD.StepImporter(fname, nextUID) self.doc = stepImporter.doc # <class 'OCC.Core.TDocStd.TDocStd_Document'> tree = stepImporter.tree tempTreeDict = { } # uid:asyPrtTreeItem (used temporarily during unpack) treedump = tree.expand_tree(mode=tree.DEPTH) for uid in treedump: # type(uid) == int node = tree.get_node(uid) name = node.tag itemName = [name, str(uid)] parentUid = node.bpointer if node.data['a']: # Assembly if not parentUid: # This is the top level item parentItem = self.treeViewRoot else: parentItem = tempTreeDict[parentUid] item = QTreeWidgetItem(parentItem, itemName) item.setFlags(item.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) self.treeView.expandItem(item) tempTreeDict[uid] = item Loc = node.data['l'] # Location object self._assyDict[uid] = Loc else: # Part # add item to asyPrtTree treeView if not parentUid: # This is the top level item parentItem = self.treeViewRoot else: parentItem = tempTreeDict[parentUid] item = QTreeWidgetItem(parentItem, itemName) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(0, Qt.Checked) tempTreeDict[uid] = item color = node.data['c'] shape = node.data['s'] # Update dictionaries self._partDict[uid] = shape self._nameDict[uid] = name if color: c = OCC.Display.OCCViewer.rgb_color( color.Red(), color.Green(), color.Blue()) else: c = OCC.Display.OCCViewer.rgb_color(.2, .1, .1) # default color self._colorDict[uid] = c self.activePartUID = uid # Set as active part self.activePart = shape self.drawList.append(uid) # Add to draw list keyList = tempTreeDict.keys() keyList = list(keyList) keyList.sort() maxUID = keyList[-1] self._currentUID = maxUID self.redraw()
class FindFileDialog(QDialog, Ui_FindFileDialog): """ Class implementing a dialog to search for text in files. The occurrences found are displayed in a QTreeWidget showing the filename, the linenumber and the found text. The file will be opened upon a double click onto the respective entry of the list. @signal sourceFile(str, int, str, int, int) emitted to open a source file at a line @signal designerFile(str) emitted to open a Qt-Designer file """ sourceFile = pyqtSignal(str, int, str, int, int) designerFile = pyqtSignal(str) lineRole = Qt.UserRole + 1 startRole = Qt.UserRole + 2 endRole = Qt.UserRole + 3 replaceRole = Qt.UserRole + 4 md5Role = Qt.UserRole + 5 def __init__(self, project, replaceMode=False, parent=None): """ Constructor @param project reference to the project object @param replaceMode flag indicating the replace dialog mode (boolean) @param parent parent widget of this dialog (QWidget) """ super(FindFileDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.dirPicker.setMode(E5PathPickerModes.DirectoryMode) self.dirPicker.setInsertPolicy(QComboBox.InsertAtTop) self.dirPicker.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLength) self.__replaceMode = replaceMode self.stopButton = \ self.buttonBox.addButton(self.tr("Stop"), QDialogButtonBox.ActionRole) self.stopButton.setEnabled(False) self.findButton = \ self.buttonBox.addButton(self.tr("Find"), QDialogButtonBox.ActionRole) self.findButton.setEnabled(False) self.findButton.setDefault(True) if self.__replaceMode: self.replaceButton.setEnabled(False) self.setWindowTitle(self.tr("Replace in Files")) else: self.replaceLabel.hide() self.replacetextCombo.hide() self.replaceButton.hide() self.findProgressLabel.setMaximumWidth(550) self.findtextCombo.setCompleter(None) self.replacetextCombo.setCompleter(None) self.searchHistory = Preferences.toList( Preferences.Prefs.settings.value( "FindFileDialog/SearchHistory")) self.replaceHistory = Preferences.toList( Preferences.Prefs.settings.value( "FindFileDialog/ReplaceHistory")) self.dirHistory = Preferences.toList( Preferences.Prefs.settings.value( "FindFileDialog/DirectoryHistory")) self.findtextCombo.addItems(self.searchHistory) self.replacetextCombo.addItems(self.replaceHistory) self.dirPicker.addItems(self.dirHistory) self.project = project self.findList.headerItem().setText(self.findList.columnCount(), "") self.findList.header().setSortIndicator(0, Qt.AscendingOrder) self.__section0Size = self.findList.header().sectionSize(0) self.findList.setExpandsOnDoubleClick(False) if self.__replaceMode: font = Preferences.getEditorOtherFonts("MonospacedFont") self.findList.setFont(font) # Qt Designer form files self.filterForms = r'.*\.ui$' self.formsExt = ['*.ui'] # Corba interface files self.filterInterfaces = r'.*\.idl$' self.interfacesExt = ['*.idl'] # Qt resources files self.filterResources = r'.*\.qrc$' self.resourcesExt = ['*.qrc'] self.__cancelSearch = False self.__lastFileItem = None self.__populating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__contextMenuRequested) def __createItem(self, file, line, text, start, end, replTxt="", md5=""): """ Private method to create an entry in the file list. @param file filename of file (string) @param line line number (integer) @param text text found (string) @param start start position of match (integer) @param end end position of match (integer) @param replTxt text with replacements applied (string) @keyparam md5 MD5 hash of the file (string) """ if self.__lastFileItem is None: # It's a new file self.__lastFileItem = QTreeWidgetItem(self.findList, [file]) self.__lastFileItem.setFirstColumnSpanned(True) self.__lastFileItem.setExpanded(True) if self.__replaceMode: self.__lastFileItem.setFlags( self.__lastFileItem.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate)) # Qt bug: # item is not user checkable if setFirstColumnSpanned # is True (< 4.5.0) self.__lastFileItem.setData(0, self.md5Role, md5) itm = QTreeWidgetItem(self.__lastFileItem) itm.setTextAlignment(0, Qt.AlignRight) itm.setData(0, Qt.DisplayRole, line) itm.setData(1, Qt.DisplayRole, text) itm.setData(0, self.lineRole, line) itm.setData(0, self.startRole, start) itm.setData(0, self.endRole, end) itm.setData(0, self.replaceRole, replTxt) if self.__replaceMode: itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable)) itm.setCheckState(0, Qt.Checked) self.replaceButton.setEnabled(True) def show(self, txt=""): """ Public method to enable/disable the project button. @param txt text to be shown in the searchtext combo (string) """ if self.project and self.project.isOpen(): self.projectButton.setEnabled(True) else: self.projectButton.setEnabled(False) self.dirButton.setChecked(True) self.findtextCombo.setEditText(txt) self.findtextCombo.lineEdit().selectAll() self.findtextCombo.setFocus() if self.__replaceMode: self.findList.clear() self.replacetextCombo.setEditText("") super(FindFileDialog, self).show() def on_findtextCombo_editTextChanged(self, text): """ Private slot to handle the editTextChanged signal of the find text combo. @param text (ignored) """ self.__enableFindButton() def on_replacetextCombo_editTextChanged(self, text): """ Private slot to handle the editTextChanged signal of the replace text combo. @param text (ignored) """ self.__enableFindButton() def on_dirPicker_editTextChanged(self, text): """ Private slot to handle the textChanged signal of the directory picker. @param text (ignored) """ self.__enableFindButton() @pyqtSlot() def on_projectButton_clicked(self): """ Private slot to handle the selection of the project radio button. """ self.__enableFindButton() @pyqtSlot() def on_dirButton_clicked(self): """ Private slot to handle the selection of the project radio button. """ self.__enableFindButton() @pyqtSlot() def on_filterCheckBox_clicked(self): """ Private slot to handle the selection of the file filter check box. """ self.__enableFindButton() @pyqtSlot(str) def on_filterEdit_textEdited(self, text): """ Private slot to handle the textChanged signal of the file filter edit. @param text (ignored) """ self.__enableFindButton() def __enableFindButton(self): """ Private slot called to enable the find button. """ if self.findtextCombo.currentText() == "" or \ (self.__replaceMode and self.replacetextCombo.currentText() == "") or \ (self.dirButton.isChecked() and (self.dirPicker.currentText() == "" or not os.path.exists(os.path.abspath( self.dirPicker.currentText())))) or \ (self.filterCheckBox.isChecked() and self.filterEdit.text() == ""): self.findButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) else: self.findButton.setEnabled(True) self.findButton.setDefault(True) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.findButton: self.__doSearch() elif button == self.stopButton: self.__stopSearch() def __stripEol(self, txt): """ Private method to strip the eol part. @param txt line of text that should be treated (string) @return text with eol stripped (string) """ return txt.replace("\r", "").replace("\n", "") def __stopSearch(self): """ Private slot to handle the stop button being pressed. """ self.__cancelSearch = True def __doSearch(self): """ Private slot to handle the find button being pressed. """ if self.__replaceMode and \ not e5App().getObject("ViewManager").checkAllDirty(): return self.__cancelSearch = False if self.filterCheckBox.isChecked(): fileFilter = self.filterEdit.text() fileFilterList = \ ["^{0}$".format(filter.replace(".", "\.").replace("*", ".*")) for filter in fileFilter.split(";")] filterRe = re.compile("|".join(fileFilterList)) if self.projectButton.isChecked(): if self.filterCheckBox.isChecked(): files = [self.project.getRelativePath(file) for file in self.__getFileList( self.project.getProjectPath(), filterRe)] else: files = [] if self.sourcesCheckBox.isChecked(): files += self.project.pdata["SOURCES"] if self.formsCheckBox.isChecked(): files += self.project.pdata["FORMS"] if self.interfacesCheckBox.isChecked(): files += self.project.pdata["INTERFACES"] if self.resourcesCheckBox.isChecked(): files += self.project.pdata["RESOURCES"] elif self.dirButton.isChecked(): if not self.filterCheckBox.isChecked(): filters = [] if self.sourcesCheckBox.isChecked(): filters.extend( ["^{0}$".format( assoc.replace(".", "\.").replace("*", ".*")) for assoc in list( Preferences.getEditorLexerAssocs().keys()) if assoc not in self.formsExt + self.interfacesExt]) if self.formsCheckBox.isChecked(): filters.append(self.filterForms) if self.interfacesCheckBox.isChecked(): filters.append(self.filterInterfaces) if self.resourcesCheckBox.isChecked(): filters.append(self.filterResources) filterString = "|".join(filters) filterRe = re.compile(filterString) files = self.__getFileList( os.path.abspath(self.dirPicker.currentText()), filterRe) elif self.openFilesButton.isChecked(): vm = e5App().getObject("ViewManager") vm.checkAllDirty() files = vm.getOpenFilenames() self.findList.clear() QApplication.processEvents() QApplication.processEvents() self.findProgress.setMaximum(len(files)) # retrieve the values reg = self.regexpCheckBox.isChecked() wo = self.wordCheckBox.isChecked() cs = self.caseCheckBox.isChecked() ct = self.findtextCombo.currentText() if reg: txt = ct else: txt = re.escape(ct) if wo: txt = "\\b{0}\\b".format(txt) flags = re.UNICODE | re.LOCALE if not cs: flags |= re.IGNORECASE try: search = re.compile(txt, flags) except re.error as why: E5MessageBox.critical( self, self.tr("Invalid search expression"), self.tr("""<p>The search expression is not valid.</p>""" """<p>Error: {0}</p>""").format(str(why))) self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) return # reset the findtextCombo if ct in self.searchHistory: self.searchHistory.remove(ct) self.searchHistory.insert(0, ct) self.findtextCombo.clear() self.findtextCombo.addItems(self.searchHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/SearchHistory", self.searchHistory[:30]) if self.__replaceMode: replTxt = self.replacetextCombo.currentText() if replTxt in self.replaceHistory: self.replaceHistory.remove(replTxt) self.replaceHistory.insert(0, replTxt) self.replacetextCombo.clear() self.replacetextCombo.addItems(self.replaceHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/ReplaceHistory", self.replaceHistory[:30]) if self.dirButton.isChecked(): searchDir = self.dirPicker.currentText() if searchDir in self.dirHistory: self.dirHistory.remove(searchDir) self.dirHistory.insert(0, searchDir) self.dirPicker.clear() self.dirPicker.addItems(self.dirHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/DirectoryHistory", self.dirHistory[:30]) # set the button states self.stopButton.setEnabled(True) self.stopButton.setDefault(True) self.findButton.setEnabled(False) # now go through all the files self.__populating = True self.findList.setUpdatesEnabled(False) progress = 0 breakSearch = False occurrences = 0 fileOccurrences = 0 for file in files: self.__lastFileItem = None found = False if self.__cancelSearch or breakSearch: break self.findProgressLabel.setPath(file) if self.projectButton.isChecked(): fn = os.path.join(self.project.ppath, file) else: fn = file # read the file and split it into textlines try: text, encoding, hash = Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError): progress += 1 self.findProgress.setValue(progress) continue # now perform the search and display the lines found count = 0 for line in lines: if self.__cancelSearch: break count += 1 contains = search.search(line) if contains: occurrences += 1 found = True start = contains.start() end = contains.end() if self.__replaceMode: rline = search.sub(replTxt, line) else: rline = "" line = self.__stripEol(line) if len(line) > 1024: line = "{0} ...".format(line[:1024]) if self.__replaceMode: if len(rline) > 1024: rline = "{0} ...".format(line[:1024]) line = "- {0}\n+ {1}".format( line, self.__stripEol(rline)) self.__createItem(file, count, line, start, end, rline, hash) if self.feelLikeCheckBox.isChecked(): fn = os.path.join(self.project.ppath, file) self.sourceFile.emit(fn, count, "", start, end) QApplication.processEvents() breakSearch = True break QApplication.processEvents() if found: fileOccurrences += 1 progress += 1 self.findProgress.setValue(progress) if not files: self.findProgress.setMaximum(1) self.findProgress.setValue(1) resultFormat = self.tr("{0} / {1}", "occurrences / files") self.findProgressLabel.setPath(resultFormat.format( self.tr("%n occurrence(s)", "", occurrences), self.tr("%n file(s)", "", fileOccurrences))) self.findList.setUpdatesEnabled(True) self.findList.sortItems(self.findList.sortColumn(), self.findList.header().sortIndicatorOrder()) self.findList.resizeColumnToContents(1) if self.__replaceMode: self.findList.header().resizeSection(0, self.__section0Size + 30) self.findList.header().setStretchLastSection(True) self.__populating = False self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) if breakSearch: self.close() def on_findList_itemDoubleClicked(self, itm, column): """ Private slot to handle the double click on a file item. It emits the signal sourceFile or designerFile depending on the file extension. @param itm the double clicked tree item (QTreeWidgetItem) @param column column that was double clicked (integer) (ignored) """ if itm.parent(): file = itm.parent().text(0) line = itm.data(0, self.lineRole) start = itm.data(0, self.startRole) end = itm.data(0, self.endRole) else: file = itm.text(0) line = 1 start = 0 end = 0 if self.project: fn = os.path.join(self.project.ppath, file) else: fn = file if fn.endswith('.ui'): self.designerFile.emit(fn) else: self.sourceFile.emit(fn, line, "", start, end) def __getFileList(self, path, filterRe): """ Private method to get a list of files to search. @param path the root directory to search in (string) @param filterRe regular expression defining the filter criteria (regexp object) @return list of files to be processed (list of strings) """ path = os.path.abspath(path) files = [] for dirname, _, names in os.walk(path): files.extend([os.path.join(dirname, f) for f in names if re.match(filterRe, f)] ) return files def setSearchDirectory(self, searchDir): """ Public slot to set the name of the directory to search in. @param searchDir name of the directory to search in (string) """ self.dirButton.setChecked(True) self.dirPicker.setEditText(Utilities.toNativeSeparators(searchDir)) def setOpenFiles(self): """ Public slot to set the mode to search in open files. """ self.openFilesButton.setChecked(True) @pyqtSlot() def on_replaceButton_clicked(self): """ Private slot to perform the requested replace actions. """ self.findProgress.setMaximum(self.findList.topLevelItemCount()) self.findProgress.setValue(0) progress = 0 for index in range(self.findList.topLevelItemCount()): itm = self.findList.topLevelItem(index) if itm.checkState(0) in [Qt.PartiallyChecked, Qt.Checked]: file = itm.text(0) origHash = itm.data(0, self.md5Role) self.findProgressLabel.setPath(file) if self.projectButton.isChecked(): fn = os.path.join(self.project.ppath, file) else: fn = file # read the file and split it into textlines try: text, encoding, hash = \ Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>Could not read the file <b>{0}</b>.""" """ Skipping it.</p><p>Reason: {1}</p>""") .format(fn, str(err)) ) progress += 1 self.findProgress.setValue(progress) continue # Check the original and the current hash. Skip the file, # if hashes are different. if origHash != hash: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>The current and the original hash of the""" """ file <b>{0}</b> are different. Skipping it.""" """</p><p>Hash 1: {1}</p><p>Hash 2: {2}</p>""") .format(fn, origHash, hash) ) progress += 1 self.findProgress.setValue(progress) continue # replace the lines authorized by the user for cindex in range(itm.childCount()): citm = itm.child(cindex) if citm.checkState(0) == Qt.Checked: line = citm.data(0, self.lineRole) rline = citm.data(0, self.replaceRole) lines[line - 1] = rline # write the file txt = "".join(lines) try: Utilities.writeEncodedFile(fn, txt, encoding) except (IOError, Utilities.CodingError, UnicodeError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>Could not save the file <b>{0}</b>.""" """ Skipping it.</p><p>Reason: {1}</p>""") .format(fn, str(err)) ) progress += 1 self.findProgress.setValue(progress) self.findProgressLabel.setPath("") self.findList.clear() self.replaceButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) def __contextMenuRequested(self, pos): """ Private slot to handle the context menu request. @param pos position the context menu shall be shown (QPoint) """ menu = QMenu(self) menu.addAction(self.tr("Open"), self.__openFile) menu.addAction(self.tr("Copy Path to Clipboard"), self.__copyToClipboard) menu.exec_(QCursor.pos()) def __openFile(self): """ Private slot to open the currently selected entry. """ itm = self.findList.selectedItems()[0] self.on_findList_itemDoubleClicked(itm, 0) def __copyToClipboard(self): """ Private method to copy the path of an entry to the clipboard. """ itm = self.findList.selectedItems()[0] if itm.parent(): fn = itm.parent().text(0) else: fn = itm.text(0) cb = QApplication.clipboard() cb.setText(fn)
class Waterfall(QWidget, waterfall.Ui_Waterfall): plot_settings_signal = QtCore.pyqtSignal(list) #send list of plotting params updated_rectangles_signal = QtCore.pyqtSignal(list) #send list of updated artists for redrawing def __init__(self, parent): super(Waterfall,self).__init__(parent) self.setupUi(self) self.get_settings() #self.send_settings() #Button functions self.btn_apply_general_settings.clicked.connect(self.send_settings) self.btn_apply_keys_and_colors_settings.clicked.connect(self.send_settings) self.patient_tree = self.create_patient_tree() self.data_viewer_container.addWidget(self.patient_tree) self.btn_color_test.clicked.connect(self.get_color) def get_color(self): self.color = QColorDialog.getColor() #returns a color object print(color) def get_settings(self): try: with shelve.open('WaterfallSettings') as shelfFile: self.keys_and_colors = shelfFile['keys_and_colors'] shelfFile.close() except: #set and use default settings self.keys_and_colors = { 'CR':'#03945D', 'PR':'#B1EE97', 'PD':'#FF6F69', 'SD':'#707070'} with shelve.open('WaterfallSettings') as shelfFile: shelfFile['keys_and_colors'] = self.keys_and_colors shelfFile.close() def on_waterfall_data_signal(self,signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe def on_generated_rectangles_signal(self,signal): self.rectangles_received = signal[0] self.add_items() #display in table self.btn_apply_general_settings.setEnabled(True) self.btn_finalize_plot.setEnabled(True) self.btn_apply_keys_and_colors_settings.setEnabled(True) def send_settings(self): ''' Emit both general plot settings, and color labeling settings. These are the settings to be used when the plot is created. ''' print(self.get_updated_color_coding() self.general_settings = [ self.plot_title.text(), self.x_label.text(), self.y_label.text(), [self.twenty_percent_line.isChecked(), self.thirty_percent_line.isChecked(), self.zero_percent_line.isChecked()], [self.display_responses_as_text.isChecked(), self.display_responses_as_color.isChecked(), self.display_no_responses.isChecked()], self.include_table.isChecked(), self.show_cancer_type.isChecked() ] self.plot_settings_signal.emit(self.general_settings) def create_patient_tree(self): ''' Create QTreeWidget populated with a patient's data for the DataEntry dialog. Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog. ''' self.tree = QTreeWidget() self.root = self.tree.invisibleRootItem() self.headers = [ 'Patient #', 'Best response %', 'Response', 'Cancer', 'Color key', ] self.headers_item = QTreeWidgetItem(self.headers) self.tree.setColumnCount(len(self.headers)) self.tree.setHeaderItem(self.headers_item) self.root.setExpanded(True) self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) return self.tree def add_items(self): ''' Populate viewing tree ''' self.tree.clear() #clear prior to entering items, prevent aggregation i=0 for rect in self.rectangles_received: #populate editable tree with rect data self.rect_item = QTreeWidgetItem(self.root) self.rect_params = [ self.waterfall_data['Patient number'][i], rect.get_height(), self.waterfall_data['Overall response'][i], self.waterfall_data['Cancer'][i] ] for col in range(0,4): self.rect_item.setText(col,str(self.rect_params[col])) self.rect_item.setTextAlignment(col,4) self.tree.setItemWidget(self.rect_item, 4, CustomCombo(self,self.keys_and_colors,self.waterfall_data['Overall response'][i])) self.rect_item.setFlags(self.rect_item.flags() | QtCore.Qt.ItemIsEditable) i+=1 def get_updated_color_coding(self): tmp_updated_color_coding = [] self.root = self.tree.invisibleRootItem() child_count = self.root.childCount() # for i in range(child_count): # child_item = self.root.child(i) # self.tree.itemWidget(self.root.child(i),4).currentText() return [self.tree.itemWidget(self.root.child(i),4).currentText() for i in range(child_count)] def on_updated_tree_item(self): #update the rectangle which was edited pass class WaterfallPlotter(QWidget): generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree def __init__(self,parent): super(WaterfallPlotter,self).__init__(parent) self.get_settings() self.settings_update = False self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas,self) self.btn_plot = QPushButton('Default Plot') self.btn_plot.clicked.connect(self.default_plot) self.layout = QVBoxLayout() self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.layout.addWidget(self.btn_plot) self.setLayout(self.layout) def on_waterfall_data_signal(self,signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe self.btn_plot.setEnabled(True) def get_settings(self): try: with shelve.open('WaterfallSettings') as shelfFile: self.keys_and_colors = shelfFile['keys_and_colors'] shelfFile.close() except: #set and use default settings self.keys_and_colors = { 'CR':'#03945D', 'PR':'#B1EE97', 'PD':'#FF6F69', 'SD':'#707070'} with shelve.open('WaterfallSettings') as shelfFile: shelfFile['keys_and_colors'] = self.keys_and_colors shelfFile.close() def on_general_settings_signal(self,signal): self.gen_settings = signal self.settings_update = True self.default_plot() def get_bar_colors(self,responses): return [self.keys_and_colors[x] for x in responses] def default_plot(self): ''' Plot waterfall data ''' self.figure.clear() self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change'])) self.ax = self.figure.add_subplot(111) self.bar_colors = self.get_bar_colors(self.waterfall_data['Overall response']) if self.settings_update == False: self.ax.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='on', # ticks along the bottom edge are off top='on', # ticks along the top edge are off labelbottom='on' ) # labels along the bottom edge are off self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent') self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent') self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent') self.ax.grid(color = 'k', axis = 'y', alpha=0.25) self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors) else: #settings were updated, we received them and stored in variable self.gen_settings self.ax.set_title(self.gen_settings[0]) self.ax.set_xlabel(self.gen_settings[1]) self.ax.set_ylabel(self.gen_settings[2]) if self.gen_settings[3][0]: self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent') if self.gen_settings[3][1]: self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent') if self.gen_settings[3][2]: self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent') if self.gen_settings[4][0] and ~self.gen_settings[6]: #show responses as labels, default color bars #legend depends on user specified keys self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change']) self.add_labels(self.ax, self.rects, self.waterfall_data, 1) elif self.gen_settings[4][1]: #color bars with response type self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors) self.patches = [] for key in self.keys_and_colors.keys(): self.patches.append(mpatches.Patch(color = self.keys_and_colors[key],label=key)) self.ax.legend(handles=self.patches) else: self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change']) if self.gen_settings[5]: self.plot_table() if self.gen_settings[6] and ~self.gen_settings[4][0]: self.add_labels(self.ax, self.rects, self.waterfall_data, 0) if ~self.gen_settings[4][1]: #response not shown as color coding, custom color code the bars pass self.ax.grid(color = 'k', axis = 'y', alpha=0.25) self.canvas.draw() self.generated_rectangles_signal.emit([self.rects]) def plot_table(self): rows = ['%s' % x for x in self.waterfall_data.keys()] rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows columns = self.waterfall_data['Patient number'] #patient numbers cell_text = [] for row in rows: cell_text_temp = [] for col in range(len(columns)): cell_text_temp.append(self.waterfall_data[row][col]) cell_text.append(cell_text_temp) the_table = self.ax.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center', colLoc='center') plt.subplots_adjust(bottom=0.15,left=0.5) self.ax.set_xlim(-0.5,len(columns)-0.5) self.ax.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom='off', # ticks along the bottom edge are off top='off', # ticks along the top edge are off labelbottom='off' ) # labels along the bottom edge are off def update_plot(self): ''' TODO ''' pass def add_labels(self, ax, rects, waterfall_data, label_type): ''' Add labels above/below bars. label_type == 1 --> display responses; == 0 --> display cancer type ''' i = 0 if label_type: for rect in rects: height = rect.get_height() if height >= 0: valign = 'bottom' else: valign = 'top' ax.text(rect.get_x() + rect.get_width()/2., height, '%s' % waterfall_data['Overall response'][i], ha='center', va=valign) i+=1 else: for rect in rects: height = rect.get_height() if height >= 0: valign = 'top' hgt = -1 else: valign = 'bottom' hgt = 1 ax.text(rect.get_x() + rect.get_width()/2., hgt, '%s' % waterfall_data['Cancer'][i], ha='center', va=valign, rotation='vertical') i+=1
def load_data_func(self): calibration_prefixes, sample_prefixes = self.get_prefixes_from_tables() # Load drift data drift_path = self.load_drift_file_lineEdit.text() self.datasets.read_drift_data(drift_path) drift_data = self.datasets.get_drift_data() self.driftDataModel = PandasModel(drift_data) self.driftDataTableView.setModel(self.driftDataModel) self.driftDataTableView.show() # Fill session tree session_files = self.datasets.get_session_dict() unique_sessions = self.datasets.get_sessions() tree = self.sessionTreeWidget tree.clear() for s in unique_sessions: session_item = QTreeWidgetItem(tree) session_item.setText(0, s) session_item.setFlags(session_item.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) files = session_files[s] for f in files: file_item = QTreeWidgetItem(session_item) file_item.setFlags(file_item.flags() | Qt.ItemIsUserCheckable) file_item.setText(0, f) file_item.setCheckState(0, Qt.Unchecked) tree.setHeaderLabel("Session") self.sessionTreeWidget.doubleClicked.connect( self.onSessionTreeDoubleClick) # Load calibration data calibration_path = self.load_calibration_file_lineEdit.text() self.datasets.read_calibration_data(calibration_path) calibration_data = self.datasets.get_calibration_data() self.calibrationDataModel = PandasModel(calibration_data) self.calibrationDataTableView.setModel(self.calibrationDataModel) self.calibrationDataTableView.show() # Load datasets datasets_path = self.load_dir_lineEdit.text() self.datasets.read_datasets(datasets_path) # Load elements tree tree = self.labelElementsTreeWidget tree.clear() elements = [ e for e in next(iter(self.datasets.get_datasets().values())).columns if e.lower() not in ['time', 'delay'] ] for e in elements: item = QTreeWidgetItem(tree) item.setText(0, e) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) if e.lower()[:4] in ['mg24', 'ca43', 'ca44']: item.setCheckState(0, Qt.Checked) else: item.setCheckState(0, Qt.Unchecked)
def _populate_repo_tree(self): """ Initialize the tree widget of repos and volumes. """ self._repo_treewidget.clear() if self._repos_info is None: return for repo_uuid, repo_info in sorted(self._repos_info.items()): if repo_info is None: continue repo_column_dict = collections.defaultdict(str) repo_column_dict["Alias"] = repo_info["Alias"] repo_column_dict["Details"] = "Created: " + repo_info["Created"] repo_column_dict["UUID"] = repo_uuid repo_column_values = [ repo_column_dict[k] for k in TREEVIEW_COLUMNS ] repo_item = QTreeWidgetItem(self._repo_treewidget, repo_column_values) repo_item.setData(0, Qt.UserRole, (repo_uuid, "", "")) for data_name, data_info in repo_info["DataInstances"].items(): data_instance_dict = collections.defaultdict(str) data_instance_dict["Alias"] = data_name typename = data_info["Base"]["TypeName"] data_instance_dict["TypeName"] = typename is_voxels = (typename in VOXEL_TYPENAMES) if is_voxels: start_coord = data_info["Extended"]["MinPoint"] if start_coord: start_coord = tuple(start_coord) stop_coord = data_info["Extended"]["MaxPoint"] if stop_coord: stop_coord = tuple(x + 1 for x in stop_coord) if start_coord and stop_coord: shape = tuple(b - a for a, b in zip(start_coord, stop_coord)) else: shape = None data_instance_dict[ "Details"] = "Size={} | Start={} | Stop={}".format( shape, start_coord, stop_coord) data_column_values = [ data_instance_dict[k] for k in TREEVIEW_COLUMNS ] data_item = QTreeWidgetItem(repo_item, data_column_values) data_item.setData(0, Qt.UserRole, (repo_uuid, data_name, typename)) # If we're in specify_new mode, only the # repo parent items are selectable. # Also, non-volume items aren't selectable. if self._mode == 'specify_new' or typename not in self._selectable_types: flags = data_item.flags() flags &= ~Qt.ItemIsSelectable flags &= ~Qt.ItemIsEnabled data_item.setFlags(flags) self._repo_treewidget.collapseAll() self._repo_treewidget.setSortingEnabled(True) if self._hostname in self._default_nodes: self._select_node_uuid(self._default_nodes[self._hostname]) self._repo_treewidget.resizeColumnToContents(0) self._repo_treewidget.setFocus()
def populate_available_terms(self): """ Runs when annotations tab is viewed and when volume is changed. Populates the avaible annotation terms. """ self.ui.treeWidgetAvailableTerms.clear() vol = self.controller.current_annotation_volume() if not vol or None in (vol.annotations.stage, vol.annotations.center): # info_dialog(self, 'Chose centre and stage', 'You must choose a centre and stage from the options tab') return self.ui.lineEditCentre.setText(vol.annotations.center) self.ui.lineEditStage.setText(vol.annotations.stage.name) self.ui.lineEditModality.setText(vol.annotations.modality.value) def setup_option_box_signal(box_: QComboBox, child_: QTreeWidgetItem): """ Connect the Qcombobox to a slot """ box_.activated.connect( partial(self.update_annotation, child_, box_)) # Setup signal so when combobox is only opened, it sets the selection to that column box_.highlighted.connect(partial(self.on_box_highlight, child)) header_labels = QTreeWidgetItem( ['', 'term', 'name', 'option', 'done?']) self.ui.treeWidgetAvailableTerms.setHeaderItem(header_labels) parent = QTreeWidgetItem(self.ui.treeWidgetAvailableTerms) parent.setText(0, '') parent.setFlags(parent.flags()) parent.setExpanded(True) header = self.ui.treeWidgetAvailableTerms.header() # Set root column to invisible self.ui.treeWidgetAvailableTerms.setColumnWidth(0, 0) header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) # For each annotation set an info row in the annotations table for i, ann in enumerate( sorted(vol.annotations, key=lambda an_: an_.order)): child = QTreeWidgetItem(parent) child.setText(1, ann.term) child.setText(3, ann.name) option = ann.selected_option # color = OPTION_COLOR_MAP[option] parent.addChild(child) # Set up the parameter option combobox and highlight the currently selected one options_box = QComboBox() options_box.setSizeAdjustPolicy(QComboBox.AdjustToContents) for opt in ann.options: options_box.addItem(opt) options_box.setCurrentIndex(options_box.findText( option)) # 060818 Louise's bug option is a bool not a str # Setup combobox selection signal setup_option_box_signal(options_box, child) self.ui.treeWidgetAvailableTerms.setItemWidget( child, 2, options_box) done_checkbox = QtWidgets.QCheckBox() done_checkbox.setChecked(ann.looked_at) done_checkbox.stateChanged.connect( partial(self.parameter_done_signal, child, done_checkbox)) self.ui.treeWidgetAvailableTerms.setItemWidget( child, 4, done_checkbox) # Set the roi coords to None self.roi_highlight_off_signal.emit()
class PatientTree(QTreeWidget): def __init__(self,pt): QWidget.__init__(self) self.tree = QTreeWidget() self.root = self.tree.invisibleRootItem() self.headers = [ 'Exam', 'Follow-Up', 'Name', 'Description', 'Target', 'Sub-Type', 'Series', 'Slice#', 'RECIST Diameter (cm)' ] self.headers_item = QTreeWidgetItem(self.headers) self.tree.setColumnCount(len(self.headers)) self.tree.setHeaderItem(self.headers_item) self.root.setExpanded(True) self.addItems(self.root,pt) self.tree.header().setResizeMode(QtGui.QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) layout = QStackedLayout() layout.addWidget(self.tree) self.setLayout(layout) def addItems(self,parent,pt): ''' Add items to the table from the patient object ''' for key,exam in pt.exams.items(): column = 0 self.exam_item = QTreeWidgetItem(parent) self.exam_item.setText(column,', '.join([str(exam.date),str(exam.modality),str(exam.description)])) if exam.ignore == False: self.exam_item.setCheckState (column, QtCore.Qt.Checked) else: self.exam_item.setCheckState (column, QtCore.Qt.Unchecked) for lesion in exam.lesions: column = 1 if lesion.params['Target'].lower() == 'target' or lesion.params['Target'].lower() == 'non-target': self.param_list = [ lesion.params['Follow-Up'], lesion.params['Name'], lesion.params['Description'], lesion.params['Target'], lesion.params['Sub-Type'], lesion.params['Series'], lesion.params['Slice#'], round(lesion.params['RECIST Diameter (mm)']/10,1) ] self.lesion_item = QTreeWidgetItem(self.exam_item) self.lesion_item.setCheckState(column,QtCore.Qt.Checked) for param_str in self.param_list: self.lesion_item.setText(column,str(self.param_list[column-1])) self.lesion_item.setTextAlignment(column,4) #align center of column column += 1 self.lesion_item.setFlags(self.lesion_item.flags() | QtCore.Qt.ItemIsEditable)
def add_root_item(self): item = QTreeWidgetItem(self, ['New Item']) item.setFlags(item.flags() | Qt.ItemIsEditable) self.addTopLevelItem(item) self.setCurrentItem(item) self.editItem(item)
def addItemToTreeView(self, name, uid): itemName = [name, str(uid)] item = QTreeWidgetItem(self.treeViewRoot, itemName) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(0, Qt.Checked)
class FindFileDialog(QDialog, Ui_FindFileDialog): """ Class implementing a dialog to search for text in files. The occurrences found are displayed in a QTreeWidget showing the filename, the linenumber and the found text. The file will be opened upon a double click onto the respective entry of the list. @signal sourceFile(str, int, str, int, int) emitted to open a source file at a line @signal designerFile(str) emitted to open a Qt-Designer file """ sourceFile = pyqtSignal(str, int, str, int, int) designerFile = pyqtSignal(str) lineRole = Qt.UserRole + 1 startRole = Qt.UserRole + 2 endRole = Qt.UserRole + 3 replaceRole = Qt.UserRole + 4 md5Role = Qt.UserRole + 5 def __init__(self, project, replaceMode=False, parent=None): """ Constructor @param project reference to the project object @param replaceMode flag indicating the replace dialog mode (boolean) @param parent parent widget of this dialog (QWidget) """ super(FindFileDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.dirSelectButton.setIcon(UI.PixmapCache.getIcon("open.png")) self.__replaceMode = replaceMode self.stopButton = \ self.buttonBox.addButton(self.tr("Stop"), QDialogButtonBox.ActionRole) self.stopButton.setEnabled(False) self.findButton = \ self.buttonBox.addButton(self.tr("Find"), QDialogButtonBox.ActionRole) self.findButton.setEnabled(False) self.findButton.setDefault(True) if self.__replaceMode: self.replaceButton.setEnabled(False) self.setWindowTitle(self.tr("Replace in Files")) else: self.replaceLabel.hide() self.replacetextCombo.hide() self.replaceButton.hide() self.findProgressLabel.setMaximumWidth(550) self.findtextCombo.setCompleter(None) self.replacetextCombo.setCompleter(None) self.searchHistory = Preferences.toList( Preferences.Prefs.settings.value("FindFileDialog/SearchHistory")) self.replaceHistory = Preferences.toList( Preferences.Prefs.settings.value("FindFileDialog/ReplaceHistory")) self.dirHistory = Preferences.toList( Preferences.Prefs.settings.value( "FindFileDialog/DirectoryHistory")) self.findtextCombo.addItems(self.searchHistory) self.replacetextCombo.addItems(self.replaceHistory) self.dirCombo.addItems(self.dirHistory) self.project = project self.findList.headerItem().setText(self.findList.columnCount(), "") self.findList.header().setSortIndicator(0, Qt.AscendingOrder) self.__section0Size = self.findList.header().sectionSize(0) self.findList.setExpandsOnDoubleClick(False) if self.__replaceMode: font = Preferences.getEditorOtherFonts("MonospacedFont") self.findList.setFont(font) # Qt Designer form files self.filterForms = r'.*\.ui$' self.formsExt = ['*.ui'] # Corba interface files self.filterInterfaces = r'.*\.idl$' self.interfacesExt = ['*.idl'] # Qt resources files self.filterResources = r'.*\.qrc$' self.resourcesExt = ['*.qrc'] self.__cancelSearch = False self.__lastFileItem = None self.__populating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__contextMenuRequested) def __createItem(self, file, line, text, start, end, replTxt="", md5=""): """ Private method to create an entry in the file list. @param file filename of file (string) @param line line number (integer) @param text text found (string) @param start start position of match (integer) @param end end position of match (integer) @param replTxt text with replacements applied (string) @keyparam md5 MD5 hash of the file (string) """ if self.__lastFileItem is None: # It's a new file self.__lastFileItem = QTreeWidgetItem(self.findList, [file]) self.__lastFileItem.setFirstColumnSpanned(True) self.__lastFileItem.setExpanded(True) if self.__replaceMode: self.__lastFileItem.setFlags( self.__lastFileItem.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate)) # Qt bug: # item is not user checkable if setFirstColumnSpanned # is True (< 4.5.0) self.__lastFileItem.setData(0, self.md5Role, md5) itm = QTreeWidgetItem(self.__lastFileItem) itm.setTextAlignment(0, Qt.AlignRight) itm.setData(0, Qt.DisplayRole, line) itm.setData(1, Qt.DisplayRole, text) itm.setData(0, self.lineRole, line) itm.setData(0, self.startRole, start) itm.setData(0, self.endRole, end) itm.setData(0, self.replaceRole, replTxt) if self.__replaceMode: itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable)) itm.setCheckState(0, Qt.Checked) self.replaceButton.setEnabled(True) def show(self, txt=""): """ Public method to enable/disable the project button. @param txt text to be shown in the searchtext combo (string) """ if self.project and self.project.isOpen(): self.projectButton.setEnabled(True) else: self.projectButton.setEnabled(False) self.dirButton.setChecked(True) self.findtextCombo.setEditText(txt) self.findtextCombo.lineEdit().selectAll() self.findtextCombo.setFocus() if self.__replaceMode: self.findList.clear() self.replacetextCombo.setEditText("") super(FindFileDialog, self).show() def on_findtextCombo_editTextChanged(self, text): """ Private slot to handle the editTextChanged signal of the find text combo. @param text (ignored) """ self.__enableFindButton() def on_replacetextCombo_editTextChanged(self, text): """ Private slot to handle the editTextChanged signal of the replace text combo. @param text (ignored) """ self.__enableFindButton() def on_dirCombo_editTextChanged(self, text): """ Private slot to handle the textChanged signal of the directory combo box. @param text (ignored) """ self.__enableFindButton() @pyqtSlot() def on_projectButton_clicked(self): """ Private slot to handle the selection of the project radio button. """ self.__enableFindButton() @pyqtSlot() def on_dirButton_clicked(self): """ Private slot to handle the selection of the project radio button. """ self.__enableFindButton() @pyqtSlot() def on_filterCheckBox_clicked(self): """ Private slot to handle the selection of the file filter check box. """ self.__enableFindButton() @pyqtSlot(str) def on_filterEdit_textEdited(self, text): """ Private slot to handle the textChanged signal of the file filter edit. @param text (ignored) """ self.__enableFindButton() def __enableFindButton(self): """ Private slot called to enable the find button. """ if self.findtextCombo.currentText() == "" or \ (self.__replaceMode and self.replacetextCombo.currentText() == "") or \ (self.dirButton.isChecked() and (self.dirCombo.currentText() == "" or not os.path.exists(os.path.abspath( self.dirCombo.currentText())))) or \ (self.filterCheckBox.isChecked() and self.filterEdit.text() == ""): self.findButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) else: self.findButton.setEnabled(True) self.findButton.setDefault(True) def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.findButton: self.__doSearch() elif button == self.stopButton: self.__stopSearch() def __stripEol(self, txt): """ Private method to strip the eol part. @param txt line of text that should be treated (string) @return text with eol stripped (string) """ return txt.replace("\r", "").replace("\n", "") def __stopSearch(self): """ Private slot to handle the stop button being pressed. """ self.__cancelSearch = True def __doSearch(self): """ Private slot to handle the find button being pressed. """ if self.__replaceMode and \ not e5App().getObject("ViewManager").checkAllDirty(): return self.__cancelSearch = False if self.filterCheckBox.isChecked(): fileFilter = self.filterEdit.text() fileFilterList = \ ["^{0}$".format(filter.replace(".", "\.").replace("*", ".*")) for filter in fileFilter.split(";")] filterRe = re.compile("|".join(fileFilterList)) if self.projectButton.isChecked(): if self.filterCheckBox.isChecked(): files = [ self.project.getRelativePath(file) for file in self.__getFileList( self.project.getProjectPath(), filterRe) ] else: files = [] if self.sourcesCheckBox.isChecked(): files += self.project.pdata["SOURCES"] if self.formsCheckBox.isChecked(): files += self.project.pdata["FORMS"] if self.interfacesCheckBox.isChecked(): files += self.project.pdata["INTERFACES"] if self.resourcesCheckBox.isChecked(): files += self.project.pdata["RESOURCES"] elif self.dirButton.isChecked(): if not self.filterCheckBox.isChecked(): filters = [] if self.sourcesCheckBox.isChecked(): filters.extend([ "^{0}$".format( assoc.replace(".", "\.").replace("*", ".*")) for assoc in list( Preferences.getEditorLexerAssocs().keys()) if assoc not in self.formsExt + self.interfacesExt ]) if self.formsCheckBox.isChecked(): filters.append(self.filterForms) if self.interfacesCheckBox.isChecked(): filters.append(self.filterInterfaces) if self.resourcesCheckBox.isChecked(): filters.append(self.filterResources) filterString = "|".join(filters) filterRe = re.compile(filterString) files = self.__getFileList( os.path.abspath(self.dirCombo.currentText()), filterRe) elif self.openFilesButton.isChecked(): vm = e5App().getObject("ViewManager") vm.checkAllDirty() files = vm.getOpenFilenames() self.findList.clear() QApplication.processEvents() QApplication.processEvents() self.findProgress.setMaximum(len(files)) # retrieve the values reg = self.regexpCheckBox.isChecked() wo = self.wordCheckBox.isChecked() cs = self.caseCheckBox.isChecked() ct = self.findtextCombo.currentText() if reg: txt = ct else: txt = re.escape(ct) if wo: txt = "\\b{0}\\b".format(txt) flags = re.UNICODE | re.LOCALE if not cs: flags |= re.IGNORECASE try: search = re.compile(txt, flags) except re.error as why: E5MessageBox.critical( self, self.tr("Invalid search expression"), self.tr("""<p>The search expression is not valid.</p>""" """<p>Error: {0}</p>""").format(str(why))) self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) return # reset the findtextCombo if ct in self.searchHistory: self.searchHistory.remove(ct) self.searchHistory.insert(0, ct) self.findtextCombo.clear() self.findtextCombo.addItems(self.searchHistory) Preferences.Prefs.settings.setValue("FindFileDialog/SearchHistory", self.searchHistory[:30]) if self.__replaceMode: replTxt = self.replacetextCombo.currentText() if replTxt in self.replaceHistory: self.replaceHistory.remove(replTxt) self.replaceHistory.insert(0, replTxt) self.replacetextCombo.clear() self.replacetextCombo.addItems(self.replaceHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/ReplaceHistory", self.replaceHistory[:30]) if self.dirButton.isChecked(): searchDir = self.dirCombo.currentText() if searchDir in self.dirHistory: self.dirHistory.remove(searchDir) self.dirHistory.insert(0, searchDir) self.dirCombo.clear() self.dirCombo.addItems(self.dirHistory) Preferences.Prefs.settings.setValue( "FindFileDialog/DirectoryHistory", self.dirHistory[:30]) # set the button states self.stopButton.setEnabled(True) self.stopButton.setDefault(True) self.findButton.setEnabled(False) # now go through all the files self.__populating = True self.findList.setUpdatesEnabled(False) progress = 0 breakSearch = False occurrences = 0 fileOccurrences = 0 for file in files: self.__lastFileItem = None found = False if self.__cancelSearch or breakSearch: break self.findProgressLabel.setPath(file) if self.projectButton.isChecked(): fn = os.path.join(self.project.ppath, file) else: fn = file # read the file and split it into textlines try: text, encoding, hash = Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError): progress += 1 self.findProgress.setValue(progress) continue # now perform the search and display the lines found count = 0 for line in lines: if self.__cancelSearch: break count += 1 contains = search.search(line) if contains: occurrences += 1 found = True start = contains.start() end = contains.end() if self.__replaceMode: rline = search.sub(replTxt, line) else: rline = "" line = self.__stripEol(line) if len(line) > 1024: line = "{0} ...".format(line[:1024]) if self.__replaceMode: if len(rline) > 1024: rline = "{0} ...".format(line[:1024]) line = "- {0}\n+ {1}".format(line, self.__stripEol(rline)) self.__createItem(file, count, line, start, end, rline, hash) if self.feelLikeCheckBox.isChecked(): fn = os.path.join(self.project.ppath, file) self.sourceFile.emit(fn, count, "", start, end) QApplication.processEvents() breakSearch = True break QApplication.processEvents() if found: fileOccurrences += 1 progress += 1 self.findProgress.setValue(progress) if not files: self.findProgress.setMaximum(1) self.findProgress.setValue(1) resultFormat = self.tr("{0} / {1}", "occurrences / files") self.findProgressLabel.setPath( resultFormat.format(self.tr("%n occurrence(s)", "", occurrences), self.tr("%n file(s)", "", fileOccurrences))) self.findList.setUpdatesEnabled(True) self.findList.sortItems(self.findList.sortColumn(), self.findList.header().sortIndicatorOrder()) self.findList.resizeColumnToContents(1) if self.__replaceMode: self.findList.header().resizeSection(0, self.__section0Size + 30) self.findList.header().setStretchLastSection(True) self.__populating = False self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) if breakSearch: self.close() def on_findList_itemDoubleClicked(self, itm, column): """ Private slot to handle the double click on a file item. It emits the signal sourceFile or designerFile depending on the file extension. @param itm the double clicked tree item (QTreeWidgetItem) @param column column that was double clicked (integer) (ignored) """ if itm.parent(): file = itm.parent().text(0) line = itm.data(0, self.lineRole) start = itm.data(0, self.startRole) end = itm.data(0, self.endRole) else: file = itm.text(0) line = 1 start = 0 end = 0 if self.project: fn = os.path.join(self.project.ppath, file) else: fn = file if fn.endswith('.ui'): self.designerFile.emit(fn) else: self.sourceFile.emit(fn, line, "", start, end) @pyqtSlot() def on_dirSelectButton_clicked(self): """ Private slot to display a directory selection dialog. """ directory = E5FileDialog.getExistingDirectory( self, self.tr("Select directory"), self.dirCombo.currentText(), E5FileDialog.Options(E5FileDialog.ShowDirsOnly)) if directory: self.dirCombo.setEditText(Utilities.toNativeSeparators(directory)) def __getFileList(self, path, filterRe): """ Private method to get a list of files to search. @param path the root directory to search in (string) @param filterRe regular expression defining the filter criteria (regexp object) @return list of files to be processed (list of strings) """ path = os.path.abspath(path) files = [] for dirname, _, names in os.walk(path): files.extend([ os.path.join(dirname, f) for f in names if re.match(filterRe, f) ]) return files def setSearchDirectory(self, searchDir): """ Public slot to set the name of the directory to search in. @param searchDir name of the directory to search in (string) """ self.dirButton.setChecked(True) self.dirCombo.setEditText(Utilities.toNativeSeparators(searchDir)) def setOpenFiles(self): """ Public slot to set the mode to search in open files. """ self.openFilesButton.setChecked(True) @pyqtSlot() def on_replaceButton_clicked(self): """ Private slot to perform the requested replace actions. """ self.findProgress.setMaximum(self.findList.topLevelItemCount()) self.findProgress.setValue(0) progress = 0 for index in range(self.findList.topLevelItemCount()): itm = self.findList.topLevelItem(index) if itm.checkState(0) in [Qt.PartiallyChecked, Qt.Checked]: file = itm.text(0) origHash = itm.data(0, self.md5Role) self.findProgressLabel.setPath(file) if self.projectButton.isChecked(): fn = os.path.join(self.project.ppath, file) else: fn = file # read the file and split it into textlines try: text, encoding, hash = \ Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>Could not read the file <b>{0}</b>.""" """ Skipping it.</p><p>Reason: {1}</p>""").format( fn, str(err))) progress += 1 self.findProgress.setValue(progress) continue # Check the original and the current hash. Skip the file, # if hashes are different. if origHash != hash: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>The current and the original hash of the""" """ file <b>{0}</b> are different. Skipping it.""" """</p><p>Hash 1: {1}</p><p>Hash 2: {2}</p>"""). format(fn, origHash, hash)) progress += 1 self.findProgress.setValue(progress) continue # replace the lines authorized by the user for cindex in range(itm.childCount()): citm = itm.child(cindex) if citm.checkState(0) == Qt.Checked: line = citm.data(0, self.lineRole) rline = citm.data(0, self.replaceRole) lines[line - 1] = rline # write the file txt = "".join(lines) try: Utilities.writeEncodedFile(fn, txt, encoding) except (IOError, Utilities.CodingError, UnicodeError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>Could not save the file <b>{0}</b>.""" """ Skipping it.</p><p>Reason: {1}</p>""").format( fn, str(err))) progress += 1 self.findProgress.setValue(progress) self.findProgressLabel.setPath("") self.findList.clear() self.replaceButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) def __contextMenuRequested(self, pos): """ Private slot to handle the context menu request. @param pos position the context menu shall be shown (QPoint) """ menu = QMenu(self) menu.addAction(self.tr("Open"), self.__openFile) menu.addAction(self.tr("Copy Path to Clipboard"), self.__copyToClipboard) menu.exec_(QCursor.pos()) def __openFile(self): """ Private slot to open the currently selected entry. """ itm = self.findList.selectedItems()[0] self.on_findList_itemDoubleClicked(itm, 0) def __copyToClipboard(self): """ Private method to copy the path of an entry to the clipboard. """ itm = self.findList.selectedItems()[0] if itm.parent(): fn = itm.parent().text(0) else: fn = itm.text(0) cb = QApplication.clipboard() cb.setText(fn)
def __init__(self, parent=None): super(Window, self).__init__(parent) self.plot_title = 'f(R),f(R,Q),GR comparison for Mass and Radius' self.xlabel = "$R[km]$" self.ylabel = r'$M[M_\odot]$' self.xlim = (8.0, 20.0) tree = QTreeWidget() headerItem = QTreeWidgetItem() item = QTreeWidgetItem() tree_fRQ = QTreeWidget() headerItem_fRQ = QTreeWidgetItem() item_fRQ = QTreeWidgetItem() tree_GR = QTreeWidget() headerItem_GR = QTreeWidgetItem() item_GR = QTreeWidgetItem() tree_quantities = QTreeWidget() headerItem_quantities = QTreeWidgetItem() item_quantities = QTreeWidgetItem() self.quant_branch = QTreeWidgetItem(tree_quantities) self.quant_branch.setText(0, "Quantities") self.quant_branch.setFlags(self.quant_branch.flags() ) # self.GR_branch.setCheckState(0, Qt.Unchecked) child = QTreeWidgetItem(self.quant_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setText(0, 'R-M') child.setCheckState(0, Qt.Checked) child.emitDataChanged() # .connect(self.plot) child = QTreeWidgetItem(self.quant_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setText(0, 'rho-M') child.setCheckState(0, Qt.Unchecked) child.emitDataChanged() self.GR_branch = QTreeWidgetItem(tree_GR) self.GR_branch.setText(0, "GR") self.GR_branch.setFlags(self.GR_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) #self.GR_branch.setCheckState(0, Qt.Unchecked) for x in range(len(glob.glob('Results/TOV_output_GR_*'))): child = QTreeWidgetItem(self.GR_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) checktext = GR_Modellist[x].EOS_type child.setText(0,checktext) child.setCheckState(0, Qt.Unchecked) child.emitDataChanged()# .connect(self.plot) self.fR_branch = QTreeWidgetItem(tree) self.fR_branch.setText(0,"fR") self.fR_branch.setFlags(self.fR_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for x in range(len(glob.glob('Results/TOV_output_fR_*'))): child = QTreeWidgetItem(self.fR_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) checktext = fR_Modellist[x].ID + fR_Modellist[x].EOS_type child.setText(0,checktext) child.setCheckState(0, Qt.Unchecked) child.emitDataChanged()# .connect(self.plot) #if(fRQ_branch.child(1).isSelected==1){print("hey hey")} self.fRQ_branch = QTreeWidgetItem(tree_fRQ) self.fRQ_branch.setText(0, "fRQ") self.fRQ_branch.setFlags(self.fRQ_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for x in range(len(glob.glob('Results/TOV_output_fRQ_*'))): child = QTreeWidgetItem(self.fRQ_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) checktext = fRQ_Modellist[x].ID + fRQ_Modellist[x].EOS_type child.setText(0, checktext) child.setCheckState(0, Qt.Unchecked) print("checked?", self.fR_branch.child(0).isSelected()) tree.itemChanged.connect(self.plot) tree_fRQ.itemChanged.connect(self.plot) tree_GR.itemChanged.connect(self.plot) tree_quantities.itemChanged.connect(self.quant_change) tree_quantities.itemChanged.connect(self.plot) #tree.show() # a figure instance to plot on self.figure = plt.figure() # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) # Just some button connected to `plot` method #self.button = QPushButton('Plot') #self.button.clicked.connect(self.plot) # set the layout self.layout = QVBoxLayout() self.sublayout1 = QVBoxLayout() self.sublayout2 = QHBoxLayout() plotBox = QHBoxLayout() plotBox.addLayout(self.sublayout1, 1) plotBox.addLayout(self.sublayout2, 4) bottomlayout = QHBoxLayout() #self.layout.addLayout() self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas,1) #self.layout.addWidget(self.button) self.setLayout(self.layout) #layout = QHBoxLayout() self.btn_rhoM = QCheckBox("rho-M") self.btn_RM = QCheckBox("R-M") self.btn_GR = QCheckBox("GR") self.btn_fR = QCheckBox("fR") self.btn_fRQ = QCheckBox("fRQ") self.btn_fRs = [] self.btn_rhoM.setChecked(False) self.btn_RM.setChecked(True) self.btn_GR.setChecked(False) self.btn_fR.setChecked(False) self.btn_fRQ.setChecked(False) #self.b1.stateChanged.connect(lambda: self.btnstate(self.b1)) #self.btn_rhoM.stateChanged.connect(self.quant_change) #self.btn_RM.stateChanged.connect(self.quant_change) self.btn_rhoM.stateChanged.connect(self.plot) self.btn_RM.stateChanged.connect(self.plot) self.btn_GR.stateChanged.connect(self.plot) self.btn_fR.stateChanged.connect(self.plot) self.btn_fRQ.stateChanged.connect(self.plot) #self.layout.addWidget(self.btn_GR) #self.layout.addWidget(self.btn_fR) #self.layout.addWidget(self.btn_fRQ) self.sublayout2.addWidget(tree_quantities) self.sublayout2.addWidget(tree_GR) self.sublayout2.addWidget(tree) self.sublayout2.addWidget(tree_fRQ) self.layout.addLayout(plotBox)
class FindFileDialog(QDialog, Ui_FindFileDialog): """ Class implementing a dialog to search for text in files. The occurrences found are displayed in a QTreeWidget showing the filename, the linenumber and the found text. The file will be opened upon a double click onto the respective entry of the list. @signal sourceFile(str, int, str, int, int) emitted to open a source file at a line @signal designerFile(str) emitted to open a Qt-Designer file """ sourceFile = pyqtSignal(str, int, str, int, int) designerFile = pyqtSignal(str) lineRole = Qt.UserRole + 1 startRole = Qt.UserRole + 2 endRole = Qt.UserRole + 3 replaceRole = Qt.UserRole + 4 md5Role = Qt.UserRole + 5 def __init__(self, parent=None, replaceMode=True, projectPath=None): """ Constructor @param project reference to the project object @param replaceMode flag indicating the replace dialog mode (boolean) @param parent parent widget of this dialog (QWidget) """ super(FindFileDialog, self).__init__(parent) self.setupUi(self) self.setWindowFlags(Qt.Window) self.dirPicker.setMode(E5PathPickerModes.DirectoryMode) self.dirPicker.setInsertPolicy(QComboBox.InsertAtTop) self.dirPicker.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLength) self.__replaceMode = replaceMode self.importButton = \ self.buttonBox.addButton(self.tr("&Import"), QDialogButtonBox.ActionRole) self.exportButton = \ self.buttonBox.addButton(self.tr("&Export"), QDialogButtonBox.ActionRole) self.stopButton = \ self.buttonBox.addButton(self.tr("Stop"), QDialogButtonBox.ActionRole) self.stopButton.setEnabled(False) self.transButton = \ self.buttonBox.addButton(self.tr("TransForm"), QDialogButtonBox.ActionRole) self.findButton = \ self.buttonBox.addButton(self.tr("Find"), QDialogButtonBox.ActionRole) self.findButton.setEnabled(False) self.findButton.setDefault(True) if projectPath is not None: self.projectPath = projectPath.replace("\\","/") self.dirPicker.setPath(self.projectPath) if self.__replaceMode: self.replaceButton.setEnabled(False) self.setWindowTitle(self.tr("Replace in Files")) else: self.replaceLabel.hide() self.replacetextCombo.hide() self.replaceButton.hide() self.findProgressLabel.setMaximumWidth(550) self.findList.headerItem().setText(self.findList.columnCount(), "") self.findList.header().setSortIndicator(0, Qt.AscendingOrder) self.__section0Size = self.findList.header().sectionSize(0) self.findList.setExpandsOnDoubleClick(False) if self.__replaceMode: font = QFont() # font = Preferences.getEditorOtherFonts("MonospacedFont") self.findList.setFont(font) self.__cancelSearch = False self.__lastFileItem = None self.__populating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__contextMenuRequested) def __createItem(self, file, line, text, start, end, replTxt="", md5=""): """ Private method to create an entry in the file list. 创建 Item @param file filename of file (string) @param line line number (integer) @param text text found (string) @param start start position of match (integer) @param end end position of match (integer) @param replTxt text with replacements applied (string) @keyparam md5 MD5 hash of the file (string) """ if self.__lastFileItem is None: # It's a new file self.__lastFileItem = QTreeWidgetItem(self.findList, [file]) self.__lastFileItem.setFirstColumnSpanned(True) self.__lastFileItem.setExpanded(True) if self.__replaceMode: self.__lastFileItem.setFlags( self.__lastFileItem.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate)) # Qt bug: # item is not user checkable if setFirstColumnSpanned # is True (< 4.5.0) self.__lastFileItem.setData(0, self.md5Role, md5) itm = QTreeWidgetItem(self.__lastFileItem) itm.setTextAlignment(0, Qt.AlignRight) itm.setData(0, Qt.DisplayRole, line) itm.setData(1, Qt.DisplayRole, text) itm.setData(0, self.lineRole, line) itm.setData(0, self.startRole, start) itm.setData(0, self.endRole, end) itm.setData(0, self.replaceRole, replTxt) if self.__replaceMode: itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable)) itm.setCheckState(0, Qt.Checked) self.replaceButton.setEnabled(True) def show(self, txt=""): """ Public method to enable/disable the project button. @param txt text to be shown in the searchtext combo (string) """ if self.__replaceMode: self.findList.clear() super(FindFileDialog, self).show() def resizeEvent(self, e): self.mdiArea.tileSubWindows() return super().resizeEvent(e) def on_dirPicker_editTextChanged(self, text): """ Private slot to handle the textChanged signal of the directory picker. @param text (ignored) """ self.enableFindButton(False, False) def enableFindButton(self, sub=None, close=None): """ Private slot called to enable the find button. """ def closeBtn(): self.findButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) def openBtn(): self.findButton.setEnabled(True) self.findButton.setDefault(True) if self.dirPicker.currentText() == "": closeBtn() elif os.path.exists(os.path.abspath(self.dirPicker.currentText())) is False: closeBtn() elif sub is not None: if close is None: if sub.findtextCombo.currentText() == "" or (sub.filterEdit.text() == "") \ or (self.__replaceMode is False and sub.replacetextCombo.currentText() == ""): closeBtn() else: openBtn() elif close is True: subList = self.mdiArea.subWindowList() for sub_ in subList: sub__ = sub_.widget() if sub__ != sub: if sub__.findtextCombo.currentText() == "" or (sub__.filterEdit.text() == ""): closeBtn() break else: openBtn() else: if len(subList) == 1: closeBtn() elif close is False: for sub_ in self.mdiArea.subWindowList(): sub__ = sub_.widget() if sub__.findtextCombo.currentText() == "" or (sub__.filterEdit.text() == ""): closeBtn() break else: openBtn() else: openBtn() def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.findButton: self.findList.clear() self.__doSearch() elif button == self.stopButton: self.__stopSearch() elif button == self.importButton: self.clear_btn.click() fileName, ok = QFileDialog.getOpenFileName(self, "Open", "history.json", "Json (*.json)") if fileName == '': return else: self.loadFromFile(fileName) elif button == self.exportButton: fileName, ok = QFileDialog.getSaveFileName(self, "Save", "history.json", "Json (*.json)") if fileName == '': return else: self.saveToFile(fileName) elif button == self.transButton: for sub in self.mdiArea.subWindowList(): sub = sub.widget() a, b = sub.findtextCombo.currentText(), sub.replacetextCombo.currentText() sub.findtextCombo.setCurrentText(b), sub.replacetextCombo.setCurrentText(a) def __stripEol(self, txt): """ Private method to strip the eol part. @param txt line of text that should be treated (string) @return text with eol stripped (string) """ return txt.replace("\r", "").replace("\n", "") def __stopSearch(self): """ Private slot to handle the stop button being pressed. """ self.__cancelSearch = True def __doSearch(self): """ Private slot to handle the find button being pressed. 搜索逻辑 """ # if self.__replaceMode and \ # not e5App().getObject("ViewManager").checkAllDirty(): # return self.__cancelSearch = False occurrences = 0 progress = 0 for sub in self.mdiArea.subWindowList(): sub = sub.widget() fileFilter = sub.filterEdit.text() fileFilterList = \ ["^{0}$".format(filter.replace(".", "\.").replace("*", ".*")) for filter in fileFilter.split(";")] # *.qml -> .*\.qml filterRe = re.compile("|".join(fileFilterList)) # 开始查找 files = self.__getFileList( os.path.abspath(self.dirPicker.currentText()), filterRe) QApplication.processEvents() QApplication.processEvents() # retrieve the values reg = sub.regexpCheckBox.isChecked() wo = sub.wordCheckBox.isChecked() cs = sub.caseCheckBox.isChecked() ct = sub.findtextCombo.currentText() if reg: txt = ct else: txt = re.escape(ct) if wo: txt = "\\b{0}\\b".format(txt) if sys.version_info[0] == 2: flags = re.UNICODE | re.LOCALE else: flags = re.UNICODE if not cs: flags |= re.IGNORECASE try: search = re.compile(txt, flags) except re.error as why: E5MessageBox.critical( self, self.tr("Invalid search expression"), self.tr("""<p>The search expression is not valid.</p>""" """<p>Error: {0}</p>""").format(str(why))) self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) return if self.__replaceMode: replTxt = sub.replacetextCombo.currentText() # ====================================================== # set the button states self.stopButton.setEnabled(True) self.stopButton.setDefault(True) self.findButton.setEnabled(False) # now go through all the files self.__populating = True self.findList.setUpdatesEnabled(False) breakSearch = False fileOccurrences = 0 for file in files: self.__lastFileItem = None found = False if self.__cancelSearch or breakSearch: break self.findProgressLabel.setPath(file) fn = file # read the file and split it into textlines try: text, encoding, hashStr = Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError): progress += 1 self.findProgress.setValue(progress) continue # now perform the search and display the lines found count = 0 for line in lines: if self.__cancelSearch: break count += 1 contains = search.search(line) if contains: occurrences += 1 found = True start = contains.start() end = contains.end() if self.__replaceMode: rline = search.sub(replTxt, line) else: rline = "" line = self.__stripEol(line) if len(line) > 1024: line = "{0} ...".format(line[:1024]) if self.__replaceMode: if len(rline) > 1024: rline = "{0} ...".format(line[:1024]) line = "- {0}\n+ {1}".format( line, self.__stripEol(rline)) self.__createItem(file, count, line, start, end, rline, hashStr) QApplication.processEvents() self.findList.setUpdatesEnabled(True) self.findList.sortItems(self.findList.sortColumn(), self.findList.header().sortIndicatorOrder()) self.findList.resizeColumnToContents(1) count_ = self.findList.topLevelItemCount() if found: fileOccurrences += 1 progress += 1 self.findProgress.setValue(progress) # if not files: self.findProgress.setMaximum(1) self.findProgress.setValue(1) # resultFormat = self.tr("{0} / {1}", "occurrences / files") self.findProgressLabel.setPath(resultFormat.format( self.tr("%n occurrence(s)", "", occurrences), self.tr("%n file(s)", "", count_))) if self.__replaceMode: self.findList.header().resizeSection(0, self.__section0Size + 30) self.findList.header().setStretchLastSection(True) self.__populating = False self.stopButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) if breakSearch: self.close() count_ = self.findList.topLevelItemCount() # self.findProgressLabel.setPath("") # self.findProgress.setValue(count_) self.findProgress.setMaximum(count_) def __getFileList(self, path, filterRe): """ Private method to get a list of files to search. @param path the root directory to search in (string) @param filterRe regular expression defining the filter criteria (regexp object) @return list of files to be processed (list of strings) """ path = os.path.abspath(path) files = [] for dirname, _, names in os.walk(path): files.extend([os.path.join(dirname, f) for f in names if re.match(filterRe, f)] ) return files def setOpenFiles(self): """ Public slot to set the mode to search in open files. """ self.openFilesButton.setChecked(True) @pyqtSlot() def on_replaceButton_clicked(self): """ Private slot to perform the requested replace actions. 替换开始 """ self.findProgress.setMaximum(self.findList.topLevelItemCount()) self.findProgress.setValue(0) progress = 0 for index in range(self.findList.topLevelItemCount()): itm = self.findList.topLevelItem(index) if itm.checkState(0) in [Qt.PartiallyChecked, Qt.Checked]: file = itm.text(0) origHash = itm.data(0, self.md5Role) self.findProgressLabel.setPath(file) fn = file # read the file and split it into textlines try: text, encoding, hashStr = \ Utilities.readEncodedFileWithHash(fn) lines = text.splitlines(True) except (UnicodeError, IOError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>Could not read the file <b>{0}</b>.""" """ Skipping it.</p><p>Reason: {1}</p>""") .format(fn, str(err)) ) progress += 1 self.findProgress.setValue(progress) continue # Check the original and the current hash. Skip the file, # if hashes are different. # if origHash != hashStr: # E5MessageBox.critical( # self, # self.tr("Replace in Files"), # self.tr( # """<p>The current and the original hash of the""" # """ file <b>{0}</b> are different. Skipping it.""" # """</p><p>Hash 1: {1}</p><p>Hash 2: {2}</p>""") # .format(fn, origHash, hashStr) # ) # progress += 1 # self.findProgress.setValue(progress) # continue # replace the lines authorized by the user for cindex in range(itm.childCount()): citm = itm.child(cindex) if citm.checkState(0) == Qt.Checked: line = citm.data(0, self.lineRole) rline = citm.data(0, self.replaceRole) lines[line - 1] = rline # write the file # 写入 txt = "".join(lines) try: Utilities.writeEncodedFile(fn, txt, encoding) except (IOError, Utilities.CodingError, UnicodeError) as err: E5MessageBox.critical( self, self.tr("Replace in Files"), self.tr( """<p>Could not save the file <b>{0}</b>.""" """ Skipping it.</p><p>Reason: {1}</p>""") .format(fn, str(err)) ) progress += 1 self.findProgress.setValue(progress) self.findProgressLabel.setPath("") # 替换完成 self.findList.clear() self.replaceButton.setEnabled(False) self.findButton.setEnabled(True) self.findButton.setDefault(True) def __contextMenuRequested(self, pos): """ Private slot to handle the context menu request. @param pos position the context menu shall be shown (QPoint) """ menu = QMenu(self) menu.addAction(self.tr("Copy Path to Clipboard"), self.__copyToClipboard) menu.exec_(QCursor.pos()) def __copyToClipboard(self): """ Private method to copy the path of an entry to the clipboard. """ itm = self.findList.selectedItems()[0] if itm.parent(): fn = itm.parent().text(0) else: fn = itm.text(0) cb = QApplication.clipboard() cb.setText(fn) # ================================= @pyqtSlot() def on_add_btn_clicked(self): """ add form. """ sub = subForm(self) self.mdiArea.addSubWindow(sub) sub.show() self.mdiArea.tileSubWindows() @pyqtSlot() def on_clear_btn_clicked(self): """ Slot documentation goes here. """ for i in self.mdiArea.subWindowList(): self.mdiArea.removeSubWindow(i) # ================================= def saveToFile(self, filename): try: with open(filename, "w") as file: file.write(json.dumps(self.serialize(), indent=4)) print("saving to", filename, "was successfull.") self.has_been_modified = False except: QMessageBox.warning(self, "error", "save json fail", QMessageBox.Ok) def loadFromFile(self, filename): try: with open(filename, "r") as file: raw_data = file.read() data = json.loads(raw_data, encoding='utf-8') self.deserialize(data) except: QMessageBox.warning(self, "error", "open json fail", QMessageBox.Ok) def serialize(self): """ÐòÁл¯""" subs = [] for sub in self.mdiArea.subWindowList(): subs.append(sub.widget().serialize()) return OrderedDict([ ('subs', subs), ('path', self.dirPicker.path()), ]) def deserialize(self, data, hashmap={}, restore_id=True): """·´ÐòÁл¯""" self.clear_btn.click() for sub_info in data['subs']: sub = subForm(self).deserialize(sub_info) self.mdiArea.addSubWindow(sub) sub.show() self.mdiArea.tileSubWindows() self.dirPicker.setPath(data['path']) self.enableFindButton(False, False) return True
def addItem(branch, name, num, num2): item = QTreeWidgetItem(branch) item.setFlags(item.flags() | Qt.ItemIsEditable) item.setText(0, name) item.setText(1, str(num)) item.setText(2, str(num2))
class Waterfall(QWidget, waterfall.Ui_Waterfall): general_settings_signal = QtCore.pyqtSignal(list) #send list of plotting params updated_rectangles_signal = QtCore.pyqtSignal(list) #send list of updated artists for redrawing def __init__(self, parent): super(Waterfall,self).__init__(parent) self.setupUi(self) self.test = {'a':1,'b':2,'c':3} #Button functions self.btn_apply_general_settings.clicked.connect(self.send_settings) self.patient_tree = self.create_patient_tree() self.data_viewer_container.addWidget(self.patient_tree) def on_waterfall_data_signal(self,signal): self.waterfall_data = signal['waterfall_data'] #pandas dataframe def on_generated_rectangles_signal(self,signal): self.rectangles_received = signal[0] self.add_items() #display in table #print(self.rectangles_received) def send_settings(self,signal): self.list_general_settings = [ self.plot_title.text(), self.x_label.text(), self.y_label.text(), self.twenty_percent_line.isChecked(), self.thirty_percent_line.isChecked(), self.zero_percent_line.isChecked(), self.display_responses_as_text.isChecked() ] self.general_settings_signal.emit(self.list_general_settings) def create_patient_tree(self): ''' Create QTreeWidget populated with a patient's data for the DataEntry dialog. Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog. ''' self.tree = QTreeWidget() self.root = self.tree.invisibleRootItem() self.headers = [ 'Patient #', 'Best response %', 'Overall response', 'Cancer', 'Color coding key', ] self.headers_item = QTreeWidgetItem(self.headers) self.tree.setColumnCount(len(self.headers)) self.tree.setHeaderItem(self.headers_item) self.root.setExpanded(True) self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) return self.tree def add_items(self): ''' Populate viewing tree ''' self.tree.clear() #clear prior to entering items, prevent aggregation i=0 for rect in self.rectangles_received: #populate editable tree with rect data self.rect_item = QTreeWidgetItem(self.root) self.rect_params = [ self.waterfall_data['Patient number'][i], rect.get_height(), self.waterfall_data['Overall response'][i], self.waterfall_data['Cancer'][i] ] for col in range(0,4): self.rect_item.setText(col,str(self.rect_params[col])) self.rect_item.setTextAlignment(col,4) self.tree.setItemWidget(self.rect_item, 4, CustomCombo(self,self.test)) self.rect_item.setFlags(self.rect_item.flags() | QtCore.Qt.ItemIsEditable) i+=1 def on_updated_tree_item(self): #update the rectangle which was edited pass
def _add_code_pep8(self): item = QTreeWidgetItem() item.setFlags(item.flags() | Qt.ItemIsEditable) self._listIgnoreViolations.addTopLevelItem(item) self._listIgnoreViolations.setCurrentItem(item) self._listIgnoreViolations.editItem(item, 0)
def new_cluster(self): item_0 = QTreeWidgetItem(self.treeWidget) item_0.setText(0,"Yeni Kolon") item_0.setFlags(item_0.flags() | Qt.ItemIsEditable)
def __generateItem(self, changelist, status, propStatus, locked, history, switched, lockinfo, uptodate, revision, change, author, path): """ Private method to generate a status item in the status list. @param changelist name of the changelist (string) @param status text status (pysvn.wc_status_kind) @param propStatus property status (pysvn.wc_status_kind) @param locked locked flag (boolean) @param history history flag (boolean) @param switched switched flag (boolean) @param lockinfo lock indicator (string) @param uptodate up to date flag (boolean) @param revision revision (integer) @param change revision of last change (integer) @param author author of the last change (string) @param path path of the file or directory (string) """ statusText = self.tr(svnStatusMap[status]) itm = QTreeWidgetItem(self.statusList) itm.setData(0, Qt.DisplayRole, "") itm.setData(1, Qt.DisplayRole, changelist) itm.setData(2, Qt.DisplayRole, statusText) itm.setData(3, Qt.DisplayRole, self.tr(svnStatusMap[propStatus])) itm.setData(4, Qt.DisplayRole, self.yesno[locked]) itm.setData(5, Qt.DisplayRole, self.yesno[history]) itm.setData(6, Qt.DisplayRole, self.yesno[switched]) itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo]) itm.setData(8, Qt.DisplayRole, self.yesno[uptodate]) itm.setData(9, Qt.DisplayRole, revision) itm.setData(10, Qt.DisplayRole, change) itm.setData(11, Qt.DisplayRole, author) itm.setData(12, Qt.DisplayRole, path) itm.setTextAlignment(1, Qt.AlignLeft) itm.setTextAlignment(2, Qt.AlignHCenter) itm.setTextAlignment(3, Qt.AlignHCenter) itm.setTextAlignment(4, Qt.AlignHCenter) itm.setTextAlignment(5, Qt.AlignHCenter) itm.setTextAlignment(6, Qt.AlignHCenter) itm.setTextAlignment(7, Qt.AlignHCenter) itm.setTextAlignment(8, Qt.AlignHCenter) itm.setTextAlignment(9, Qt.AlignRight) itm.setTextAlignment(10, Qt.AlignRight) itm.setTextAlignment(11, Qt.AlignLeft) itm.setTextAlignment(12, Qt.AlignLeft) if status in [pysvn.wc_status_kind.added, pysvn.wc_status_kind.deleted, pysvn.wc_status_kind.modified] or \ propStatus in [pysvn.wc_status_kind.added, pysvn.wc_status_kind.deleted, pysvn.wc_status_kind.modified]: itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable) if statusText not in self.__statusFilters: self.__statusFilters.append(statusText)
class myGUI(QMainWindow): signal_loginSuccess = QtCore.pyqtSignal() signal_startShowTree = QtCore.pyqtSignal() signal_setStartBackupBtn = QtCore.pyqtSignal(str, bool) signal_showUserOptionWindow = QtCore.pyqtSignal() signal_showDevOptionWindow = QtCore.pyqtSignal() signal_close = QtCore.pyqtSignal() signal_appendDownloadList = QtCore.pyqtSignal(dict) signal_processbar_value = QtCore.pyqtSignal(int) signal_startUpdate = QtCore.pyqtSignal(str) def __init__(self): super().__init__() self.config = ConfigParser() self.pool = threadpool.ThreadPool(4) self.DownloadPool = threadpool.ThreadPool(1) self.readSetting() string.setLanguage(self.config['User']['language']) self.version = 1.21 self.host = 'https://ilearn2.fcu.edu.tw' self.statusbar = self.statusBar() self.initUI() self.web = iLearnManager(self.host) self.init_iLearn() self.FileTree = {} self.success = 0 self.failed = 0 self.fileList = [] self.retryList = [] self.failedList = [] self.retryTimes = 0 self.nowLoad = 0 self.retryAfter = 0 self.initCheckUpdate = False self.retryTimer = QtCore.QTimer() self.retryTimer.timeout.connect(self.startRetry) self.signal_loginSuccess.connect(self.ShowResource) self.signal_appendDownloadList.connect(self.appendItemToDownloadList) self.signal_processbar_value.connect(self.setProcessBarValue) self.signal_startShowTree.connect(self.startShowTree) self.signal_setStartBackupBtn.connect(self.setStartBackupBtn) self.timer_checkUpdate = QtCore.QTimer() self.timer_checkUpdate.timeout.connect(self.checkUpdate) self.timer_checkUpdate.start(1000) if self.config['dev'].getboolean('autologin') == True: self.btn_login.click() def closeEvent(self, event): self.signal_close.emit() self.close() def setStatusBarText(self, str): self.statusbar.showMessage(str) def init_iLearn(self): self.web.signal_finishDownload.connect(self.startDownload) self.web.signal_setStatusProcessBar.connect(self.setStatusProcessBar) self.web.signal_Log.connect(self.print) self.web.signal_setStatusBarText.connect(self.setStatusBarText) t = Thread(target=self.TestiLearnConnection) t.run() def setStartBackupBtn(self, text, enabled): self.btn_StartBackup.setEnabled(enabled) self.btn_StartBackup.setText(text) def setStatusProcessBar(self, idx, value): if value == -1: ProcessBar = QProgressBar() self.StatusTable.setCellWidget(idx, 3, ProcessBar) elif value == -2: if self.retryTimes == 0: self.failed += 1 self.failedList.append(idx) self.StatusTable.removeCellWidget(idx, 3) # 移除進度條之控件 ErrorIcon = QIcon(":img/DownloadFailed.png") # 開啟下載失敗之圖案 item = QTableWidgetItem(ErrorIcon, string._('Download Falied')) # 新增顯示失敗的元件 self.StatusTable.setItem(idx, 3, item) # 將新元件設定到表格內 if idx == len(self.fileList) - 1: self.signal_processbar_value.emit(idx + 1) self.finishDownloadCheck(idx) elif value == 101: if self.retryTimes != 0: self.failed -= 1 self.success += 1 self.print(string._('Download file %d finish!') % (idx + 1)) self.StatusTable.removeCellWidget(idx, 3) OkIcon = QIcon(":img/FinishDownload.png") # 開啟下載完成之圖案 item = QTableWidgetItem(OkIcon, "OK") # 新增顯示OK的元件 self.StatusTable.setItem(idx, 3, item) # 將新元件設定到表格內 self.finishDownloadCheck(idx) else: ProcessBar = self.StatusTable.cellWidget(idx, 3) if ProcessBar == None: ProcessBar = QProgressBar() self.StatusTable.setCellWidget(idx, 3, ProcessBar) ProcessBar.setValue(value) def finishDownloadCheck(self, idx): def checkIsEndElement(idx): if self.retryTimes == 0: return idx == len(self.fileList) - 1 else: return idx == self.retryList[-1] def backupFinish(): self.signal_processbar_value.emit(self.statusProcessBar.maximum()) self.signal_setStartBackupBtn.emit(string._('Start Backup'), True) QMessageBox.information( self, string._("Download finish!"), string._("Success:%d\nFailed:%d") % (self.success, self.failed)) if checkIsEndElement(idx): if self.retryTimes == self.config['User'].getint('retrytimes'): backupFinish() else: self.signal_processbar_value.emit( self.statusProcessBar.maximum()) if self.failed == 0: backupFinish() else: self.retryAfter = self.config['User'].getint( 'secondbetweenretry') self.retryTimer.start(1000) def checkUpdate(self): try: self.timer_checkUpdate.stop() except: pass with open('version.ini', mode='w') as f: f.write(str(self.version)) s = requests.Session() versionFile = s.get( 'https://raw.githubusercontent.com/fcu-d0441320/iLearnBackupTool/master/version.ini' ) version = float(versionFile.text) if version > self.version: reply = QMessageBox.question( self, string._('Find New version'), string. _('Find New Version:%.1f\nNow Vsrsion:%.1f\nDo you want to update?' ) % (version, self.version), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.setVisible(False) self.signal_startUpdate.emit(self.config['User']['language']) else: if self.initCheckUpdate == False: self.initCheckUpdate = True else: QMessageBox.information(self, string._('This is the latest version'), string._('This is the latest version')) # QMessageBox().information(self,"有更新版本!","發現有新版本,請前往官網更新,或檢查是否與Updater_GUI.exe放置於相同資料夾!") def moveToCenter(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def initUI(self): self.resize(800, 600) self.setWindowIcon(QIcon(':img/Main_Icon.png')) self.moveToCenter() self.setWindowTitle(string._('iLearn Backup Tool')) self.statusbar.showMessage(string._('Starting Backup Tool...')) self.createMenu() self.statusProcessBar = QProgressBar() self.statusProcessBar.setValue(0) self.statusProcessBar.setFormat(string._("Ready...")) self.statusbar.addPermanentWidget(self.statusProcessBar) self.grid = QGridLayout() widget = QWidget() self.setCentralWidget(widget) widget.setLayout(self.grid) self.grid.addWidget(self.createLoginGroup(), 0, 0) self.grid.addWidget(self.createSaveGroup(), 1, 0) self.grid.addWidget(self.createCourseGroup(), 0, 1, 2, 1) self.grid.addWidget(self.createStatusView(), 2, 0, 1, 2) self.grid.setColumnStretch(0, 10) self.grid.setColumnStretch(1, 20) self.grid.setRowStretch(0, 6) self.grid.setRowStretch(1, 6) self.grid.setRowStretch(2, 10) self.web = iLearnManager() self.show() def createStatusTable(self): self.StatusTable = QTableWidget() self.StatusTable.setColumnCount(4) horizontal_header = [ string._('File name'), string._('Path'), string._('iLearn mod'), string._('Download status') ] self.StatusTable.setHorizontalHeaderLabels(horizontal_header) self.StatusTable.setEditTriggers(QTableWidget.NoEditTriggers) self.StatusTable.setColumnWidth(0, 140) self.StatusTable.setColumnWidth(1, 120) self.StatusTable.setColumnWidth(2, 120) self.StatusTable.setColumnWidth(3, 380) return self.StatusTable def createLogSpace(self): self.LogSpace = QPlainTextEdit() self.LogSpace.setReadOnly(True) return self.LogSpace def print(self, msg): self.LogSpace.appendPlainText( time.strftime("[%H:%M:%S] ", time.localtime()) + msg) def createStatusView(self): tabs = QTabWidget() tabs.addTab(self.createStatusTable(), string._('Backup status')) tabs.addTab(self.createLogSpace(), string._('Log')) return tabs def createLoginGroup(self): groupBox = QGroupBox(string._('Step 1: Login')) form = QGridLayout() label_NID = QLabel(string._('NID:')) self.input_NID = QLineEdit() self.input_NID.setText(self.config['dev']['nid']) label_Pass = QLabel(string._('Password:'******'dev']['pass']) self.input_Pass.setEchoMode(QLineEdit.Password) form.addWidget(label_NID, 0, 0) form.addWidget(self.input_NID, 0, 1, 1, 2) form.addWidget(label_Pass, 1, 0) form.addWidget(self.input_Pass, 1, 1, 1, 2) self.btn_clean = QPushButton(string._('Clean'), self) self.btn_clean.clicked[bool].connect(self.cleanLogin) form.addWidget(self.btn_clean, 2, 1) self.btn_login = QPushButton(string._('Login'), self) self.btn_login.clicked[bool].connect(self.Login) form.addWidget(self.btn_login, 2, 2) label_iLearnStatus = QLabel(string._('iLearn status:')) form.addWidget(label_iLearnStatus, 3, 0) self.label_iLearn = QLabel() form.addWidget(self.label_iLearn, 3, 1, 1, 2) vbox = QVBoxLayout() vbox.addLayout(form) vbox.addStretch(1) groupBox.setLayout(vbox) return groupBox def cleanLogin(self): self.input_NID.setText("") self.input_Pass.setText("") def createSaveGroup(self): groupBox = QGroupBox(string._('Step 3:Select save option')) radio1 = QRadioButton(string._('Save as file')) radio1.setChecked(True) radio2 = QRadioButton(string._('Save as web page')) radio2.setEnabled(False) self.btn_StartBackup = QPushButton(string._('Start Backup'), self) self.btn_StartBackup.setEnabled(False) self.btn_StartBackup.clicked[bool].connect(self.StartBackup) self.btn_OpenFolder = QPushButton(string._('Open Folder'), self) self.btn_OpenFolder.clicked[bool].connect(self.OpenFolder) vbox = QVBoxLayout() vbox.addWidget(radio1) vbox.addWidget(radio2) vbox.addWidget(self.btn_StartBackup) vbox.addWidget(self.btn_OpenFolder) vbox.addStretch(1) groupBox.setLayout(vbox) if not exists('iLearn'): makedirs('iLearn') return groupBox def OpenFolder(self): subprocess.Popen(['explorer', "iLearn"]) def createCourseGroup(self): groupBox = QGroupBox( string._('Step 2:Select sourse resource to backup')) self.CourseListBox = QVBoxLayout() self.CourseListBox.addStretch(1) self.CourseTreeList = QTreeWidget() self.CourseTreeList.setHeaderHidden(True) self.CourseTreeList.setEnabled(False) self.CourseTreeList.itemExpanded.connect(self.ExpandCourse) self.CourseTreeListRoot = QTreeWidgetItem(self.CourseTreeList) self.CourseTreeListRoot.setText(0, string._("All course")) self.CourseTreeListRoot.setFlags(self.CourseTreeListRoot.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) self.CourseTreeListRoot.setCheckState(0, QtCore.Qt.Unchecked) HLayout = QHBoxLayout() HLayout.addWidget(self.CourseTreeList) groupBox.setLayout(HLayout) return groupBox def createMenu(self): menubar = self.menuBar() fileMenu = menubar.addMenu(string._('File')) closeAct = QAction(QIcon(':img/Close_Icon.png'), string._('Quit'), self) closeAct.triggered.connect(qApp.quit) fileMenu.addAction(closeAct) optMenu = menubar.addMenu(string._('Option')) DevOptAct = QAction(QIcon(':img/Settings_Icon.png'), string._('Developer options'), self) DevOptAct.triggered.connect(self.showDevOption) UserOptionAction = QAction(QIcon(':img/Settings_Icon.png'), string._('Preferences'), self) UserOptionAction.triggered.connect(self.showUserOption) optMenu.addAction(UserOptionAction) optMenu.addAction(DevOptAct) helpMenu = menubar.addMenu(string._('Help')) helpAct = QAction(QIcon(':img/Help_Icon.png'), string._('Help'), self) helpAct.triggered.connect(self.showHelp) aboutAct = QAction(QIcon(':img/About_Icon.png'), string._('About'), self) aboutAct.triggered.connect(self.showInformation) checkUpdateAct = QAction(QIcon(':img/Update_Icon.png'), string._('Check update'), self) checkUpdateAct.triggered.connect(self.checkUpdate) helpMenu.addAction(helpAct) helpMenu.addAction(checkUpdateAct) helpMenu.addAction(aboutAct) def showHelp(self): subprocess.Popen( ["explorer", "http://github.com/fcu-d0441320/iLearnBackupTool"]) def showUserOption(self): self.signal_showUserOptionWindow.emit() def showDevOption(self): self.signal_showDevOptionWindow.emit() def Login(self): t = Thread(target=self.__Login) t.run() def __Login(self): self.web.setUser(self.input_NID.text(), self.input_Pass.text()) self.label_iLearn.setText( string._('User %s is signing in...') % self.input_NID.text()) self.print( string._('User %s is signing in...') % self.input_NID.text()) status, UserName = self.web.Login() if status: # == True self.statusbar.showMessage(string._('Sign in success')) self.label_iLearn.setText( string._('%s sign in sucess') % (UserName)) self.print(string._('%s sign in sucess') % (UserName)) self.input_Pass.setEnabled(False) self.input_NID.setEnabled(False) self.btn_login.setEnabled(False) self.btn_clean.setEnabled(False) self.signal_loginSuccess.emit() else: self.statusbar.showMessage(string._('Sign in failed')) self.label_iLearn.setText(string._('Sign in failed')) self.print(UserName + string._('Sign in failed')) self.nowLoad = 0 def ShowResource(self): self.CourseTreeList.setEnabled(True) self.courseList = self.web.getCourseList() for course in self.courseList: courseItem = QTreeWidgetItem(self.CourseTreeListRoot) self.CourseTreeListRoot.setExpanded(True) courseItem.setFlags(courseItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) courseItem.setText(0, course['title']) courseItem.setCheckState(0, QtCore.Qt.Unchecked) courseItem.setIcon(0, QIcon(':img/mod.course.jpg')) child = QTreeWidgetItem(courseItem) child.setFlags(courseItem.flags() | QtCore.Qt.ItemIsUserCheckable) child.setText(0, string._('Loading...')) child.setCheckState(0, QtCore.Qt.Unchecked) self.startBackgroundLoad() def ExpandCourse(self, courseItem): if courseItem.child(0).text(0) == string._('Loading...'): i = 0 for ele in self.courseList: if ele['title'] == courseItem.text(0): break else: i += 1 self.timer = QtCore.QTimer() # 计时器 self.timer.timeout.connect( partial(self.appedResourceToTree, i, courseItem)) self.timer.start(10) def startBackgroundLoad(self): if self.nowLoad < len(self.courseList): self.statusProcessBar.setMaximum(len(self.courseList)) self.statusProcessBar.setFormat( string._('Loding course resource') + '(%v/' + '%d)' % (len(self.courseList))) reqs = threadpool.makeRequests(self.loadFileTreeBackground, range(len(self.courseList))) for req in reqs: self.pool.putRequest(req) def setProcessBarValue(self, value): if value == self.statusProcessBar.maximum(): self.statusProcessBar.setFormat(string._('Ready...')) self.statusProcessBar.setMaximum(100) self.statusProcessBar.setValue(0) else: self.statusProcessBar.setValue(value) def startShowTree(self): for i, courseItem in [ (i, self.CourseTreeListRoot.child(i)) for i in range(self.CourseTreeListRoot.childCount()) ]: if courseItem.child(0).text(0) == string._('Loading...'): self.appedResourceToTree(i, courseItem) def loadFileTreeBackground(self, index): self.signal_processbar_value.emit(index) if self.courseList[index]['title'] not in self.FileTree: FileList = self.web.getCourseFileList( self.courseList[index], useRealFileName=self.config['User'].getboolean( 'userealfilename'), showTime=self.config['dev'].getboolean('showloadtime')) if self.courseList[index]['title'] not in self.FileTree: self.FileTree[self.courseList[index]['title']] = FileList if index == len(self.courseList) - 1: self.signal_processbar_value.emit(len(self.courseList)) self.signal_setStartBackupBtn.emit(string._('Start Backup'), True) self.signal_startShowTree.emit() def appedResourceToTree(self, i, courseItem): course = self.courseList[i] try: self.timer.stop() except: pass tStart = time.time() if course['title'] not in self.FileTree: courseFileList = self.web.getCourseFileList( course, useRealFileName=self.config['User'].getboolean( 'userealfilename'), showTime=self.config['dev'].getboolean('showloadtime')) if course['title'] not in self.FileTree: self.FileTree[course['title']] = courseFileList self.nowLoad += 1 else: courseFileList = self.FileTree[course['title']] checkStatus = courseItem.checkState(0) totalFiles = 0 if len(courseFileList) == 0: sectionItem = QTreeWidgetItem(courseItem) sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) sectionItem.setText(0, string._('There has no resource to download.')) sectionItem.setCheckState(0, checkStatus) for section in courseFileList: sectionItem = QTreeWidgetItem(courseItem) sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) sectionItem.setText(0, section['section']) sectionItem.setCheckState(0, checkStatus) sectionItem.setIcon(0, QIcon(":img/mod.folder.svg")) for recource in section['mods']: if recource['mod'] == 'forum': forumItem = QTreeWidgetItem(sectionItem) forumItem.setFlags(forumItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) forumItem.setText(0, recource['name']) forumItem.setCheckState(0, checkStatus) forumItem.setIcon(0, QIcon(":img/mod.discuss.svg")) for topic in recource['data']: topicItem = QTreeWidgetItem(forumItem) topicItem.setFlags(topicItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) topicItem.setText(0, topic['name']) topicItem.setCheckState(0, checkStatus) topicItem.setIcon(0, QIcon(":img/mod.discuss.svg")) totalFiles += 1 elif recource['mod'] in [ 'url', 'resource', 'assign', 'page', 'videos' ]: recourceItem = QTreeWidgetItem(sectionItem) recourceItem.setFlags(recourceItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) recourceItem.setText(0, recource['name']) recourceItem.setCheckState(0, checkStatus) recourceItem.setIcon( 0, QIcon(":img/mod." + recource['mod'] + ".svg")) totalFiles += 1 elif recource['mod'] == 'folder': folderItem = QTreeWidgetItem(sectionItem) folderItem.setFlags(folderItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) folderItem.setText(0, recource['name']) folderItem.setCheckState(0, checkStatus) folderItem.setIcon(0, QIcon(":img/mod.folder.svg")) for file in recource['data']: fileItem = QTreeWidgetItem(folderItem) fileItem.setFlags(fileItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) fileItem.setText(0, file['name']) fileItem.setCheckState(0, checkStatus) fileItem.setIcon(0, QIcon(":img/mod.resource.svg")) totalFiles += 1 courseItem.removeChild(courseItem.child(0)) tStop = time.time() if self.config['dev'].getboolean('showloadtime'): self.print( string._( 'Load course %s in %.3f sec, total has %d resource(s)') % (courseItem.text(0), tStop - tStart, totalFiles)) def showFileList(self): self.btn_StartBackup.setEnabled(False) courseIndex = 0 for courseItem in [ self.CourseTreeListRoot.child(i) for i in range(self.CourseTreeListRoot.childCount()) ]: courseIndex += 1 self.signal_processbar_value.emit(courseIndex) courseData = self.FileTree[courseItem.text(0)] if courseItem.checkState(0) != QtCore.Qt.Unchecked: for sectionItem in [ courseItem.child(i) for i in range(courseItem.childCount()) ]: sectionItemName = sectionItem.text(0) if sectionItemName == string._( 'There has no resource to download.'): continue sectionData = \ [courseData[i] for i in range(len(courseData)) if courseData[i]['section'] == sectionItemName][0] if sectionItem.checkState(0) != QtCore.Qt.Unchecked: for modItem in [ sectionItem.child(i) for i in range(sectionItem.childCount()) ]: modItemName = modItem.text(0) modData = [ sectionData['mods'][i] for i in range(len(sectionData['mods'])) if sectionData['mods'][i]['name'] == modItemName ][0] if modItem.checkState(0) != QtCore.Qt.Unchecked: if modData['mod'] == 'forum': for topicItem in [ modItem.child(i) for i in range( modItem.childCount()) ]: if topicItem.checkState( 0) == QtCore.Qt.Checked: topicName = topicItem.text(0) resource = [ modData['data'][i] for i in range( len(modData['data'])) if modData['data'][i]['name'] == topicName ][0] self.signal_appendDownloadList.emit( resource) elif modData['mod'] in [ 'resource', 'url', 'assign', 'page', 'videos' ]: if modItem.checkState( 0) == QtCore.Qt.Checked: self.signal_appendDownloadList.emit( modData) elif modData['mod'] == 'folder': for fileItem in [ modItem.child(i) for i in range( modItem.childCount()) ]: if fileItem.checkState( 0) == QtCore.Qt.Checked: fileName = fileItem.text(0) resource = [ modData['data'][i] for i in range( len(modData['data'])) if modData['data'][i]['name'] == fileName ][0] self.signal_appendDownloadList.emit( resource) self.retryTimes = 0 self.failedList = [] self.retryList = [] self.success = 0 self.failed = 0 time.sleep(0.5) reqs = threadpool.makeRequests(self.startDownload, range(len(self.fileList))) for req in reqs: self.DownloadPool.putRequest(req) if len(self.fileList) == 0: self.btn_StartBackup.setEnabled(True) else: self.statusProcessBar.setFormat( string._('Downloading...') + "(%v/" + "%d)" % len(self.fileList)) self.statusProcessBar.setMaximum(len(self.fileList)) def startRetry(self): if self.retryAfter == 0: self.retryTimes += 1 self.retryTimer.stop() self.retryList = self.failedList self.failedList = [] reqs = threadpool.makeRequests(self.startDownload, self.retryList) for req in reqs: self.DownloadPool.putRequest(req) self.statusProcessBar.setFormat( string._('Downloading...') + "(%v/" + "%d)" % len(self.retryList)) self.statusProcessBar.setMaximum(len(self.retryList)) else: self.retryAfter -= 1 self.signal_setStartBackupBtn.emit( string._('Download will retry after %d sec.') % self.retryAfter, False) def appendItemToDownloadList(self, Item): self.fileList.append(Item) mod = Item['mod'] if '/' in mod: mod = mod.split('/')[1] row_count = self.StatusTable.rowCount() self.StatusTable.insertRow(row_count) self.StatusTable.setItem(row_count, 0, QTableWidgetItem(Item['name'])) self.StatusTable.setItem(row_count, 1, QTableWidgetItem(Item['path'])) self.StatusTable.setItem( row_count, 2, QTableWidgetItem(QIcon(':img/mod.%s.svg' % mod), Item['mod'])) self.StatusTable.setItem(row_count, 3, QTableWidgetItem('等待中...')) def startDownload(self, idx): if idx < len(self.fileList): self.btn_StartBackup.setText( string._('Downloading...(%d/%d)') % (idx, len(self.fileList))) if self.retryTimes != 0: indexInRetryList = 0 for ele in self.retryList: indexInRetryList += 1 if ele == idx: break self.btn_StartBackup.setText( string._('Downloading...(%d/%d)') % (indexInRetryList, len(self.retryList))) self.signal_processbar_value.emit(idx) self.print(string._('Start to download %dth file') % (idx + 1)) self.web.DownloadFile(idx, self.fileList[idx]) time.sleep(0.5) def StartBackup(self): self.fileList = [] self.StatusTable.setRowCount(0) self.statusProcessBar.setFormat( string._('Loading file list') + "(%v" + "/%d)" % self.CourseTreeListRoot.childCount()) self.statusProcessBar.setMaximum(self.CourseTreeListRoot.childCount()) self.showFileList() def showInformation(self): QMessageBox.about(self, string._('About'), string._('tool Information') % self.version) def TestiLearnConnection(self): self.statusbar.showMessage( string._('Testing connection with iLearn2...')) self.label_iLearn.setText(string._('Connecting...')) if self.web.TestConnection(): # ==Ture self.statusbar.showMessage(string._('Connect to iLearn2 success!')) self.label_iLearn.setText(string._('Connect success!')) else: self.statusbar.showMessage(string._('Can not connect to iLearn2!')) self.label_iLearn.setText(string._('Connect failed!')) def readSetting(self): try: self.config.read('setting.ini', encoding='utf-8') OPTION = self.config.get('User', 'userealfilename') OPTION = self.config.get('User', 'language') OPTION = self.config.get('User', 'retrytimes') OPTION = self.config.get('User', 'secondbetweenretry') OPTION = self.config.get('dev', 'nid') OPTION = self.config.get('dev', 'pass') OPTION = self.config.get('dev', 'showloadtime') except: self.config['User'] = {} self.config['User']['userealfilename'] = 'False' self.config['User']['language'] = '繁體中文' self.config['dev'] = {} self.config['dev']['nid'] = '' self.config['dev']['pass'] = '' self.config['dev']['autologin'] = '******' self.config['dev']['showloadtime'] = 'False' self.config['User']['retrytimes'] = '3' self.config['User']['secondbetweenretry'] = '5' with open('setting.ini', 'w', encoding='utf-8') as configfile: self.config.write(configfile) def restart(self): subprocess.Popen("iLearnBackupTool") self.close()
def create_complex_node(self, key, value, root=None): # 0: key, 1:value, 2:type 3:file/image path sub_node = None if isinstance(value, (int, float)): if root is None: sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) sub_node.setText(1, str(value)) sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable) else: sub_node = create_tree_item(key=key, value=value, edit=True) root.addChild(sub_node) root.setExpanded(True) elif isinstance(value, str): if root is None: sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) sub_node.setText(1, str(value)) if key not in DISABLE_EDIT_KEYS: sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable) else: enable_edit = False if key in [ ITEM_TYPE_ELEMENT_NAME, ITEM_CONDITION_NAME, ITEM_CONDITIONS_NAME ]: enable_edit = True sub_node = create_tree_item(key=key, value=value, edit=enable_edit) root.addChild(sub_node) if key == 'algorithm': self._create_algorithm_node(key=key, value=value, node=sub_node) elif key == 'type': self._set_type_node(key, value, sub_node) elif isinstance(value, dict): if root is None: sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) else: sub_node = create_tree_item(key=key) root.addChild(sub_node) if key == 'refer': sub_node.setText(2, ITEM_TYPE_REFER_TASK) for sub_key, sub_value in value.items(): self.create_complex_node(key=sub_key, value=sub_value, root=sub_node) sub_node.setExpanded(True) elif isinstance(value, list): if key == 'elements': sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) sub_node.setText(2, ITEM_TYPE_ELEMENTS) sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable) else: sub_node = root for sub_value in value: rename_key = key[:-1] sub_type = ITEM_TYPE_ELEMENT if rename_key == 'template': sub_type = ITEM_TYPE_TEMPLATE enable_edit = False ss_node = create_tree_item(key=rename_key, node_type=sub_type, edit=enable_edit) sub_node.addChild(ss_node) for ss_key, ss_value in sub_value.items(): self.create_complex_node(key=ss_key, value=ss_value, root=ss_node) ss_node.setExpanded(True) sub_node.setExpanded(True) if sub_node is None: return if key in SCENE_HIDDEN_KEYS: sub_node.setHidden(True)
def appedResourceToTree(self, i, courseItem): course = self.courseList[i] try: self.timer.stop() except: pass tStart = time.time() if course['title'] not in self.FileTree: courseFileList = self.web.getCourseFileList( course, useRealFileName=self.config['User'].getboolean( 'userealfilename'), showTime=self.config['dev'].getboolean('showloadtime')) if course['title'] not in self.FileTree: self.FileTree[course['title']] = courseFileList self.nowLoad += 1 else: courseFileList = self.FileTree[course['title']] checkStatus = courseItem.checkState(0) totalFiles = 0 if len(courseFileList) == 0: sectionItem = QTreeWidgetItem(courseItem) sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) sectionItem.setText(0, string._('There has no resource to download.')) sectionItem.setCheckState(0, checkStatus) for section in courseFileList: sectionItem = QTreeWidgetItem(courseItem) sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) sectionItem.setText(0, section['section']) sectionItem.setCheckState(0, checkStatus) sectionItem.setIcon(0, QIcon(":img/mod.folder.svg")) for recource in section['mods']: if recource['mod'] == 'forum': forumItem = QTreeWidgetItem(sectionItem) forumItem.setFlags(forumItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) forumItem.setText(0, recource['name']) forumItem.setCheckState(0, checkStatus) forumItem.setIcon(0, QIcon(":img/mod.discuss.svg")) for topic in recource['data']: topicItem = QTreeWidgetItem(forumItem) topicItem.setFlags(topicItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) topicItem.setText(0, topic['name']) topicItem.setCheckState(0, checkStatus) topicItem.setIcon(0, QIcon(":img/mod.discuss.svg")) totalFiles += 1 elif recource['mod'] in [ 'url', 'resource', 'assign', 'page', 'videos' ]: recourceItem = QTreeWidgetItem(sectionItem) recourceItem.setFlags(recourceItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) recourceItem.setText(0, recource['name']) recourceItem.setCheckState(0, checkStatus) recourceItem.setIcon( 0, QIcon(":img/mod." + recource['mod'] + ".svg")) totalFiles += 1 elif recource['mod'] == 'folder': folderItem = QTreeWidgetItem(sectionItem) folderItem.setFlags(folderItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) folderItem.setText(0, recource['name']) folderItem.setCheckState(0, checkStatus) folderItem.setIcon(0, QIcon(":img/mod.folder.svg")) for file in recource['data']: fileItem = QTreeWidgetItem(folderItem) fileItem.setFlags(fileItem.flags() | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable) fileItem.setText(0, file['name']) fileItem.setCheckState(0, checkStatus) fileItem.setIcon(0, QIcon(":img/mod.resource.svg")) totalFiles += 1 courseItem.removeChild(courseItem.child(0)) tStop = time.time() if self.config['dev'].getboolean('showloadtime'): self.print( string._( 'Load course %s in %.3f sec, total has %d resource(s)') % (courseItem.text(0), tStop - tStart, totalFiles))
def TreeItem(self, parent, name, tooltip, icon): child = QTreeWidgetItem(parent) child.setText(0, name) child.setToolTip(0, tooltip) child.setIcon(0, QIcon(icon)) child.setFlags(child.flags())
def __generateItem(self, status, propStatus, locked, history, switched, lockinfo, uptodate, revision, change, author, path): """ Private method to generate a status item in the status list. @param status status indicator (string) @param propStatus property status indicator (string) @param locked locked indicator (string) @param history history indicator (string) @param switched switched indicator (string) @param lockinfo lock indicator (string) @param uptodate up to date indicator (string) @param revision revision string (string) @param change revision of last change (string) @param author author of the last change (string) @param path path of the file or directory (string) """ if self.__nonverbose and \ status == " " and \ propStatus == " " and \ locked == " " and \ history == " " and \ switched == " " and \ lockinfo == " " and \ uptodate == " " and \ self.currentChangelist == "": return if revision == "": rev = "" else: try: rev = int(revision) except ValueError: rev = revision if change == "": chg = "" else: try: chg = int(change) except ValueError: chg = change statusText = self.status[status] itm = QTreeWidgetItem(self.statusList) itm.setData(0, Qt.DisplayRole, "") itm.setData(1, Qt.DisplayRole, self.currentChangelist) itm.setData(2, Qt.DisplayRole, statusText) itm.setData(3, Qt.DisplayRole, self.propStatus[propStatus]) itm.setData(4, Qt.DisplayRole, self.locked[locked]) itm.setData(5, Qt.DisplayRole, self.history[history]) itm.setData(6, Qt.DisplayRole, self.switched[switched]) itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo]) itm.setData(8, Qt.DisplayRole, self.uptodate[uptodate]) itm.setData(9, Qt.DisplayRole, rev) itm.setData(10, Qt.DisplayRole, chg) itm.setData(11, Qt.DisplayRole, author) itm.setData(12, Qt.DisplayRole, path) itm.setTextAlignment(1, Qt.AlignLeft) itm.setTextAlignment(2, Qt.AlignHCenter) itm.setTextAlignment(3, Qt.AlignHCenter) itm.setTextAlignment(4, Qt.AlignHCenter) itm.setTextAlignment(5, Qt.AlignHCenter) itm.setTextAlignment(6, Qt.AlignHCenter) itm.setTextAlignment(7, Qt.AlignHCenter) itm.setTextAlignment(8, Qt.AlignHCenter) itm.setTextAlignment(9, Qt.AlignRight) itm.setTextAlignment(10, Qt.AlignRight) itm.setTextAlignment(11, Qt.AlignLeft) itm.setTextAlignment(12, Qt.AlignLeft) if status in "ADM" or propStatus in "M": itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) else: itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable) self.hidePropertyStatusColumn = self.hidePropertyStatusColumn and \ propStatus == " " self.hideLockColumns = self.hideLockColumns and \ locked == " " and lockinfo == " " self.hideUpToDateColumn = self.hideUpToDateColumn and uptodate == " " self.hideHistoryColumn = self.hideHistoryColumn and history == " " self.hideSwitchedColumn = self.hideSwitchedColumn and switched == " " if statusText not in self.__statusFilters: self.__statusFilters.append(statusText)
def FolderItem(self, parent, name, icon): table_folder = QTreeWidgetItem(parent) table_folder.setText(0, name) table_folder.setIcon(0, QIcon(icon)) table_folder.setFlags(table_folder.flags()) return table_folder
class Window(QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.plot_title = 'f(R),f(R,Q),GR comparison for Mass and Radius' self.xlabel = "$R[km]$" self.ylabel = r'$M[M_\odot]$' self.xlim = (8.0, 20.0) tree = QTreeWidget() headerItem = QTreeWidgetItem() item = QTreeWidgetItem() tree_fRQ = QTreeWidget() headerItem_fRQ = QTreeWidgetItem() item_fRQ = QTreeWidgetItem() tree_GR = QTreeWidget() headerItem_GR = QTreeWidgetItem() item_GR = QTreeWidgetItem() tree_quantities = QTreeWidget() headerItem_quantities = QTreeWidgetItem() item_quantities = QTreeWidgetItem() self.quant_branch = QTreeWidgetItem(tree_quantities) self.quant_branch.setText(0, "Quantities") self.quant_branch.setFlags(self.quant_branch.flags() ) # self.GR_branch.setCheckState(0, Qt.Unchecked) child = QTreeWidgetItem(self.quant_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setText(0, 'R-M') child.setCheckState(0, Qt.Checked) child.emitDataChanged() # .connect(self.plot) child = QTreeWidgetItem(self.quant_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) child.setText(0, 'rho-M') child.setCheckState(0, Qt.Unchecked) child.emitDataChanged() self.GR_branch = QTreeWidgetItem(tree_GR) self.GR_branch.setText(0, "GR") self.GR_branch.setFlags(self.GR_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) #self.GR_branch.setCheckState(0, Qt.Unchecked) for x in range(len(glob.glob('Results/TOV_output_GR_*'))): child = QTreeWidgetItem(self.GR_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) checktext = GR_Modellist[x].EOS_type child.setText(0,checktext) child.setCheckState(0, Qt.Unchecked) child.emitDataChanged()# .connect(self.plot) self.fR_branch = QTreeWidgetItem(tree) self.fR_branch.setText(0,"fR") self.fR_branch.setFlags(self.fR_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for x in range(len(glob.glob('Results/TOV_output_fR_*'))): child = QTreeWidgetItem(self.fR_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) checktext = fR_Modellist[x].ID + fR_Modellist[x].EOS_type child.setText(0,checktext) child.setCheckState(0, Qt.Unchecked) child.emitDataChanged()# .connect(self.plot) #if(fRQ_branch.child(1).isSelected==1){print("hey hey")} self.fRQ_branch = QTreeWidgetItem(tree_fRQ) self.fRQ_branch.setText(0, "fRQ") self.fRQ_branch.setFlags(self.fRQ_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) for x in range(len(glob.glob('Results/TOV_output_fRQ_*'))): child = QTreeWidgetItem(self.fRQ_branch) child.setFlags(child.flags() | Qt.ItemIsUserCheckable) checktext = fRQ_Modellist[x].ID + fRQ_Modellist[x].EOS_type child.setText(0, checktext) child.setCheckState(0, Qt.Unchecked) print("checked?", self.fR_branch.child(0).isSelected()) tree.itemChanged.connect(self.plot) tree_fRQ.itemChanged.connect(self.plot) tree_GR.itemChanged.connect(self.plot) tree_quantities.itemChanged.connect(self.quant_change) tree_quantities.itemChanged.connect(self.plot) #tree.show() # a figure instance to plot on self.figure = plt.figure() # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) # Just some button connected to `plot` method #self.button = QPushButton('Plot') #self.button.clicked.connect(self.plot) # set the layout self.layout = QVBoxLayout() self.sublayout1 = QVBoxLayout() self.sublayout2 = QHBoxLayout() plotBox = QHBoxLayout() plotBox.addLayout(self.sublayout1, 1) plotBox.addLayout(self.sublayout2, 4) bottomlayout = QHBoxLayout() #self.layout.addLayout() self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas,1) #self.layout.addWidget(self.button) self.setLayout(self.layout) #layout = QHBoxLayout() self.btn_rhoM = QCheckBox("rho-M") self.btn_RM = QCheckBox("R-M") self.btn_GR = QCheckBox("GR") self.btn_fR = QCheckBox("fR") self.btn_fRQ = QCheckBox("fRQ") self.btn_fRs = [] self.btn_rhoM.setChecked(False) self.btn_RM.setChecked(True) self.btn_GR.setChecked(False) self.btn_fR.setChecked(False) self.btn_fRQ.setChecked(False) #self.b1.stateChanged.connect(lambda: self.btnstate(self.b1)) #self.btn_rhoM.stateChanged.connect(self.quant_change) #self.btn_RM.stateChanged.connect(self.quant_change) self.btn_rhoM.stateChanged.connect(self.plot) self.btn_RM.stateChanged.connect(self.plot) self.btn_GR.stateChanged.connect(self.plot) self.btn_fR.stateChanged.connect(self.plot) self.btn_fRQ.stateChanged.connect(self.plot) #self.layout.addWidget(self.btn_GR) #self.layout.addWidget(self.btn_fR) #self.layout.addWidget(self.btn_fRQ) self.sublayout2.addWidget(tree_quantities) self.sublayout2.addWidget(tree_GR) self.sublayout2.addWidget(tree) self.sublayout2.addWidget(tree_fRQ) self.layout.addLayout(plotBox) def quant_change(self): if(self.quant_branch.child(0).checkState(0)): self.plot_title = 'f(R),f(R,Q),GR comparison for Radius and Mass of NS' self.xlabel = "R[km]" self.ylabel = r'M[$M_\odot$]' self.xlim = (8.0, 20.0) if (self.quant_branch.child(1).checkState(0)): self.plot_title = 'f(R),f(R,Q),GR comparison for Central Density and Mass of NS' self.xlabel = r'$\log\rho_c[\frac{g}{cm^3}]$' self.ylabel = r'M[$M_\odot$]' self.xlim = (13.5, 17.0) def plot(self): fR_label = 'f(R)\n $(R_p=$' + r'$%s$' % fR_Rp + r'$)$' fRQ_label = 'f(R,Q) \n $(R_p=$' + r'$%s$' % fRQ_Rp + '$)$\n ' + r'$(R_q=$' + r'$%s$' % fRQ_Rq + '$)$' if self.btn_fR.isChecked() == True: #self.btn_fRs.append(QCheckBox("yep")) print("self.fR_branch.child(i).isSelected()", self.fR_branch.child(i).isSelected()) self.layout.addWidget(self.btn_fRs[0]) plt.plot(x, y, label=r'${}$'.format(fR_label), color='blue') plt.title('fR/GR comparison for Mass and Radius for $R_p=2.1*10^{80}$') plt.legend(fontsize=20) #plt.show() ''' plot some random stuff ''' # random data #data = [random.random() for i in range(10)] # instead of ax.hold(False) self.figure.clear() # create an axis ax = self.figure.add_subplot(111) # discards the old graph # ax.hold(False) # deprecated, see above # plot data for i in range(len(glob.glob('Results/TOV_output_GR_*'))): if self.GR_branch.child(i).checkState(0): labelly = 'GR ' + GR_Modellist[i].EOS_type if (self.quant_branch.child(0).checkState(0)): ax.plot(GR_Modellist[i].rad, GR_Modellist[i].mass, label=labelly) #, next(linecycler) if (self.quant_branch.child(1).checkState(0)): ax.plot(GR_Modellist[i].rho, GR_Modellist[i].mass, label=labelly) #, next(linecycler) for i in range(len(glob.glob('Results/TOV_output_fR_*'))): if self.fR_branch.child(i).checkState(0): labelly = 'f(R) ' + fR_Modellist[i].EOS_type + ": R_p= " + fR_Modellist[i].ID if (self.quant_branch.child(0).checkState(0)): ax.plot(fR_Modellist[i].rad,fR_Modellist[i].mass,next(linecycler),label=r'${}$'.format(labelly)) if (self.quant_branch.child(1).checkState(0)): ax.plot(fR_Modellist[i].rho, fR_Modellist[i].mass,next(linecycler), label=r'${}$'.format(labelly)) #print(self.fR_branch.child(i).isSelected()) #ax.plot(x5, y5, label='GR', color='black') for i in range(len(glob.glob('Results/TOV_output_fRQ_*'))): if self.fRQ_branch.child(i).checkState(0): labelly = 'f(R,Q) ' + fRQ_Modellist[i].EOS_type + ": R_p= " + fRQ_Modellist[i].ID if (self.quant_branch.child(0).checkState(0)): ax.plot(fRQ_Modellist[i].rad,fRQ_Modellist[i].mass,next(linecycler),label=r'${}$'.format(labelly)) if (self.quant_branch.child(1).checkState(0)): ax.plot(fRQ_Modellist[i].rho, fRQ_Modellist[i].mass, next(linecycler), label=r'${}$'.format(labelly)) #ax.plot(x5, y5, label='GR', color='black') #print(fRQ_Modellist[i].rad, " ", fRQ_Modellist[i].mass) ax.legend(fontsize=15) if self.btn_fRQ.isChecked() == True: ax.plot(x2, y2, label=fRQ_label, color='blue') ax.legend(fontsize=20) #ax.set_title(self.plot_title) ax.set_xlim(self.xlim) ax.set_xlabel(self.xlabel,fontsize=20) ax.set_ylabel(self.ylabel,fontsize=20) # refresh canvas self.canvas.draw() def btnstate(self, b): if b.text() == "fR": if b.isChecked() == True: self.plot(b)