class CurvePanel(QListView): def __init__(self, curve_source): QListView.__init__(self) self.curve_source = curve_source self.setViewMode(QListView.IconMode) self.setIconSize(QSize(64,64)) self.model = QStandardItemModel() for curve in curve_source._curves: self.add_curve(curve) self.setModel(self.model) self.setWrapping(True) self.show() def edit(self, index, trigger, event): if trigger == QAbstractItemView.DoubleClicked: item = self.model.item(index.row()) curve = item.curve print curve.name() return True else: return False def add_new_curve(self): pass def add_curve(self, curve): name = curve.name() plot = self._create_plot(name) item = PlotItem(plot) item.curve = curve self.model.appendRow(item) def _create_plot(self, xcurve_name): index = self.curve_source.index() return Plot.of(xcurve_name, index.name()).from_(self.curve_source)
def getSampleModel(spl, flags='peak', **kw): from gui.MetBaseGui import MSStandardItem if flags not in ('peak', 'cluster', 'id'): return model = QStandardItemModel() if flags == 'peak': from utils.misc import Hot areas = [peak.area for peak in spl.rawPeaks.ipeaks()] mxInt = max(areas) model.setHorizontalHeaderLabels(MSSample.peakModelLabel) for i, peak in enumerate(spl.rawPeaks.ipeaks()): model.setItem(i, 0, MSStandardItem(str(peak.mass()))) model.item(i, 0).setBackground( QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5))) model.setItem(i, 1, MSStandardItem(str(peak.rt))) model.item(i, 1).setBackground( QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5))) model.setItem(i, 2, MSStandardItem(str(peak.area))) model.item(i, 2).setBackground( QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5))) model.setItem(i, 3, MSStandardItem(str(peak.sn))) model.item(i, 3).setBackground( QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5))) model.setItem(i, 4, MSStandardItem(str(peak.r_coef))) model.item(i, 4).setBackground( QBrush(Hot._get_color(areas[i] / mxInt, True, alpha=0.5))) elif flags == 'cluster': model.setHorizontalHeaderLabels(MSSample.clusterModelLabel) for i, peak in enumerate(spl.mappedPeaks.ipeaks()): model.setItem(i, 0, MSStandardItem(str(peak.mass()))) model.setItem(i, 1, MSStandardItem(str(peak.rt))) model.setItem(i, 2, MSStandardItem(str(peak.area))) info_iso = "" info_frag = "" for iso in peak.isoCluster: info_iso += '%s/%s\t' % (str(iso.mass()), str(iso.rt)) for add in peak.fragCluster: info_frag += '%s/%s\t' % (str(add.mass()), str(add.rt)) model.setItem(i, 3, MSStandardItem(info_iso)) model.setItem(i, 4, MSStandardItem(info_frag)) return model
class DataModel(object): def __init__(self): super(DataModel,self).__init__() self.servers = QStandardItemModel(0,3) self.selected = '' self.autoconnect = False def loadSettings(self): settings = QSettings() servers = settings.value("servers", None) self.servers.clear() if servers: for s in servers: self.servers.appendRow([QStandardItem(str(i)) for i in s]) self.selected = str(settings.value("selected", self.selected)) self.autoconnect = int(settings.value("autoconnect", self.autoconnect)) def saveSettings(self): settings = QSettings() servers = [] if self.servers: for row in xrange(self.servers.rowCount()): entry = [] for col in xrange(self.servers.columnCount()): entry += [self.servers.item(row,col).text()] servers += [entry] if len(servers): settings.setValue("servers", servers) else: settings.setValue("servers", None) settings.setValue("selected", str(self.selected)) settings.setValue("autoconnect", int(self.autoconnect)) def selectedServer(self): selectedServer = [] if self.selected: result = self.servers.findItems( self.selected) if len(result): mi = result[0] row = mi.row() for col in xrange(self.servers.columnCount()): selectedServer += [self.servers.item(row,col).text()] return selectedServer
def getSampleModel(spl, flags='peak', **kw): from gui.MetBaseGui import MSStandardItem if flags not in ('peak', 'cluster', 'id'): return model = QStandardItemModel() if flags=='peak': from utils.misc import Hot areas=[peak.area for peak in spl.rawPeaks.ipeaks()] mxInt=max(areas) model.setHorizontalHeaderLabels(MSSample.peakModelLabel) for i, peak in enumerate(spl.rawPeaks.ipeaks()): model.setItem(i, 0, MSStandardItem(str(peak.mass()))) model.item(i, 0).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5))) model.setItem(i, 1, MSStandardItem(str(peak.rt))) model.item(i, 1).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5))) model.setItem(i, 2, MSStandardItem(str(peak.area))) model.item(i, 2).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5))) model.setItem(i, 3, MSStandardItem(str(peak.sn))) model.item(i, 3).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5))) model.setItem(i, 4, MSStandardItem(str(peak.r_coef))) model.item(i, 4).setBackground(QBrush(Hot._get_color(areas[i]/mxInt, True, alpha=0.5))) elif flags=='cluster': model.setHorizontalHeaderLabels(MSSample.clusterModelLabel) for i, peak in enumerate(spl.mappedPeaks.ipeaks()): model.setItem(i, 0, MSStandardItem(str(peak.mass()))) model.setItem(i, 1, MSStandardItem(str(peak.rt))) model.setItem(i, 2, MSStandardItem(str(peak.area))) info_iso ="";info_frag="" for iso in peak.isoCluster: info_iso += '%s/%s\t'%(str(iso.mass()),str(iso.rt)) for add in peak.fragCluster: info_frag += '%s/%s\t'%(str(add.mass()),str(add.rt)) model.setItem(i, 3, MSStandardItem(info_iso)) model.setItem(i, 4, MSStandardItem(info_frag)) return model
class ListViewWindow(QtGui.QWidget): def __init__(self): super(ListViewWindow, self).__init__() # ui_full_path = find_file_in_product('list_ui_widget.ui') ui_full_path = find_resource_in_pkg('list_window.ui') self.ui = uic.loadUi(ui_full_path, self) self.model = QStandardItemModel() self._mouse_button = None self.listView.setModel(self.model) # self.show() self.listView.clicked.connect(self.item_clicked) # self.listView.doubleClicked.connect(self.handle_right_click) self.minimized = True self.click_handler = None self.right_click_handler = None self.list_view_mouse_pressed = self.listView.mousePressEvent self.listView.mousePressEvent = self.mousePressEvent # self.ui.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # self.ui.connect(self.ui, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), # self.on_context) # # def on_context(self, point): # # Create a menu # menu = QtGui.QMenu("Menu", self) # menu.addAction(self.mAction1) # menu.addAction(self.mAction2) # # Show the context menu. # menu.exec_(self.view.mapToGlobal(point)) def item_clicked(self, index): row_text = str(self.model.item(index.row()).text()) # mouse_buttons = QtGui.qApp.mouseButtons() # print int(mouse_buttons) if self._mouse_button == QtCore.Qt.RightButton: if self.right_click_handler: self.right_click_handler(row_text) elif not (self.click_handler is None): self.click_handler(row_text) # def handle_right_click(self, index): # row_text = str(self.model.item(index.row()).text()) # if self.right_click_handler: # self.right_click_handler(row_text) def set_click_handler(self, callback_func): self.click_handler = callback_func def mousePressEvent(self, event): self._mouse_button = event.button() self.list_view_mouse_pressed(event)
class ApplicationList(QtGui.QWidget, MinimizeOnClose): def __init__(self): super(ApplicationList, self).__init__() ui_full_path = fileTools.findFileInProduct('app_list.ui') self.ui = uic.loadUi(ui_full_path, self) self.model = QStandardItemModel() ''' item = QStandardItem('Hello world') item1 = QStandardItem('Hello world1') item.setCheckState(Qt.Checked) item.setCheckable(True) item1.setCheckState(Qt.Checked) item1.setCheckable(True) self.model.appendRow(item) self.model.appendRow(item1) ''' self.listView.setModel(self.model) ''' self.connect(self.listView.selectionModel(), QtCore.SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.store_current_selection) ''' self.show() self.listView.clicked.connect(self.item_clicked) def item_clicked(self, index): self.callback_func(str(self.model.item(index.row()).text())) ''' #--------------------------------------------------------------------------- def store_current_selection(self, newSelection, oldSelection): indexes = newSelection.indexes() for index in indexes: text = u"(%i,%i)" % (index.row(), index.column()) #self.model.setData(index, text) #print text #print self.model.item(index.row()).text() self.callback_func(str(self.model.item(index.row()).text()) ''' def set_callback(self, callback_func): self.callback_func = callback_func
def initListView(self): """Init status table""" # List Box model model = QStandardItemModel() # Init list objects for i, frame in enumerate(self.task.videoLabelHandler.files): item = QStandardItem(frame + "\t{0} Objects".format(len(self.task.videoLabelHandler.objects))) item.setCheckState(Qt.Checked) item.setCheckable(True) model.appendRow(item) if self.segmentation_mode: model.item(0).setEnabled(False) else: model.item(i).setCheckState(Qt.Unchecked) model.item(i).setEnabled(False) # Set model self.view.setModel(model)
class STRPartyListView(QListView): """ A widget for listing and selecting STR party entities. .. versionadded:: 1.5 """ party_selected = pyqtSignal(QStandardItem) party_deselected = pyqtSignal(QStandardItem) def __init__(self, parent=None, profile=None, social_tenure=None): super(STRPartyListView, self).__init__(parent) self._model = QStandardItemModel(self) self._model.setColumnCount(1) self.setModel(self._model) self.setEditTriggers(QAbstractItemView.NoEditTriggers) self._model.itemChanged.connect(self._on_item_changed) self._profile = profile if not self._profile is None: self._load_profile_entities() self._social_tenure = social_tenure if not self._social_tenure is None: self.select_parties(self._social_tenure.parties) def _on_item_changed(self, item): # Emit signals when an item has been (de)selected. if item.checkState() == Qt.Checked: self.party_selected.emit(item) elif item.checkState() == Qt.Unchecked: self.party_deselected.emit(item) @property def profile(self): """ :return: Returns the current profile object in the configuration. :rtype: Profile """ return self._profile @profile.setter def profile(self, profile): """ Sets the current profile object in the configuration. :param profile: Profile object. :type profile: Profile """ self._profile = profile self._load_profile_entities() @property def social_tenure(self): """ :return: Returns the profile's social tenure entity. :rtype: SocialTenure """ return self._social_tenure @social_tenure.setter def social_tenure(self, social_tenure): """ Set the social_tenure entity. :param social_tenure: A profile's social tenure entity. :type social_tenure: SocialTenure """ self._social_tenure = social_tenure self.select_parties(self._social_tenure.parties) def _load_profile_entities(self): # Reset view self.clear() # Populate entity items in the view for e in self._profile.user_entities(): self._add_entity(e) def _add_entity(self, party): # Add entity item to view item = QStandardItem(QIcon(':/plugins/stdm/images/icons/table.png'), party.short_name) item.setCheckable(True) item.setCheckState(Qt.Unchecked) self._model.appendRow(item) def select_parties(self, parties): """ Checks party entities in the view and emit the party_selected signal for each item selected. :param parties: Collection of STR party entities. :type parties: list """ # Clear selection self.clear_selection() for p in parties: name = p.short_name self.select_party(name) def parties(self): """ :return: Returns a list of selected party names. :rtype: list """ selected_items = [] for i in range(self._model.rowCount()): item = self._model.item(i) if item.checkState() == Qt.Checked: selected_items.append(item.text()) return selected_items def clear(self): """ Remove all party items in the view. """ self._model.clear() self._model.setColumnCount(1) def clear_selection(self): """ Uncheck all items in the view. """ for i in range(self._model.rowCount()): item = self._model.item(i) if item.checkState() == Qt.Checked: item.setCheckState(Qt.Unchecked) def select_party(self, name): """ Selects a party entity with the given short name. :param name: Entity short name :type name: str """ items = self._model.findItems(name) if len(items) > 0: item = items[0] if item.checkState() == Qt.Unchecked: item.setCheckState(Qt.Checked) def deselect_party(self, name): """ Deselects a party entity with the given short name. :param name: Entity short name :type name: str """ items = self._model.findItems(name) if len(items) > 0: item = items[0] if item.checkState() == Qt.Checked: item.setCheckState(Qt.Unchecked)
class LogDialog(QDialog): """LogDialog for the Freeseer project. It is the dialog window for the log. There is an instance for every FreeseerApp. It has a LogHandler which calls LogDialog's message() method when a new log message is received. The call to message() causes a call to add_entry() which adds the information to a new row in the table. """ def __init__(self, parent=None): super(LogDialog, self).__init__(parent) self.resize(800, 500) self.app = QApplication.instance() icon = QIcon() icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) layout = QVBoxLayout() self.setLayout(layout) self.level = 0 self.handler = LogHandler() self.table_model = QStandardItemModel(0, 5) header_names = ["Date", "Level", "Module", "Message", "LevelNo"] date_column = header_names.index("Date") level_column = header_names.index("Level") module_column = header_names.index("Module") self.level_num_column = header_names.index("LevelNo") self.table_model.setHorizontalHeaderLabels(header_names) self.table_view = QTableView() self.table_view.setModel(self.table_model) self.table_view.horizontalHeader().setStretchLastSection(True) self.table_view.setColumnWidth(date_column, 125) self.table_view.setColumnWidth(level_column, 60) self.table_view.setColumnWidth(module_column, 250) self.table_view.setColumnHidden(self.level_num_column, True) self.table_view.setShowGrid(False) self.table_view.horizontalHeader().setClickable(False) self.table_view.verticalHeader().hide() self.table_view.setStyleSheet("""Qtable_view::item { border-bottom: 1px solid lightgrey; selection-background-color: white; selection-color: black; }""") top_panel = QHBoxLayout() self.log_levels = ["Debug", "Info", "Warning", "Error"] self.level_colors = ["#3E4C85", "#269629", "#B0AB21", "#B32020"] self.levels_label = QLabel("Filter Level: ") self.levels_label.setStyleSheet("QLabel { font-weight: bold }") self.current_level_label = QLabel(self.log_levels[0]) self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format(self.level_colors[0])) self.clear_button = QPushButton("Clear Log") self.levels_slider = QSlider(Qt.Horizontal) self.levels_slider.setStyleSheet(""" QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FFFFFF, stop:1 #E3E3E3); border: 1px solid #707070; width: 10px; margin-top: -4px; margin-bottom: -4px; border-radius: 4px; } QSlider::handle:horizontal:hover { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #DEDEDE, stop:1 #C9C9C9); border: 1px solid #4F4F4F; border-radius: 4px; } QSlider::sub-page:horizontal { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #BFBFBF, stop: 1 #9E9E9E); background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1, stop: 0 #9E9E9E, stop: 1 #858585); border: 1px solid #777; height: 10px; border-radius: 4px; } QSlider::add-page:horizontal { background: #fff; border: 1px solid #707070; height: 10px; border-radius: 4px; }""") self.levels_slider.setRange(0, len(self.log_levels) - 1) self.levels_slider.setTickPosition(QSlider.TicksBelow) self.levels_slider.setTickInterval(1) top_panel.addSpacerItem(QSpacerItem(10, 0)) top_panel.addWidget(self.levels_label, 3) top_panel.addWidget(self.current_level_label, 2) top_panel.addWidget(self.levels_slider, 8) top_panel.addSpacerItem(QSpacerItem(25, 0)) top_panel.addWidget(self.clear_button, 10) layout.addLayout(top_panel) layout.addWidget(self.table_view) self.connect(self.clear_button, SIGNAL('clicked()'), functools.partial(self.table_model.setRowCount, 0)) self.connect(self.levels_slider, SIGNAL('valueChanged(int)'), self.slider_set_level) self.setWindowTitle("Log") self.handler.add_listener(self) def __del__(self): self.handler.remove_listener(self) def retranslate(self): self.setWindowTitle(self.app.translate("LogDialog", "Log")) self.clear_button.setText(self.app.translate("LogDialog", "Clear Log")) self.levels_label.setText("{}: ".format(self.app.translate("LogDialog", "Filter Level"))) def message(self, message): """Passes the log fields to add_entry() It is called by LogHandler when a log message is received""" self.add_entry(message["time"], message["level"], message["full_module_name"], message["message"], str(message["levelno"])) def add_entry(self, date, level, module, message, levelno): """Adds the given fields to a new row in the log table It is called by message() when a log message is received""" items = [QStandardItem(date), QStandardItem(level), QStandardItem(module), QStandardItem(message), QStandardItem(levelno)] for item in items: item.setEditable(False) self.table_model.appendRow(items) def slider_set_level(self, level): self.current_level_label.setText(self.log_levels[level]) self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format(self.level_colors[level])) self.set_level(level + 1) def set_level(self, level): """Sets the current level of the LogDialog. Level is based on the selection made in the levels_combo_box. It hides all messages with a lower level.""" self.level = level * 10 for i in range(self.table_model.rowCount()): if int(str(self.table_model.item(i, self.level_num_column).text())) < self.level: self.table_view.setRowHidden(i, True) else: self.table_view.setRowHidden(i, False)
class SubPowerWidget(QWidget): """ @brief Zeigt alle Unterkräfte in einer Baumstruktur an. """ def __init__(self, template, character, parent=None): super(SubPowerWidget, self).__init__(parent) self.__storage = template self.__character = character self.__model = QStandardItemModel() # Das ungenutzte Model dient dazu, alle Unterkräfte aufzunehmen, die ich nicht darstellen möchte. Ist einfacher, als diese im View zu verstecken. self.__modelUnused = QStandardItemModel() self._layout = QVBoxLayout() self.setLayout( self._layout ) self.__view = QTreeView() self.__view.setHeaderHidden(True) self.__view.setModel( self.__model) self._layout.addWidget(self.__view) self._typ = "Subpower" categories = self.__storage.categories(self._typ) self.__items = {} self.__rootItem = QStandardItem() self.__rootItem = self.__model.invisibleRootItem() self.__rootItemUnused = QStandardItem() self.__rootItemUnused = self.__modelUnused.invisibleRootItem() for item in categories: categoryItem = QStandardItem(item) self.__rootItem.appendRow(categoryItem) ## Ich benötige diese Items auch im ungenutzten Model. categoryItemUnused = QStandardItem(item) self.__rootItemUnused.appendRow(categoryItemUnused) traitList = list( self.__character.traits[self._typ][item].items() ) traitList.sort() for trait in traitList: traitItem = QStandardItem(trait[1].name) traitItem.setCheckable(True) ## Unhashable Type self.__items[trait[1]] = traitItem categoryItem.appendRow(traitItem) ## Funktioniert mit PySide nicht: #trait[1].availableChanged.connect(traitItem.setEnabled) ## Funktioniert auch mit PySide: trait[1].availableChanged.connect( lambda enable, item=traitItem: item.setEnabled(enable) ) trait[1].valueChanged.connect( lambda val, trait=trait[1], item=traitItem: self.__setItemValue(trait, item) ) self.__model.itemChanged.connect(self.__getItemValue) self.__character.speciesChanged.connect(self.hideOrShowToolPage) self.__character.breedChanged.connect(self.hideOrShowToolPage) self.__character.factionChanged.connect(self.hideOrShowToolPage) def __setItemValue(self, trait, item): """ Setzt den Wert der Angezeigten Items. """ if trait.value == 0: item.setCheckState(Qt.Unchecked) elif trait.value == 1: item.setCheckState(Qt.PartiallyChecked) else: item.setCheckState(Qt.Checked) def __getItemValue(self, item): """ Setzt den Wert der Eigenschaft im Speicher. """ for trait in self.__items.items(): if id(trait[1]) == id(item): trait[0].value = item.checkState() break def hideOrShowToolPage(self, res): """ Alle Eigenschaften, die nicht zur Verfügung stehen, werden verborgen, indem sie in ein anderes Model verschoben werden. \bug Möglicher Fehler in PySide: Der Aufruf von QStandardItem.model() führt beim Beenden des Programms zu einem Segmentation Fault. """ # Versteckt alle Unterkräfte, die zu gewähltem Charakter nicht passen. for item in self.__items.items(): if ( ( item[0].species and item[0].species != self.__character.species ) or ( item[0].only and self.__character.breed not in item[0].only and self.__character.faction not in item[0].only ) ): #self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), True) #Debug.debug(item[1].model()) ## Hier wird beispielsweise besagter Aufruf getätigt, der zu einem segfault führt. if item[1].model() == self.__model: parent = item[1].parent() itemUnused = parent.takeRow(item[1].index().row()) parentUnused = self.__modelUnused.findItems(parent.text())[0] parentUnused.appendRow(itemUnused) else: #self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), False) if item[1].model() == self.__modelUnused: parent = item[1].parent() itemUsed = parent.takeRow(item[1].index().row()) parentUsed = self.__model.findItems(parent.text())[0] parentUsed.appendRow(itemUsed) ## Versteckt alle Elternzeilen, wenn sie keine Kinder enthalten. for i in range(self.__model.rowCount()): categoryItem = self.__model.item(i) if categoryItem.hasChildren(): self.__view.setRowHidden(categoryItem.index().row(), self.__rootItem.index(), False) else: self.__view.setRowHidden(categoryItem.index().row(), self.__rootItem.index(), True)
class MSClusteringController(MSDialogController): """ Class to Control the gui and the model for clustering """ POS_ADDUCTS=path.normcase('config/databases/POS_ADDUCTS.csv'), \ path.normcase('config/databases/POS_ADDUCTS_LOW_RES.csv') NEG_ADDUCTS=path.normcase('config/databases/NEG_ADDUCTS.csv'), \ path.normcase('config/databases/NEG_ADDUCTS_LOW_RES.csv') FRAGMENTS=path.normcase('config/databases/FRAGMENTS.csv'), \ path.normcase('config/databases/FRAGMENTS_LOW_RES.csv') def __init__(self, lspl, visu, creation): MSDialogController.__init__(self, lspl, visu, creation) self.polarity=1 #initialisation if not self.model: self.goodIdx = 0 else: self.goodIdx = 0 if self.model[0].kind == 'HighRes' else 1 self.populateTableViews(self.polarity) self.allAddsChecked = False self.allFragsChecked = False QObject.connect(self.view.posmode, SIGNAL('toggled(bool)'), self.updatePolarity) QObject.connect(self.view.checkAllAdds, SIGNAL('clicked()'), self.checkAdds) QObject.connect(self.view.checkAllFrags, SIGNAL('clicked()'), self.checkFrags) self.view.exec_() def getFragAddData(self, polarity=1): """parsing adducts and fragments files""" frags=self.readData(self.FRAGMENTS[self.goodIdx]) if not polarity: adds=self.readData(self.NEG_ADDUCTS[self.goodIdx]) elif polarity: adds=self.readData(self.POS_ADDUCTS[self.goodIdx]) return frags, adds def readData(self, file_): """read data from databases files""" def fragData(line, d): d[(s[0], s[1], str(1))]= False def addData(line, d): d[(s[0], s[-1].rstrip(), s[1])]= False routine=None if file_ in (self.POS_ADDUCTS+self.NEG_ADDUCTS): routine=addData elif file_ in self.FRAGMENTS: routine=fragData else: print ("Error reading adducts and fragments files") return res=OrderedDict() with open(file_) as f: for i in range (2): l=f.readline() while l!="": s=l.split(',') routine(l, res) l=f.readline() return res def checkAdds(self): for i in xrange(self.adductsModel.rowCount()): #data = self.adductsModel.item(i,0).text() item = self.adductsModel.item(i,0) if self.allAddsChecked: item.setCheckState(0) self.view.checkAllAdds.setText('Check All') else: item.setCheckState(2) self.view.checkAllAdds.setText('UnCheck All') self.allAddsChecked = not self.allAddsChecked def checkFrags(self): for i in xrange(self.fragsModel.rowCount()): #data = self.fragsModel.item(i,0).text() item = self.fragsModel.item(i,0) if self.allFragsChecked: item.setCheckState(0) self.view.checkAllFrags.setText('Check All') else: item.setCheckState(2) self.view.checkAllFrags.setText('UnCheck All') self.allFragsChecked = not self.allFragsChecked def populateTableViews(self, polarity): frags, adds = self.getFragAddData(polarity) self.adductsModel, self.fragsModel = QStandardItemModel(), QStandardItemModel() self.adductsModel.setHorizontalHeaderLabels(["Adducts(name, mass, nmol)"]) self.fragsModel.setHorizontalHeaderLabels(["Fragments(name, mass, nmol)"]) for i, adduct in enumerate(adds.keys()): item =QStandardItem(', '.join(map(str, adduct))) item.setCheckable(True) if adds[adduct]: item.setCheckState(2) else: item.setCheckState(0) self.adductsModel.setItem(i, 0, item) self.view.adductsTable.setModel(self.adductsModel) for i, frag in enumerate(frags.keys()): item = QStandardItem(', '.join(map(str, frag))) item.setCheckable(True) if frags[frag]: item.setCheckState(2) else: item.setCheckState(0) self.fragsModel.setItem(i, 0, item) self.view.fragTable.setModel(self.fragsModel) def getFragsAndAdductsToCheck(self): frags, adducts={}, {} for i in range(self.fragsModel.rowCount()): data = self.fragsModel.item(i,0).text() item = self.fragsModel.item(i,0) if item.checkState(): frags[tuple([str(x) for x in data.split(', ')])]= True else: frags[tuple([str(x) for x in data.split(', ')])]= False for i in range(self.adductsModel.rowCount()): data = self.adductsModel.item(i,0).text() item = self.adductsModel.item(i,0) if item.checkState(): adducts[tuple([str(x) for x in data.split(', ')])]= True else: adducts[tuple([str(x) for x in data.split(', ')])]= False checkMasses=OrderedDict() for frag in frags.keys(): if frags[frag]: checkMasses[(float(frag[1]), float(frag[2]))] = frag[0] for add in adducts.keys(): if adducts[add]: if self.polarity:#positive polarity checkMasses[(-float(add[1]), float(add[2]))] = add[0] elif not self.polarity:#negative polarity checkMasses[(float(add[1]), float(add[2]))] = add[0] return checkMasses def updatePolarity(self, boolean): self.polarity = 1 if boolean else 0#positive, negative self.populateTableViews(self.polarity) def getParameters(self): """classical getParameters (model) function""" self.parameters["rtError"] = self.view.lineEdit_2.value() self.parameters["clusterLength"] = self.view.lineEdit_3.value() self.parameters["idmsLength"] =tuple([float(x) for x in self.view.lineEdit_4.text().split('-')]) self.parameters["badPeaks"] = self.view.lineEdit_5.isChecked() #self.parameters["useCorr"] = self.view.check.isChecked() self.parameters["gap"]=self.view.spinBox.value() self.parameters["resolveConflicts"]=self.view.lineEdit_6.isChecked() self.parameters["frags"]=self.getFragsAndAdductsToCheck() def startTask(self): """ Main Function (model function) Clustering """ MSDialogController.startTask(self) #qApp.instance().view.showInStatusBar("Clustering Step...Please Wait..", 5000) self.task = MSClusterThread(self.sampleList, **self.parameters) QObject.connect(self.view, SIGNAL('destroyed(QObject *)'), self.task.begin) #self.connect(self.view, SIGNAL('destroyed(QObject *)'), self.setViewToNone) QObject.connect(self.task, SIGNAL("started()"),qApp.instance().view.to_determined_mode) QObject.connect(self.task, SIGNAL('update_pb'), qApp.instance().view.updateProgressBar) #QObject.connect(self.task, SIGNAL("finished()"),qApp.instance().view.to_determined_mode) QObject.connect(self.task, SIGNAL("finished()"), self.setModels) #print "about to close" self.view.close() #print "closed" #self.task.begin() def setModels(self):#, sampleList): """ closing function of the process """ qApp.instance().view.showInformationMessage("Clustering done", "Clustering Done succesfully !") qApp.instance().view.tabWidget.setCurrentIndex(2) def _initialize(self): """initialization of the parameters""" self.view.lineEdit_2.setValue(6.) self.view.lineEdit_3.setValue(6) self.view.lineEdit_4.setText("0-0") #self.view.lineEdit_5.setText("10.") self.view.decrOrder.setChecked(True) self.view.lineEdit_6.setChecked(True) self.view.spinBox.setValue(0)
class ModelAtrributesView(QListView): """ Custom QListView implementation that displays checkable model attributes. """ def __init__(self,parent=None,dataModel = None): QListView.__init__(self, parent) self._dataModel = dataModel self._selectedDisplayMapping = OrderedDict() self._modelDisplayMapping = OrderedDict() self._attrModel = QStandardItemModel(self) def dataModel(self): """ Returns the data model instance. """ return self._dataModel def setDataModel(self,dataModel): """ Sets the data model. Should be a callable class rather than the class. instance. """ if callable(dataModel): self._dataModel = dataModel else: self._dataModel = dataModel.__class__ def modelDisplayMapping(self): """ Returns the column name and display name collection. """ return self._modelDisplayMapping def setModelDisplayMapping(self, dataMapping): """ Sets the mapping dictionary for the table object """ if dataMapping != None: self._modelDisplayMapping=dataMapping def load(self, sort=False): """ Load the model's attributes into the list view. """ if self._dataModel == None: return try: self._loadAttrs(self._dataModel.displayMapping(), sort) except AttributeError: #Ignore error if model does not contain the displayMapping static method pass def load_mapping(self, mapping, sort=False): """ Load collection containing column name and corresponding display name. """ self._modelDisplayMapping = mapping self._loadAttrs(mapping, sort) def sort(self): """ Sorts display name in ascending order. """ self._attrModel.sort(0) def _loadAttrs(self, attrMapping, sort=False): """ Loads display mapping into the list view. Specify to sort display names in ascending order once items have been added to the model. """ self._attrModel.clear() self._attrModel.setColumnCount(2) for attrName,displayName in attrMapping.iteritems(): #Exclude row ID in the list, other unique identifier attributes in the model can be used if attrName != "id": displayNameItem = QStandardItem(displayName) displayNameItem.setCheckable(True) attrNameItem = QStandardItem(attrName) self._attrModel.appendRow([displayNameItem,attrNameItem]) self.setModel(self._attrModel) if sort: self._attrModel.sort(0) def selectedMappings(self): """ Return a dictionary of field names and their corresponding display values. """ selectedAttrs = {} for i in range(self._attrModel.rowCount()): displayNameItem = self._attrModel.item(i,0) if displayNameItem.checkState() == Qt.Checked: attrNameItem = self._attrModel.item(i,1) selectedAttrs[attrNameItem.text()] = displayNameItem.text() return selectedAttrs
class OWConfusionMatrix(widget.OWWidget): """Confusion matrix widget""" name = "Confusion Matrix" description = "Display a confusion matrix constructed from " \ "the results of classifier evaluations." icon = "icons/ConfusionMatrix.svg" priority = 1001 inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")] outputs = [("Selected Data", Orange.data.Table)] quantities = [ "Number of instances", "Proportion of predicted", "Proportion of actual" ] settingsHandler = settings.ClassValuesContextHandler() selected_learner = settings.Setting([0], schema_only=True) selection = settings.ContextSetting(set()) selected_quantity = settings.Setting(0) append_predictions = settings.Setting(True) append_probabilities = settings.Setting(False) autocommit = settings.Setting(True) UserAdviceMessages = [ widget.Message( "Clicking on cells or in headers outputs the corresponding " "data instances", "click_cell") ] def __init__(self): super().__init__() self.data = None self.results = None self.learners = [] self.headers = [] box = gui.vBox(self.controlArea, "Learners") self.learners_box = gui.listBox(box, self, "selected_learner", "learners", callback=self._learner_changed) box = gui.vBox(self.controlArea, "Show") gui.comboBox(box, self, "selected_quantity", items=self.quantities, callback=self._update) box = gui.vBox(self.controlArea, "Select") gui.button(box, self, "Select Correct", callback=self.select_correct, autoDefault=False) gui.button(box, self, "Select Misclassified", callback=self.select_wrong, autoDefault=False) gui.button(box, self, "Clear Selection", callback=self.select_none, autoDefault=False) self.outputbox = box = gui.vBox(self.controlArea, "Output") gui.checkBox(box, self, "append_predictions", "Predictions", callback=self._invalidate) gui.checkBox(box, self, "append_probabilities", "Probabilities", callback=self._invalidate) gui.auto_commit(self.controlArea, self, "autocommit", "Send Selected", "Send Automatically") grid = QGridLayout() self.tablemodel = QStandardItemModel(self) view = self.tableview = QTableView( editTriggers=QTableView.NoEditTriggers) view.setModel(self.tablemodel) view.horizontalHeader().hide() view.verticalHeader().hide() view.horizontalHeader().setMinimumSectionSize(60) view.selectionModel().selectionChanged.connect(self._invalidate) view.setShowGrid(False) view.setItemDelegate(BorderedItemDelegate(Qt.white)) view.clicked.connect(self.cell_clicked) grid.addWidget(view, 0, 0) self.mainArea.layout().addLayout(grid) def sizeHint(self): """Initial size""" return QSize(750, 490) def _item(self, i, j): return self.tablemodel.item(i, j) or QStandardItem() def _set_item(self, i, j, item): self.tablemodel.setItem(i, j, item) def _init_table(self, nclasses): item = self._item(0, 2) item.setData("Predicted", Qt.DisplayRole) item.setTextAlignment(Qt.AlignCenter) item.setFlags(Qt.NoItemFlags) self._set_item(0, 2, item) item = self._item(2, 0) item.setData("Actual", Qt.DisplayRole) item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom) item.setFlags(Qt.NoItemFlags) self.tableview.setItemDelegateForColumn(0, gui.VerticalItemDelegate()) self._set_item(2, 0, item) self.tableview.setSpan(0, 2, 1, nclasses) self.tableview.setSpan(2, 0, nclasses, 1) font = self.tablemodel.invisibleRootItem().font() bold_font = QFont(font) bold_font.setBold(True) for i in (0, 1): for j in (0, 1): item = self._item(i, j) item.setFlags(Qt.NoItemFlags) self._set_item(i, j, item) for p, label in enumerate(self.headers): for i, j in ((1, p + 2), (p + 2, 1)): item = self._item(i, j) item.setData(label, Qt.DisplayRole) item.setFont(bold_font) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) if p < len(self.headers) - 1: item.setData("br"[j == 1], BorderRole) item.setData(QColor(192, 192, 192), BorderColorRole) self._set_item(i, j, item) hor_header = self.tableview.horizontalHeader() if len(' '.join(self.headers)) < 120: hor_header.setResizeMode(QHeaderView.ResizeToContents) else: hor_header.setDefaultSectionSize(60) self.tablemodel.setRowCount(nclasses + 3) self.tablemodel.setColumnCount(nclasses + 3) def set_results(self, results): """Set the input results.""" prev_sel_learner = self.selected_learner.copy() self.clear() self.warning() self.closeContext() data = None if results is not None and results.data is not None: data = results.data if data is not None and not data.domain.has_discrete_class: self.warning("Confusion Matrix cannot show regression results.") self.results = results self.data = data if data is not None: class_values = data.domain.class_var.values elif results is not None: raise NotImplementedError if results is None: self.report_button.setDisabled(True) else: self.report_button.setDisabled(False) nmodels = results.predicted.shape[0] self.headers = class_values + \ [unicodedata.lookup("N-ARY SUMMATION")] # NOTE: The 'learner_names' is set in 'Test Learners' widget. if hasattr(results, "learner_names"): self.learners = results.learner_names else: self.learners = [ "Learner #{}".format(i + 1) for i in range(nmodels) ] self._init_table(len(class_values)) self.openContext(data.domain.class_var) if not prev_sel_learner or prev_sel_learner[0] >= len( self.learners): self.selected_learner[:] = [0] else: self.selected_learner[:] = prev_sel_learner self._update() self._set_selection() self.unconditional_commit() def clear(self): """Reset the widget, clear controls""" self.results = None self.data = None self.tablemodel.clear() self.headers = [] # Clear learners last. This action will invoke `_learner_changed` self.learners = [] def select_correct(self): """Select the diagonal elements of the matrix""" selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): index = self.tablemodel.index(i, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def select_wrong(self): """Select the off-diagonal elements of the matrix""" selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): for j in range(i + 1, n): index = self.tablemodel.index(i, j) selection.select(index, index) index = self.tablemodel.index(j, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def select_none(self): """Reset selection""" self.tableview.selectionModel().clear() def cell_clicked(self, model_index): """Handle cell click event""" i, j = model_index.row(), model_index.column() if not i or not j: return n = self.tablemodel.rowCount() index = self.tablemodel.index selection = None if i == j == 1 or i == j == n - 1: selection = QItemSelection(index(2, 2), index(n - 1, n - 1)) elif i in (1, n - 1): selection = QItemSelection(index(2, j), index(n - 1, j)) elif j in (1, n - 1): selection = QItemSelection(index(i, 2), index(i, n - 1)) if selection is not None: self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def commit(self): """Output data instances corresponding to selected cells""" if self.results is not None and self.data is not None \ and self.selected_learner: indices = self.tableview.selectedIndexes() indices = {(ind.row() - 2, ind.column() - 2) for ind in indices} actual = self.results.actual learner_name = self.learners[self.selected_learner[0]] predicted = self.results.predicted[self.selected_learner[0]] selected = [ i for i, t in enumerate(zip(actual, predicted)) if t in indices ] row_indices = self.results.row_indices[selected] extra = [] class_var = self.data.domain.class_var metas = self.data.domain.metas if self.append_predictions: predicted = numpy.array(predicted[selected], dtype=object) extra.append(predicted.reshape(-1, 1)) var = Orange.data.DiscreteVariable( "{}({})".format(class_var.name, learner_name), class_var.values) metas = metas + (var, ) if self.append_probabilities and \ self.results.probabilities is not None: probs = self.results.probabilities[self.selected_learner[0], selected] extra.append(numpy.array(probs, dtype=object)) pvars = [ Orange.data.ContinuousVariable("p({})".format(value)) for value in class_var.values ] metas = metas + tuple(pvars) X = self.data.X[row_indices] Y = self.data.Y[row_indices] M = self.data.metas[row_indices] row_ids = self.data.ids[row_indices] M = numpy.hstack((M, ) + tuple(extra)) domain = Orange.data.Domain(self.data.domain.attributes, self.data.domain.class_vars, metas) data = Orange.data.Table.from_numpy(domain, X, Y, M) data.ids = row_ids data.name = learner_name else: data = None self.send("Selected Data", data) def _invalidate(self): indices = self.tableview.selectedIndexes() self.selection = {(ind.row() - 2, ind.column() - 2) for ind in indices} self.commit() def _set_selection(self): selection = QItemSelection() index = self.tableview.model().index for row, col in self.selection: sel = index(row + 2, col + 2) selection.select(sel, sel) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def _learner_changed(self): self._update() self._set_selection() self.commit() def _update(self): def _isinvalid(x): return isnan(x) or isinf(x) # Update the displayed confusion matrix if self.results is not None and self.selected_learner: cmatrix = confusion_matrix(self.results, self.selected_learner[0]) colsum = cmatrix.sum(axis=0) rowsum = cmatrix.sum(axis=1) n = len(cmatrix) diag = numpy.diag_indices(n) colors = cmatrix.astype(numpy.double) colors[diag] = 0 if self.selected_quantity == 0: normalized = cmatrix.astype(numpy.int) formatstr = "{}" div = numpy.array([colors.max()]) else: if self.selected_quantity == 1: normalized = 100 * cmatrix / colsum div = colors.max(axis=0) else: normalized = 100 * cmatrix / rowsum[:, numpy.newaxis] div = colors.max(axis=1)[:, numpy.newaxis] formatstr = "{:2.1f} %" div[div == 0] = 1 colors /= div colors[diag] = normalized[diag] / normalized[diag].max() for i in range(n): for j in range(n): val = normalized[i, j] col_val = colors[i, j] item = self._item(i + 2, j + 2) item.setData( "NA" if _isinvalid(val) else formatstr.format(val), Qt.DisplayRole) bkcolor = QColor.fromHsl( [0, 240][i == j], 160, 255 if _isinvalid(col_val) else int(255 - 30 * col_val)) item.setData(QBrush(bkcolor), Qt.BackgroundRole) item.setData("trbl", BorderRole) item.setToolTip("actual: {}\npredicted: {}".format( self.headers[i], self.headers[j])) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self._set_item(i + 2, j + 2, item) bold_font = self.tablemodel.invisibleRootItem().font() bold_font.setBold(True) def _sum_item(value, border=""): item = QStandardItem() item.setData(value, Qt.DisplayRole) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) item.setFont(bold_font) item.setData(border, BorderRole) item.setData(QColor(192, 192, 192), BorderColorRole) return item for i in range(n): self._set_item(n + 2, i + 2, _sum_item(int(colsum[i]), "t")) self._set_item(i + 2, n + 2, _sum_item(int(rowsum[i]), "l")) self._set_item(n + 2, n + 2, _sum_item(int(rowsum.sum()))) def send_report(self): """Send report""" if self.results is not None and self.selected_learner: self.report_table( "Confusion matrix for {} (showing {})".format( self.learners[self.selected_learner[0]], self.quantities[self.selected_quantity].lower()), self.tableview)
class ObstacleTable(QSortFilterProxyModel): MocMultiplier = 1 SelectionMode = SelectionModeType.Automatic def __init__(self, surfacesList, fileWriter=None): QSortFilterProxyModel.__init__(self) ObstacleTable.SelectionMode = SelectionModeType.Automatic self.manualPolygon = None self.surfacesList = surfacesList self.surfaceType = None self.source = QStandardItemModel() self.setSourceModel(self.source) # tableView.hideColumn(self.IndexObjectId) # tableView.hideColumn(self.IndexLayerId) # tableView.hideColumn(self.IndexX) # tableView.hideColumn(self.IndexY) # tableView.hideColumn(self.IndexLat) # tableView.hideColumn(self.IndexLon) # tableView.hideColumn(self.IndexSurface) self.hideColumnLabels = [ ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId, ObstacleTableColumnType.X, ObstacleTableColumnType.Y, ObstacleTableColumnType.Lat, ObstacleTableColumnType.Lon, ObstacleTableColumnType.Surface ] self.fixedColumnLabels = [ ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId, ObstacleTableColumnType.Name, ObstacleTableColumnType.X, ObstacleTableColumnType.Y, ObstacleTableColumnType.Lat, ObstacleTableColumnType.Lon, ObstacleTableColumnType.AltM, ObstacleTableColumnType.AltFt, ObstacleTableColumnType.TreesM, ObstacleTableColumnType.TreesFt ] self.IndexObjectId = 0 self.IndexLayerId = 1 self.IndexName = 2 self.IndexX = 3 self.IndexY = 4 self.IndexLat = 5 self.IndexLon = 6 self.IndexAltM = 7 self.IndexAltFt = 8 self.IndexTreesM = 9 self.IndexTreesFt = 10 self.IndexOcaM = -1 self.IndexOcaFt = -1 self.IndexOchM = -1 self.IndexOchFt = -1 self.IndexObstArea = -1 self.IndexDistInSecM = -1 self.IndexMocAppliedM = -1 self.IndexMocAppliedFt = -1 self.IndexMocMultiplier = -1 self.IndexMocReqM = -1 self.IndexMocReqFt = -1 self.IndexDoM = -1 self.IndexDrM = -1 self.IndexDzM = -1 self.IndexDxM = -1 self.IndexDsocM = -1 self.IndexHeightLossM = -1 self.IndexHeightLossFt = -1 self.IndexAcAltM = -1 self.IndexAcAltFt = -1 self.IndexAltReqM = -1 self.IndexAltReqFt = -1 self.IndexCritical = -1 self.IndexMACG = -1 self.IndexPDG = -1 self.IndexSurfAltM = -1 self.IndexSurfAltFt = -1 self.IndexDifferenceM = -1 self.IndexDifferenceFt = -1 self.IndexIlsX = -1 self.IndexIlsY = -1 self.IndexEqAltM = -1 self.IndexEqAltFt = -1 self.IndexSurfaceName = -1 self.IndexDisregardable = -1 self.IndexCloseIn = -1 self.IndexTag = -1 self.IndexSurface = -1 self.IndexArea = -1 self.IndexHLAppliedM = -1 self.setHeaderLabels() self.setFilterKeyColumn(self.IndexSurface) self.setSortRole(Qt.UserRole + 1) self.layoutChanged.connect(self.setVerticalHeader) self.btnLocate = None self.tblObstacles = None def FilterDisregardableObstacles(self, state): if state: self.setFilterKeyColumn(self.IndexDisregardable) self.setFilterFixedString("Yes") self.setFilterKeyColumn(self.IndexSurface) def setSurfaceType(self, surfaceType): self.surfaceType = surfaceType def setFilterFixedString(self, filterString): QSortFilterProxyModel.setFilterFixedString(self, filterString) self.setVerticalHeader() if self.btnLocate != None and self.tblObstacles != None: selectedIndexes = self.tblObstacles.selectedIndexes() if len(selectedIndexes) == 0: self.btnLocate.setEnabled(False) else: self.btnLocate.setEnabled(True) def setLocateBtn(self, btnLocate): self.btnLocate = btnLocate self.btnLocate.setEnabled(False) self.btnLocate.clicked.connect(self.btnLocateClicked) def btnLocateClicked(self): if self.tblObstacles == None: return selectedIndexes = self.tblObstacles.selectedIndexes() self.locate(selectedIndexes) def tblObstaclesClicked(self, idx): if len(self.tblObstacles.selectedIndexes()) > 0: self.btnLocate.setEnabled(True) def setTableView(self, tblObstacles): self.tblObstacles = tblObstacles self.tblObstacles.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblObstacles.setSortingEnabled(True) self.tblObstacles.clicked.connect(self.tblObstaclesClicked) self.tblObstacles.verticalHeader().sectionClicked.connect( self.tblObstaclesClicked) pass def setHeaderLabels(self): # print self.setHeaderData(1, Qt.Vertical, 1, Qt.DisplayRole) pass def setVerticalHeader(self): for i in range(self.rowCount()): self.setHeaderData(i, Qt.Vertical, i + 1, Qt.DisplayRole) def setHiddenColumns(self, tableView): tableView.hideColumn(self.IndexObjectId) tableView.hideColumn(self.IndexLayerId) tableView.hideColumn(self.IndexX) tableView.hideColumn(self.IndexY) tableView.hideColumn(self.IndexLat) tableView.hideColumn(self.IndexLon) tableView.hideColumn(self.IndexSurface) def getExtentForLocate(self, sourceRow): extent = None surfaceType = None if self.IndexSurface < 0: surfaceType = self.surfaceType else: surfaceType = self.source.item(sourceRow, self.IndexSurface).text() surfaceLayers = QgisHelper.getSurfaceLayers(self.surfaceType) for sfLayer in surfaceLayers: lId = sfLayer.name() if lId.contains(surfaceType): extent = sfLayer.extent() break return extent def clear(self): self.source.clear() self.source.setHorizontalHeaderLabels(self.fixedColumnLabels) # self.setHeaderLabels() def locate(self, selectedRowIndexes): if selectedRowIndexes == None or len(selectedRowIndexes) <= 0: return sourceRow = self.mapToSource(selectedRowIndexes[0]).row() objectId = int(self.source.item(sourceRow, self.IndexObjectId).text()) layerId = self.source.item(sourceRow, self.IndexLayerId).text() QgisHelper.selectFeature(layerId, objectId) layer = QgsMapLayerRegistry.instance().mapLayer(layerId) crs = define._canvas.mapSettings().destinationCrs() if crs.mapUnits() == QGis.Meters: x = float(self.source.item(sourceRow, self.IndexX).text()) y = float(self.source.item(sourceRow, self.IndexY).text()) extent = QgsRectangle(x - 350, y - 350, x + 350, y + 350) else: x, result1 = self.source.item(sourceRow, self.IndexLon).data().toDouble() y, result2 = self.source.item(sourceRow, self.IndexLat).data().toDouble() extent = QgsRectangle(x - 0.005, y - 0.005, x + 0.005, y + 0.005) point = QgsPoint(x, y) # extent = self.getExtentForLocate(sourceRow) if extent is None: return QgisHelper.zoomExtent(point, extent, 2) pass def loadObstacles(self, surfaceLayers): if self.source.rowCount() > 0: self.source.clear() self.source.setHorizontalHeaderLabels(self.fixedColumnLabels) demEvaluateAg = None existingDemFlag = False obstacleLayersDEM = QgisHelper.getSurfaceLayers(SurfaceTypes.DEM) obstacleLayers = QgisHelper.getSurfaceLayers(SurfaceTypes.Obstacles) if obstacleLayersDEM != None and len(obstacleLayersDEM) > 0: if QMessageBox.question( None, "Question", "Do you want to use DEM for evaluating Obstacle?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes: self.loadObstaclesDEM(obstacleLayersDEM, surfaceLayers) if obstacleLayers != None and len(obstacleLayers) > 0: # if QMessageBox.question(None, "Question", "Do you want to use DEM for evaluating Obstacle?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: self.loadObstaclesVector(obstacleLayers, surfaceLayers) return True def loadObstaclesDEM(self, obstacleLayersDEM, surfaceLayers): progressMessageBar = define._messagBar.createMessage( "Loading DEM Obstacles...") self.progress = QProgressBar() self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(self.progress) define._messagBar.pushWidget(progressMessageBar, define._messagBar.INFO) maxium = 0 offset = 0.0 self.progress.setValue(0) wCount = 0 hCount = 0 for ly in obstacleLayersDEM: demDataProvider = ly.dataProvider() boundDem = demDataProvider.extent() xMin = boundDem.xMinimum() xMax = boundDem.xMaximum() yMin = boundDem.yMinimum() yMax = boundDem.yMaximum() bound = QgisHelper.getIntersectExtent( ly, QgsGeometry.fromRect(boundDem), surfaceLayers) # boundGeom = QgsGeometry.fromRect(bound) if bound == None: continue block = ly.dataProvider().block(0, ly.extent(), ly.width(), ly.height()) xMinimum = ly.dataProvider().extent().xMinimum() yMaximum = ly.dataProvider().extent().yMaximum() yMinimum = ly.dataProvider().extent().yMinimum() xMaximum = ly.dataProvider().extent().xMaximum() xOffSet = ly.extent().width() / ly.width() yOffSet = ly.extent().height() / ly.height() offset = xOffSet if bound.xMinimum() < xMinimum: wStartNumber = 0 xStartValue = xMinimum else: wStartNumber = int((bound.xMinimum() - xMinimum) / xOffSet) xStartValue = bound.xMinimum() if yMaximum < bound.yMaximum(): hStartNumber = 0 yStartValue = yMaximum else: hStartNumber = int((yMaximum - bound.yMaximum()) / yOffSet) yStartValue = bound.yMaximum() if bound.xMaximum() > xMaximum: xEndValue = xMaximum else: xEndValue = bound.xMaximum() if yMinimum > bound.yMinimum(): yEndValue = yMinimum else: yEndValue = bound.yMinimum() wCount = int(math.fabs(xEndValue - xStartValue) / xOffSet) hCount = int(math.fabs(yEndValue - yStartValue) / yOffSet) pixelCount = hCount maxium += pixelCount cellSizeWnd = cellsizeWnd(offset, wCount * hCount, maxium * 0.04) cellSizeWnd.setWindowTitle("Input Cell Size") result = cellSizeWnd.exec_() cellRate = 1 if result == 1: offset = cellSizeWnd.cellsize maxium = cellSizeWnd.cellCount + 2 cellRate = cellSizeWnd.cellRate # print cellSizeWnd.textedit1.text() if maxium == 0: return False self.progress.setMaximum(maxium) trees = define._treesDEM tolerance = define._toleranceDEM for obstacleLayer in obstacleLayersDEM: obstacleUnits = obstacleLayer.crs().mapUnits() demDataProvider = obstacleLayer.dataProvider() boundDem = demDataProvider.extent() bound = QgisHelper.getIntersectExtent( obstacleLayer, QgsGeometry.fromRect(boundDem), surfaceLayers) if bound == None: continue boundGeom = QgsGeometry.fromRect(bound) if not boundGeom.intersects(QgsGeometry.fromRect(boundDem)): continue block = obstacleLayer.dataProvider().block(1, obstacleLayer.extent(), obstacleLayer.width(), obstacleLayer.height()) xMinimum = obstacleLayer.extent().xMinimum() yMaximum = obstacleLayer.extent().yMaximum() yMinimum = obstacleLayer.extent().yMinimum() xMaximum = obstacleLayer.extent().xMaximum() xOffSet = obstacleLayer.extent().width() / obstacleLayer.width() yOffSet = obstacleLayer.extent().height() / obstacleLayer.height() if bound.xMinimum() < xMinimum: hStartNumber = 0 xStartValue = xMinimum else: hStartNumber = int((bound.xMinimum() - xMinimum) / xOffSet) xStartValue = bound.xMinimum() if yMaximum < bound.yMaximum(): wStartNumber = 0 yStartValue = yMaximum else: wStartNumber = int((yMaximum - bound.yMaximum()) / yOffSet) yStartValue = bound.yMaximum() if bound.xMaximum() > xMaximum: xEndValue = xMaximum else: xEndValue = bound.xMaximum() if yMinimum > bound.yMinimum(): yEndValue = yMinimum else: yEndValue = bound.yMinimum() wCount = int(math.fabs(xEndValue - xStartValue) / offset) hCount = int(math.fabs(yEndValue - yStartValue) / offset) xPixelWidth = 0.0 yPixelWidth = 0.0 featureID = 0 # i = 0 # k = 0 # altitudeList = [] # self.progress.setValue(0) # while i <= hCount - 1: # j = 0 # while j <= wCount - 1: # if block.isNoData(j * int(cellRate) + wStartNumber, i* int(cellRate) + hStartNumber): # self.progress.setValue(k) # QApplication.processEvents() # j += 1 # k += 1 # altitudeList.append(None) # continue # altitude = block.value(j * int(cellRate) + wStartNumber, i * int(cellRate) + hStartNumber) # altitudeList.append(altitude) # self.progress.setValue(k) # QApplication.processEvents() # j += 1 # k += 1 # i += 1 i = 0 k = 0 name = "DEM" semiXoffset = xOffSet / 2 semiYoffset = yOffSet / 2 while i <= hCount - 1: j = 0 while j <= wCount - 1: if block.isNoData(j * cellRate + wStartNumber, i * cellRate + hStartNumber): self.progress.setValue(k) QApplication.processEvents() j += 1 k += 1 continue altitude = block.value(j * cellRate + wStartNumber, i * cellRate + hStartNumber) # # if block.isNoData(j * int(cellRate) + wStartNumber, i* int(cellRate) + hStartNumber): # # j += 1 # # self.progress.setValue(self.progress.value() + 1) # # QApplication.processEvents() # # continue # # altitude = block.value(j* int(cellRate) + wStartNumber, i* int(cellRate)+ hStartNumber) # altitude = altitudeList[k] # if altitude == None: # self.progress.setValue(k) # QApplication.processEvents() # j += 1 # k += 1 # continue point = QgsPoint( xStartValue + (i * cellRate) * xOffSet + semiXoffset, yStartValue - (j * cellRate - 1) * yOffSet - semiYoffset) position = Point3D() positionDegree = Point3D() if define._canvas.mapUnits() == QGis.Meters: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): position = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: position = Point3D(point.x(), point.y(), altitude) else: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): positionDegree = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: positionDegree = Point3D(point.x(), point.y(), altitude) obstacle = Obstacle(name, position, obstacleLayer.id(), featureID, None, trees, ObstacleTable.MocMultiplier, tolerance) obstacle.positionDegree = positionDegree if self.manualPolygon != None: if not self.manualPolygon.contains(obstacle.Position): continue self.checkObstacle(obstacle) self.progress.setValue(k) QApplication.processEvents() j += 1 featureID += 1 k += 1 i += 1 self.progress.setValue(maxium) define._messagBar.hide() self.manualPolygon = None def loadObstaclesVector(self, obstacleLayers, surfaceLayers): progressMessageBar = define._messagBar.createMessage( "Loading Vector Obstacles...") self.progress = QProgressBar() self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(self.progress) define._messagBar.pushWidget(progressMessageBar, define._messagBar.INFO) maxium = 0 self.progress.setValue(0) for ly in obstacleLayers: maxium += ly.featureCount() if maxium == 0: return False self.progress.setMaximum(maxium) for obstacleLayer in obstacleLayers: obstacleUnits = obstacleLayer.crs().mapUnits() features = QgisHelper.getFeaturesInLayerExtent( define._canvas, obstacleLayer, surfaceLayers, SelectionModeType.Automatic) # print len(features) for feature in features: name = feature.attribute("Name").toString() altitude = feature.attribute("Altitude").toFloat()[0] trees = define._trees tolerance = define._tolerance point = feature.geometry().asPoint() position = Point3D() positionDegree = Point3D() if define._canvas.mapUnits() == QGis.Meters: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): position = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: position = Point3D(point.x(), point.y(), altitude) else: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): positionDegree = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: positionDegree = Point3D(point.x(), point.y(), altitude) featureId = feature.id() layerId = obstacleLayer.id() obstacle = Obstacle(name, position, layerId, featureId, None, trees, ObstacleTable.MocMultiplier, tolerance) obstacle.positionDegree = positionDegree # obstacle.positionDegree = positionDegree self.checkObstacle(obstacle) self.progress.setValue(self.progress.value() + 1) QApplication.processEvents() QApplication.processEvents() self.progress.setValue(maxium) define._messagBar.hide() self.manualPolygon = None def addObstacleToModel(self, obstacle, checkResult=None): standardItemList = [] # obstacle.positionDegree = QgisHelper.Meter2Degree(obstacle.Position.x(), obstacle.Position.y()) standardItem = QStandardItem(str(obstacle.featureId)) standardItem.setData(obstacle.featureId) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.layerId)) standardItem.setData(obstacle.layerId) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.name)) standardItem.setData(obstacle.name) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.Position.x())) standardItem.setData(obstacle.Position.x()) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.Position.y())) standardItem.setData(obstacle.Position.y()) standardItemList.append(standardItem) value = QVariant(QgisHelper.strDegree(obstacle.positionDegree.y())) standardItem = QStandardItem(value.toString()) standardItem.setData(obstacle.positionDegree.y()) standardItemList.append(standardItem) strV = QgisHelper.strDegree(obstacle.positionDegree.y()) value = QVariant(QgisHelper.strDegree(obstacle.positionDegree.x())) standardItem = QStandardItem(value.toString()) standardItem.setData(obstacle.positionDegree.x()) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.Position.z())) standardItem.setData(obstacle.Position.z()) standardItemList.append(standardItem) standardItem = QStandardItem( str(Unit.ConvertMeterToFeet(obstacle.Position.z()))) standardItem.setData(Unit.ConvertMeterToFeet(obstacle.Position.z())) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.trees)) standardItem.setData(obstacle.trees) standardItemList.append(standardItem) standardItem = QStandardItem( str(Unit.ConvertMeterToFeet(obstacle.trees))) standardItem.setData(Unit.ConvertMeterToFeet(obstacle.trees)) standardItemList.append(standardItem) # for i in range(len(standardItemList), self.source.columnCount()): # standardItemList.append(QStandardItem("None")) self.source.appendRow(standardItemList) standardItem = QStandardItem(str(obstacle.mocMultiplier)) standardItem.setData(obstacle.mocMultiplier) self.source.setItem(self.source.rowCount() - 1, self.IndexMocMultiplier, standardItem) def checkObstacle(self, obstacle): pass def CompareObstacleRows(self, newRow, row, ignore): pass def method_0(self, obstacle_0): colCount = self.columnCount() objectId = range(colCount) objectId[0] = (obstacle_0.featureId) objectId[1] = (obstacle_0.name) objectId[2] = (obstacle_0.position.x()) objectId[3] = (obstacle_0.position.y()) objectId[4] = (obstacle_0.Position.z()) position = obstacle_0.position objectId[6] = (Unit.ConvertMeterToFeet(position.z())) objectId[7] = (obstacle_0.trees) objectId[8] = (Unit.ConvertMeterToFeet(obstacle_0.Trees)) if (self.IndexMocMultiplier > -1): objectId[self.IndexMocMultiplier] = obstacle_0.MocMultiplier return objectId def method_1(self, object_0): pass
class SetupDialog(QDialog, Ui_SetupDialog): """ Function and Event handling class for the Ui_SetupDialog. """ def __init__(self, parent): QDialog.__init__(self, parent) self._gui_logger = GUILogger("GUILogger", logging.INFO) self._gui_job = None EventLogger.add_logger(self._gui_logger) # FIXME better way to find interval and uids in tree_widget?! self.__tree_interval_tooltip = "Update interval in seconds" self.__tree_uid_tooltip = "UID cannot be empty" self.data_logger_thread = None self.tab_debug_warning = False self.device_dialog = None self.host_infos = None self.last_host = None self.host_index_changing = None self.setupUi(self) self.model_data = QStandardItemModel(self) self.model_data.setHorizontalHeaderLabels( ['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit']) self.table_data.setModel(self.model_data) self.table_data.setColumnWidth(0, 160) self.table_data.setColumnWidth(1, 170) self.table_data.setColumnWidth(2, 50) self.table_data.setColumnWidth(3, 110) self.table_data.setColumnWidth(4, 70) self.table_data.setColumnWidth(5, 100) self.model_devices = QStandardItemModel(self) self.model_devices.setHorizontalHeaderLabels(['Device', 'Value']) self.tree_devices.setModel(self.model_devices) self.tree_devices.setColumnWidth(0, 300) self.widget_initialization() self.btn_start_logging.setIcon( QIcon(load_pixmap('data_logger/start-icon.png'))) timestamp = int(time.time()) self.edit_csv_file_name.setText( os.path.join(get_home_path(), 'logger_data_{0}.csv'.format(timestamp))) self.edit_log_file_name.setText( os.path.join(get_home_path(), 'logger_debug_{0}.log'.format(timestamp))) self.combo_data_time_format.addItem( utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de') self.combo_data_time_format.addItem( utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us') self.combo_data_time_format.addItem( utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso') self.combo_data_time_format.addItem( utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix') self.combo_debug_time_format.addItem( utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de') self.combo_debug_time_format.addItem( utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us') self.combo_debug_time_format.addItem( utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso') self.combo_debug_time_format.addItem( utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix') self.combo_log_level.addItem('Debug', 'debug') self.combo_log_level.addItem('Info', 'info') self.combo_log_level.addItem('Warning', 'warning') self.combo_log_level.addItem('Error', 'error') self.combo_log_level.addItem('Critical', 'critical') self.combo_log_level.setCurrentIndex(0) # debug self.combo_debug_level.addItem('Debug', logging.DEBUG) self.combo_debug_level.addItem('Info', logging.INFO) self.combo_debug_level.addItem('Warning', logging.WARNING) self.combo_debug_level.addItem('Error', logging.ERROR) self.combo_debug_level.addItem('Critical', logging.CRITICAL) self.combo_debug_level.setCurrentIndex(1) # info self.update_ui_state() def update_ui_state(self): data_to_csv_file = self.check_data_to_csv_file.isChecked() debug_to_log_file = self.check_debug_to_log_file.isChecked() self.label_csv_file_name.setVisible(data_to_csv_file) self.edit_csv_file_name.setVisible(data_to_csv_file) self.btn_browse_csv_file_name.setVisible(data_to_csv_file) self.label_log_file_name.setVisible(debug_to_log_file) self.edit_log_file_name.setVisible(debug_to_log_file) self.btn_browse_log_file_name.setVisible(debug_to_log_file) self.label_log_level.setVisible(debug_to_log_file) self.combo_log_level.setVisible(debug_to_log_file) def widget_initialization(self): """ Sets default values for some widgets """ # Login data self.host_info_initialization() self.signal_initialization() def signal_initialization(self): """ Init of all important Signals and connections. """ # Buttons self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked) self.btn_save_config.clicked.connect(self.btn_save_config_clicked) self.btn_load_config.clicked.connect(self.btn_load_config_clicked) self.check_data_to_csv_file.stateChanged.connect(self.update_ui_state) self.check_debug_to_log_file.stateChanged.connect(self.update_ui_state) self.btn_browse_csv_file_name.clicked.connect( self.btn_browse_csv_file_name_clicked) self.btn_browse_log_file_name.clicked.connect( self.btn_browse_log_file_name_clicked) self.btn_clear_debug.clicked.connect(self.btn_clear_debug_clicked) self.combo_debug_level.currentIndexChanged.connect( self.combo_debug_level_changed) self.btn_add_device.clicked.connect(self.btn_add_device_clicked) self.btn_remove_device.clicked.connect(self.btn_remove_device_clicked) self.btn_remove_all_devices.clicked.connect( self.btn_remove_all_devices_clicked) self.tab_widget.currentChanged.connect(self.tab_reset_warning) self.btn_clear_data.clicked.connect(self.btn_clear_data_clicked) self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE), self.add_debug_message) self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE_TAB_HIGHLIGHT), self.highlight_debug_tab) self.combo_host.currentIndexChanged.connect(self._host_index_changed) self.spin_port.valueChanged.connect(self._port_changed) def host_info_initialization(self): """ initialize host by getting information out of brickv.config """ self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT) self.host_index_changing = True for host_info in self.host_infos: self.combo_host.addItem(host_info.host) self.last_host = None self.combo_host.setCurrentIndex(0) self.spin_port.setValue(self.host_infos[0].port) self.host_index_changing = False def btn_start_logging_clicked(self): """ Start/Stop of the logging process """ if (self.data_logger_thread is not None) and (not self.data_logger_thread.stopped): self.btn_start_logging.clicked.disconnect() self.data_logger_thread.stop() self._reset_stop() elif self.data_logger_thread is None: from brickv.data_logger import main self._gui_job = GuiDataJob(name="GuiData-Writer") self.connect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row) self.data_logger_thread = main.main( None, GuiConfigHandler.create_config(self), self._gui_job) if self.data_logger_thread is not None: self.btn_start_logging.setText("Stop Logging") self.btn_start_logging.setIcon( QIcon(load_pixmap('data_logger/stop-icon.png'))) self.tab_devices.setEnabled(False) self.tab_setup.setEnabled(False) self.tab_widget.setCurrentIndex( self.tab_widget.indexOf(self.tab_data)) self.tab_reset_warning() def _reset_stop(self): self.tab_devices.setEnabled(True) self.tab_setup.setEnabled(True) self.btn_start_logging.setText("Start Logging") self.btn_start_logging.setIcon( QIcon(load_pixmap('data_logger/start-icon.png'))) self.disconnect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row) self.data_logger_thread = None self._gui_job = None self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked) def btn_save_config_clicked(self): filename = get_save_file_name(get_main_window(), 'Save Config', get_home_path(), 'JSON Files (*.json)') if len(filename) == 0: return if not filename.lower().endswith('.json'): filename += '.json' config = GuiConfigHandler.create_config(self) if not save_config(config, filename): QMessageBox.warning( get_main_window(), 'Save Config', 'Could not save config to file! See Debug tab for details.', QMessageBox.Ok) def btn_load_config_clicked(self): filename = get_open_file_name(get_main_window(), 'Load Config', get_home_path(), 'JSON Files (*.json)') if len(filename) == 0: return config = load_and_validate_config(filename) if config == None: QMessageBox.warning( get_main_window(), 'Load Config', 'Could not load config from file! See Debug tab for details.', QMessageBox.Ok) return self.update_setup_tab(config) self.update_devices_tab(config) def btn_browse_csv_file_name_clicked(self): if len(self.edit_csv_file_name.text()) > 0: last_dir = os.path.dirname( os.path.realpath(self.edit_csv_file_name.text())) else: last_dir = get_home_path() filename = get_save_file_name(get_main_window(), 'Choose CSV File', last_dir, "CSV Files (*.csv)") if len(filename) > 0: if not filename.lower().endswith('.csv'): filename += '.csv' self.edit_csv_file_name.setText(filename) def btn_browse_log_file_name_clicked(self): if len(self.edit_log_file_name.text()) > 0: last_dir = os.path.dirname( os.path.realpath(self.edit_log_file_name.text())) else: last_dir = get_home_path() filename = get_save_file_name(get_main_window(), 'Choose Log File', last_dir, "Log Files (*.log)") if len(filename) > 0: if not filename.lower().endswith('.log'): filename += '.log' self.edit_log_file_name.setText(filename) def btn_add_device_clicked(self): """ Opens the DeviceDialog in Add-Mode. """ if self.device_dialog is None: self.device_dialog = DeviceDialog(self) self.device_dialog.btn_refresh_clicked() self.device_dialog.show() def btn_remove_device_clicked(self): selection = self.tree_devices.selectionModel().selectedIndexes() while len(selection) > 0: index = selection[0] while index.parent() != self.model_devices.invisibleRootItem( ).index(): index = index.parent() self.model_devices.removeRows(index.row(), 1) # get new selection, because row removal might invalid indices selection = self.tree_devices.selectionModel().selectedIndexes() def btn_remove_all_devices_clicked(self): self.model_devices.removeRows(0, self.model_devices.rowCount()) def btn_clear_data_clicked(self): self.model_data.removeRows(0, self.model_data.rowCount()) def tab_reset_warning(self): """ Resets the Warning @ the debug tab. """ if not self.tab_debug_warning or self.tab_widget.currentWidget( ).objectName() != self.tab_debug.objectName(): return self.tab_debug_warning = False self.tab_set(self.tab_widget.indexOf(self.tab_debug), self.palette().color(QPalette.WindowText), None) def combo_debug_level_changed(self): """ Changes the log level dynamically. """ self._gui_logger.level = self.combo_debug_level.itemData( self.combo_debug_level.currentIndex()) def tab_set(self, tab_index, color, icon=None): """ Sets the font Color and an icon, if given, at a specific tab. """ from PyQt4.QtGui import QIcon self.tab_widget.tabBar().setTabTextColor(tab_index, color) if icon is not None: self.tab_widget.setTabIcon(tab_index, QIcon(icon)) else: self.tab_widget.setTabIcon(tab_index, QIcon()) def _host_index_changed(self, i): """ Persists host information changes like in brickv.mainwindow Changes port if the host was changed """ if i < 0: return self.host_index_changing = True self.spin_port.setValue(self.host_infos[i].port) self.host_index_changing = False def _port_changed(self, value): """ Persists host information changes like in brickv.mainwindow """ if self.host_index_changing: return i = self.combo_host.currentIndex() if i < 0: return self.host_infos[i].port = self.spin_port.value() def update_setup_tab(self, config): EventLogger.debug('Updating setup tab from config') self.combo_host.setEditText(config['hosts']['default']['name']) self.spin_port.setValue(config['hosts']['default']['port']) self.combo_data_time_format.setCurrentIndex( max( self.combo_data_time_format.findData( config['data']['time_format']), 0)) self.check_data_to_csv_file.setChecked( config['data']['csv']['enabled']) self.edit_csv_file_name.setText( config['data']['csv']['file_name'].decode('utf-8')) self.combo_debug_time_format.setCurrentIndex( max( self.combo_debug_time_format.findData( config['debug']['time_format']), 0)) self.check_debug_to_log_file.setChecked( config['debug']['log']['enabled']) self.edit_log_file_name.setText( config['debug']['log']['file_name'].decode('utf-8')) self.combo_log_level.setCurrentIndex( max( self.combo_debug_time_format.findData( config['debug']['log']['level']), 0)) def update_devices_tab(self, config): EventLogger.debug('Updating devices tab from config') self.model_devices.removeRows(0, self.model_data.rowCount()) for device in config['devices']: self.add_device_to_tree(device) def add_device_to_tree(self, device): # check if device is already added if len(device['uid']) > 0: for row in range(self.model_devices.rowCount()): existing_name = self.model_devices.item(row, 0).text() exisitng_uid = self.tree_devices.indexWidget( self.model_devices.item(row, 1).index()).text() if device['name'] == existing_name and device[ 'uid'] == exisitng_uid: EventLogger.info( 'Ignoring duplicate device "{0}" with UID "{1}"'. format(device['name'], device['uid'])) return # add device name_item = QStandardItem(device['name']) uid_item = QStandardItem('') self.model_devices.appendRow([name_item, uid_item]) edit_uid = QLineEdit() edit_uid.setPlaceholderText('Enter UID') edit_uid.setValidator( QRegExpValidator(QRegExp( '^[{0}]{{1,6}}$'.format(BASE58)))) # FIXME: use stricter logic edit_uid.setText(device['uid']) self.tree_devices.setIndexWidget(uid_item.index(), edit_uid) value_specs = device_specs[device['name']]['values'] parent_item = QStandardItem('Values') name_item.appendRow([parent_item, QStandardItem('')]) self.tree_devices.expand(parent_item.index()) # add values for value_spec in value_specs: value_name_item = QStandardItem(value_spec['name']) value_interval_item = QStandardItem('') parent_item.appendRow([value_name_item, value_interval_item]) spinbox_interval = QSpinBox() spinbox_interval.setRange(0, (1 << 31) - 1) spinbox_interval.setSingleStep(1) spinbox_interval.setValue( device['values'][value_spec['name']]['interval']) spinbox_interval.setSuffix(' seconds') self.tree_devices.setIndexWidget(value_interval_item.index(), spinbox_interval) if value_spec['subvalues'] != None: for subvalue_name in value_spec['subvalues']: subvalue_name_item = QStandardItem(subvalue_name) subvalue_check_item = QStandardItem('') value_name_item.appendRow( [subvalue_name_item, subvalue_check_item]) check_subvalue = QCheckBox() check_subvalue.setChecked(device['values'][ value_spec['name']]['subvalues'][subvalue_name]) self.tree_devices.setIndexWidget( subvalue_check_item.index(), check_subvalue) self.tree_devices.expand(name_item.index()) # add options option_specs = device_specs[device['name']]['options'] if option_specs != None: parent_item = QStandardItem('Options') name_item.appendRow([parent_item, QStandardItem('')]) for option_spec in option_specs: option_name_item = QStandardItem(option_spec['name']) option_widget_item = QStandardItem('') parent_item.appendRow([option_name_item, option_widget_item]) if option_spec['type'] == 'choice': widget_option_value = QComboBox() for option_value_spec in option_spec['values']: widget_option_value.addItem( option_value_spec[0].decode('utf-8'), option_value_spec[1]) widget_option_value.setCurrentIndex( widget_option_value.findText(device['options'][ option_spec['name']]['value'].decode('utf-8'))) elif option_spec['type'] == 'int': widget_option_value = QSpinBox() widget_option_value.setRange(option_spec['minimum'], option_spec['maximum']) widget_option_value.setSuffix(option_spec['suffix']) widget_option_value.setValue( device['options'][option_spec['name']]['value']) elif option_spec['type'] == 'bool': widget_option_value = QCheckBox() widget_option_value.setChecked( device['options'][option_spec['name']]['value']) self.tree_devices.setIndexWidget(option_widget_item.index(), widget_option_value) def add_debug_message(self, message): self.text_debug.append(message) while self.text_debug.document().blockCount() > 1000: cursor = QTextCursor(self.text_debug.document().begin()) cursor.select(QTextCursor.BlockUnderCursor) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor) cursor.removeSelectedText() if self.checkbox_debug_auto_scroll.isChecked(): self.text_debug.verticalScrollBar().setValue( self.text_debug.verticalScrollBar().maximum()) def btn_clear_debug_clicked(self): self.text_debug.clear() def highlight_debug_tab(self): """ SIGNAL function: Highlight the debug tab when an error occurs. """ if not self.tab_debug_warning and self.tab_widget.currentWidget( ).objectName() != self.tab_debug.objectName(): self.tab_debug_warning = True self.tab_set( self.tab_widget.indexOf(self.tab_debug), QColor(255, 0, 0), os.path.join(get_resources_path(), "warning-icon.png")) def table_add_row(self, csv_data): """ SIGNAL function: Adds new CSV Data into the Table. """ rows = self.model_data.rowCount() while rows >= 1000: self.model_data.removeRow(0) rows = self.model_data.rowCount() row_number = None if rows > 0: try: row_number = int( self.model_data.headerData(rows - 1, Qt.Vertical)) except ValueError: pass self.model_data.appendRow([ QStandardItem(csv_data.timestamp), QStandardItem(csv_data.name), QStandardItem(csv_data.uid), QStandardItem(csv_data.var_name), QStandardItem(str(csv_data.raw_data)), QStandardItem(csv_data.var_unit.decode('utf-8')) ]) if row_number != None: self.model_data.setHeaderData(rows, Qt.Vertical, str(row_number + 1)) if self.checkbox_data_auto_scroll.isChecked(): self.table_data.scrollToBottom()
class DefaultsDlg(QDialog, Ui_Dialog): """ Class documentation goes here. """ def __init__(self, defaults, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super().__init__(parent) self.setupUi(self) self.setAttribute(Qt.WA_DeleteOnClose) self.defaults = defaults self.fillScalars() self.fillPlots() self.fillCalculations() def updateDefaults(self): self.defaults['defaultScalars'] = self.setDefaultScalars() self.defaults['defaultPlots'] = self.setDefaultPlots() self.defaults['defaultCalculations'] = self.setDefaultCalculations() def fillScalars(self): scalars = [ 'absorbance (%)', 'reflectance (%)', 'transmittance (%)', 'absorbance (mA/cm²)', 'reflectance (mA/cm²)', 'transmittance (mA/cm²)', 'generation', 'Jmax (mA/cm²)', 'absorption layerwise (%)', 'absorption layerwise (mA/cm²)', 'collection layerwise (%)', 'collection layerwise (mA/cm²)', 'calc. time (s)' ] self.scalarListModel = QStandardItemModel() scalarsToShow = self.defaults['defaultScalars'] for value in scalars: item = QStandardItem(value) check = Qt.Checked if value in scalarsToShow else Qt.Unchecked item.setCheckState(check) item.setCheckable(True) self.scalarListModel.appendRow(item) self.scalarListView.setModel(self.scalarListModel) def setDefaultScalars(self): setVisible = [] for row in range(self.scalarListModel.rowCount()): item = self.scalarListModel.item(row) if item.checkState() == Qt.Checked: setVisible.append(item.text()) return setVisible def fillPlots(self): plots = [ 'total A,R,T', # requires calc [0] 'Ellipsometry', # requires nothing 'absorption (layerwise)', # requires calc [2] 'collection (layerwise)', # requires calc [2] 'QE', # requires calc [2] 'reflection (interfacewise)', 'generation' # requires calc [3] ] self.plotListModel = QStandardItemModel() plotsToShow = self.defaults['defaultPlots'] for value in plots: item = QStandardItem(value) check = Qt.Checked if value in plotsToShow else Qt.Unchecked item.setCheckState(check) item.setCheckable(True) self.plotListModel.appendRow(item) self.plotListView.setModel(self.plotListModel) def setDefaultPlots(self): setVisible = [] for row in range(self.plotListModel.rowCount()): item = self.plotListModel.item(row) if item.checkState() == Qt.Checked: setVisible.append(item.text()) return setVisible def fillCalculations(self): self.calculations = ['Stack optics (A,R,T)', 'Ellipsometry', 'Field intensity', 'Layerwise optics (absorption, collection, QE)', 'Generation' ] self.calcListModel = QStandardItemModel() calculationsToShow = self.defaults['defaultCalculations'] for value in self.calculations: item = QStandardItem(value) check = Qt.Checked if value in calculationsToShow else Qt.Unchecked item.setCheckState(check) item.setCheckable(True) #item.setEnabled(False) self.calcListModel.appendRow(item) self.calculationsListView.setModel(self.calcListModel) def setDefaultCalculations(self): for row in range(self.calcListModel.rowCount()): item = self.calcListModel.item(row) if item.checkState() == Qt.Checked: highestRow = row setCalcOn = self.calculations[:highestRow+1] return setCalcOn
class SetupDialog(QDialog, Ui_SetupDialog): """ Function and Event handling class for the Ui_SetupDialog. """ def __init__(self, parent): QDialog.__init__(self, parent) self._gui_logger = GUILogger("GUILogger", logging.INFO) self._gui_job = None EventLogger.add_logger(self._gui_logger) # FIXME better way to find interval and uids in tree_widget?! self.__tree_interval_tooltip = "Update interval in seconds" self.__tree_uid_tooltip = "UID cannot be empty" self.data_logger_thread = None self.tab_debug_warning = False self.device_dialog = None self.host_infos = None self.last_host = None self.host_index_changing = None self.setupUi(self) self.model_data = QStandardItemModel(self) self.model_data.setHorizontalHeaderLabels(['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit']) self.table_data.setModel(self.model_data) self.table_data.setColumnWidth(0, 160) self.table_data.setColumnWidth(1, 170) self.table_data.setColumnWidth(2, 50) self.table_data.setColumnWidth(3, 110) self.table_data.setColumnWidth(4, 70) self.table_data.setColumnWidth(5, 100) self.model_devices = QStandardItemModel(self) self.model_devices.setHorizontalHeaderLabels(['Device', 'Value']) self.tree_devices.setModel(self.model_devices) self.tree_devices.setColumnWidth(0, 300) self.widget_initialization() self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png'))) timestamp = int(time.time()) self.edit_csv_file_name.setText(os.path.join(get_home_path(), 'logger_data_{0}.csv'.format(timestamp))) self.edit_log_file_name.setText(os.path.join(get_home_path(), 'logger_debug_{0}.log'.format(timestamp))) self.combo_data_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de') self.combo_data_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us') self.combo_data_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso') self.combo_data_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix') self.combo_debug_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de') self.combo_debug_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us') self.combo_debug_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso') self.combo_debug_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix') self.combo_log_level.addItem('Debug', 'debug') self.combo_log_level.addItem('Info', 'info') self.combo_log_level.addItem('Warning', 'warning') self.combo_log_level.addItem('Error', 'error') self.combo_log_level.addItem('Critical', 'critical') self.combo_log_level.setCurrentIndex(0) # debug self.combo_debug_level.addItem('Debug', logging.DEBUG) self.combo_debug_level.addItem('Info', logging.INFO) self.combo_debug_level.addItem('Warning', logging.WARNING) self.combo_debug_level.addItem('Error', logging.ERROR) self.combo_debug_level.addItem('Critical', logging.CRITICAL) self.combo_debug_level.setCurrentIndex(1) # info self.update_ui_state() def update_ui_state(self): data_to_csv_file = self.check_data_to_csv_file.isChecked() debug_to_log_file = self.check_debug_to_log_file.isChecked() self.label_csv_file_name.setVisible(data_to_csv_file) self.edit_csv_file_name.setVisible(data_to_csv_file) self.btn_browse_csv_file_name.setVisible(data_to_csv_file) self.label_log_file_name.setVisible(debug_to_log_file) self.edit_log_file_name.setVisible(debug_to_log_file) self.btn_browse_log_file_name.setVisible(debug_to_log_file) self.label_log_level.setVisible(debug_to_log_file) self.combo_log_level.setVisible(debug_to_log_file) def widget_initialization(self): """ Sets default values for some widgets """ # Login data self.host_info_initialization() self.signal_initialization() def signal_initialization(self): """ Init of all important Signals and connections. """ # Buttons self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked) self.btn_save_config.clicked.connect(self.btn_save_config_clicked) self.btn_load_config.clicked.connect(self.btn_load_config_clicked) self.check_data_to_csv_file.stateChanged.connect(self.update_ui_state) self.check_debug_to_log_file.stateChanged.connect(self.update_ui_state) self.btn_browse_csv_file_name.clicked.connect(self.btn_browse_csv_file_name_clicked) self.btn_browse_log_file_name.clicked.connect(self.btn_browse_log_file_name_clicked) self.btn_clear_debug.clicked.connect(self.btn_clear_debug_clicked) self.combo_debug_level.currentIndexChanged.connect(self.combo_debug_level_changed) self.btn_add_device.clicked.connect(self.btn_add_device_clicked) self.btn_remove_device.clicked.connect(self.btn_remove_device_clicked) self.btn_remove_all_devices.clicked.connect(self.btn_remove_all_devices_clicked) self.tab_widget.currentChanged.connect(self.tab_reset_warning) self.btn_clear_data.clicked.connect(self.btn_clear_data_clicked) self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE), self.add_debug_message) self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE_TAB_HIGHLIGHT), self.highlight_debug_tab) self.combo_host.currentIndexChanged.connect(self._host_index_changed) self.spin_port.valueChanged.connect(self._port_changed) def host_info_initialization(self): """ initialize host by getting information out of brickv.config """ self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT) self.host_index_changing = True for host_info in self.host_infos: self.combo_host.addItem(host_info.host) self.last_host = None self.combo_host.setCurrentIndex(0) self.spin_port.setValue(self.host_infos[0].port) self.host_index_changing = False def btn_start_logging_clicked(self): """ Start/Stop of the logging process """ if (self.data_logger_thread is not None) and (not self.data_logger_thread.stopped): self.btn_start_logging.clicked.disconnect() self.data_logger_thread.stop() self._reset_stop() elif self.data_logger_thread is None: from brickv.data_logger import main self._gui_job = GuiDataJob(name="GuiData-Writer") self.connect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row) self.data_logger_thread = main.main(None, GuiConfigHandler.create_config(self), self._gui_job) if self.data_logger_thread is not None: self.btn_start_logging.setText("Stop Logging") self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/stop-icon.png'))) self.tab_devices.setEnabled(False) self.tab_setup.setEnabled(False) self.tab_widget.setCurrentIndex(self.tab_widget.indexOf(self.tab_data)) self.tab_reset_warning() def _reset_stop(self): self.tab_devices.setEnabled(True) self.tab_setup.setEnabled(True) self.btn_start_logging.setText("Start Logging") self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png'))) self.disconnect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row) self.data_logger_thread = None self._gui_job = None self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked) def btn_save_config_clicked(self): filename = get_save_file_name(get_main_window(), 'Save Config', get_home_path(), 'JSON Files (*.json)') if len(filename) == 0: return if not filename.lower().endswith('.json'): filename += '.json' config = GuiConfigHandler.create_config(self) if not save_config(config, filename): QMessageBox.warning(get_main_window(), 'Save Config', 'Could not save config to file! See Debug tab for details.', QMessageBox.Ok) def btn_load_config_clicked(self): filename = get_open_file_name(get_main_window(), 'Load Config', get_home_path(), 'JSON Files (*.json)') if len(filename) == 0: return config = load_and_validate_config(filename) if config == None: QMessageBox.warning(get_main_window(), 'Load Config', 'Could not load config from file! See Debug tab for details.', QMessageBox.Ok) return self.update_setup_tab(config) self.update_devices_tab(config) def btn_browse_csv_file_name_clicked(self): if len(self.edit_csv_file_name.text()) > 0: last_dir = os.path.dirname(os.path.realpath(self.edit_csv_file_name.text())) else: last_dir = get_home_path() filename = get_save_file_name(get_main_window(), 'Choose CSV File', last_dir, "CSV Files (*.csv)") if len(filename) > 0: if not filename.lower().endswith('.csv'): filename += '.csv' self.edit_csv_file_name.setText(filename) def btn_browse_log_file_name_clicked(self): if len(self.edit_log_file_name.text()) > 0: last_dir = os.path.dirname(os.path.realpath(self.edit_log_file_name.text())) else: last_dir = get_home_path() filename = get_save_file_name(get_main_window(), 'Choose Log File', last_dir, "Log Files (*.log)") if len(filename) > 0: if not filename.lower().endswith('.log'): filename += '.log' self.edit_log_file_name.setText(filename) def btn_add_device_clicked(self): """ Opens the DeviceDialog in Add-Mode. """ if self.device_dialog is None: self.device_dialog = DeviceDialog(self) self.device_dialog.btn_refresh_clicked() self.device_dialog.show() def btn_remove_device_clicked(self): selection = self.tree_devices.selectionModel().selectedIndexes() while len(selection) > 0: index = selection[0] while index.parent() != self.model_devices.invisibleRootItem().index(): index = index.parent() self.model_devices.removeRows(index.row(), 1) # get new selection, because row removal might invalid indices selection = self.tree_devices.selectionModel().selectedIndexes() def btn_remove_all_devices_clicked(self): self.model_devices.removeRows(0, self.model_devices.rowCount()) def btn_clear_data_clicked(self): self.model_data.removeRows(0, self.model_data.rowCount()) def tab_reset_warning(self): """ Resets the Warning @ the debug tab. """ if not self.tab_debug_warning or self.tab_widget.currentWidget().objectName() != self.tab_debug.objectName(): return self.tab_debug_warning = False self.tab_set(self.tab_widget.indexOf(self.tab_debug), self.palette().color(QPalette.WindowText), None) def combo_debug_level_changed(self): """ Changes the log level dynamically. """ self._gui_logger.level = self.combo_debug_level.itemData(self.combo_debug_level.currentIndex()) def tab_set(self, tab_index, color, icon=None): """ Sets the font Color and an icon, if given, at a specific tab. """ from PyQt4.QtGui import QIcon self.tab_widget.tabBar().setTabTextColor(tab_index, color) if icon is not None: self.tab_widget.setTabIcon(tab_index, QIcon(icon)) else: self.tab_widget.setTabIcon(tab_index, QIcon()) def _host_index_changed(self, i): """ Persists host information changes like in brickv.mainwindow Changes port if the host was changed """ if i < 0: return self.host_index_changing = True self.spin_port.setValue(self.host_infos[i].port) self.host_index_changing = False def _port_changed(self, value): """ Persists host information changes like in brickv.mainwindow """ if self.host_index_changing: return i = self.combo_host.currentIndex() if i < 0: return self.host_infos[i].port = self.spin_port.value() def update_setup_tab(self, config): EventLogger.debug('Updating setup tab from config') self.combo_host.setEditText(config['hosts']['default']['name']) self.spin_port.setValue(config['hosts']['default']['port']) self.combo_data_time_format.setCurrentIndex(max(self.combo_data_time_format.findData(config['data']['time_format']), 0)) self.check_data_to_csv_file.setChecked(config['data']['csv']['enabled']) self.edit_csv_file_name.setText(config['data']['csv']['file_name'].decode('utf-8')) self.combo_debug_time_format.setCurrentIndex(max(self.combo_debug_time_format.findData(config['debug']['time_format']), 0)) self.check_debug_to_log_file.setChecked(config['debug']['log']['enabled']) self.edit_log_file_name.setText(config['debug']['log']['file_name'].decode('utf-8')) self.combo_log_level.setCurrentIndex(max(self.combo_debug_time_format.findData(config['debug']['log']['level']), 0)) def update_devices_tab(self, config): EventLogger.debug('Updating devices tab from config') self.model_devices.removeRows(0, self.model_data.rowCount()) for device in config['devices']: self.add_device_to_tree(device) def add_device_to_tree(self, device): # check if device is already added if len(device['uid']) > 0: for row in range(self.model_devices.rowCount()): existing_name = self.model_devices.item(row, 0).text() exisitng_uid = self.tree_devices.indexWidget(self.model_devices.item(row, 1).index()).text() if device['name'] == existing_name and device['uid'] == exisitng_uid: EventLogger.info('Ignoring duplicate device "{0}" with UID "{1}"' .format(device['name'], device['uid'])) return # add device name_item = QStandardItem(device['name']) uid_item = QStandardItem('') self.model_devices.appendRow([name_item, uid_item]) edit_uid = QLineEdit() edit_uid.setPlaceholderText('Enter UID') edit_uid.setValidator(QRegExpValidator(QRegExp('^[{0}]{{1,6}}$'.format(BASE58)))) # FIXME: use stricter logic edit_uid.setText(device['uid']) self.tree_devices.setIndexWidget(uid_item.index(), edit_uid) value_specs = device_specs[device['name']]['values'] parent_item = QStandardItem('Values') name_item.appendRow([parent_item, QStandardItem('')]) self.tree_devices.expand(parent_item.index()) # add values for value_spec in value_specs: value_name_item = QStandardItem(value_spec['name']) value_interval_item = QStandardItem('') parent_item.appendRow([value_name_item, value_interval_item]) spinbox_interval = QSpinBox() spinbox_interval.setRange(0, (1 << 31) - 1) spinbox_interval.setSingleStep(1) spinbox_interval.setValue(device['values'][value_spec['name']]['interval']) spinbox_interval.setSuffix(' seconds') self.tree_devices.setIndexWidget(value_interval_item.index(), spinbox_interval) if value_spec['subvalues'] != None: for subvalue_name in value_spec['subvalues']: subvalue_name_item = QStandardItem(subvalue_name) subvalue_check_item = QStandardItem('') value_name_item.appendRow([subvalue_name_item, subvalue_check_item]) check_subvalue = QCheckBox() check_subvalue.setChecked(device['values'][value_spec['name']]['subvalues'][subvalue_name]) self.tree_devices.setIndexWidget(subvalue_check_item.index(), check_subvalue) self.tree_devices.expand(name_item.index()) # add options option_specs = device_specs[device['name']]['options'] if option_specs != None: parent_item = QStandardItem('Options') name_item.appendRow([parent_item, QStandardItem('')]) for option_spec in option_specs: option_name_item = QStandardItem(option_spec['name']) option_widget_item = QStandardItem('') parent_item.appendRow([option_name_item, option_widget_item]) if option_spec['type'] == 'choice': widget_option_value = QComboBox() for option_value_spec in option_spec['values']: widget_option_value.addItem(option_value_spec[0].decode('utf-8'), option_value_spec[1]) widget_option_value.setCurrentIndex(widget_option_value.findText(device['options'][option_spec['name']]['value'].decode('utf-8'))) elif option_spec['type'] == 'int': widget_option_value = QSpinBox() widget_option_value.setRange(option_spec['minimum'], option_spec['maximum']) widget_option_value.setSuffix(option_spec['suffix']) widget_option_value.setValue(device['options'][option_spec['name']]['value']) elif option_spec['type'] == 'bool': widget_option_value = QCheckBox() widget_option_value.setChecked(device['options'][option_spec['name']]['value']) self.tree_devices.setIndexWidget(option_widget_item.index(), widget_option_value) def add_debug_message(self, message): self.text_debug.append(message) while self.text_debug.document().blockCount() > 1000: cursor = QTextCursor(self.text_debug.document().begin()) cursor.select(QTextCursor.BlockUnderCursor) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor) cursor.removeSelectedText() if self.checkbox_debug_auto_scroll.isChecked(): self.text_debug.verticalScrollBar().setValue(self.text_debug.verticalScrollBar().maximum()) def btn_clear_debug_clicked(self): self.text_debug.clear() def highlight_debug_tab(self): """ SIGNAL function: Highlight the debug tab when an error occurs. """ if not self.tab_debug_warning and self.tab_widget.currentWidget().objectName() != self.tab_debug.objectName(): self.tab_debug_warning = True self.tab_set(self.tab_widget.indexOf(self.tab_debug), QColor(255, 0, 0), os.path.join(get_resources_path(), "warning-icon.png")) def table_add_row(self, csv_data): """ SIGNAL function: Adds new CSV Data into the Table. """ rows = self.model_data.rowCount() while rows >= 1000: self.model_data.removeRow(0) rows = self.model_data.rowCount() row_number = None if rows > 0: try: row_number = int(self.model_data.headerData(rows - 1, Qt.Vertical)) except ValueError: pass self.model_data.appendRow([QStandardItem(csv_data.timestamp), QStandardItem(csv_data.name), QStandardItem(csv_data.uid), QStandardItem(csv_data.var_name), QStandardItem(str(csv_data.raw_data)), QStandardItem(csv_data.var_unit.decode('utf-8'))]) if row_number != None: self.model_data.setHeaderData(rows, Qt.Vertical, str(row_number + 1)) if self.checkbox_data_auto_scroll.isChecked(): self.table_data.scrollToBottom()
class OWConfusionMatrix(widget.OWWidget): name = "Confusion Matrix" description = "Display confusion matrix constructed from results " \ "of evaluation of classifiers." icon = "icons/ConfusionMatrix.svg" priority = 1001 inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")] outputs = [("Selected Data", Orange.data.Table)] quantities = ["Number of instances", "Proportion of predicted", "Proportion of actual"] selected_learner = settings.Setting([]) selected_quantity = settings.Setting(0) append_predictions = settings.Setting(True) append_probabilities = settings.Setting(False) autocommit = settings.Setting(True) UserAdviceMessages = [ widget.Message( "Clicking on cells or in headers outputs the corresponding " "data instances", "click_cell")] def __init__(self): super().__init__() self.data = None self.results = None self.learners = [] self.headers = [] box = gui.widgetBox(self.controlArea, "Learners") self.learners_box = gui.listBox( box, self, "selected_learner", "learners", callback=self._learner_changed ) box = gui.widgetBox(self.controlArea, "Show") gui.comboBox(box, self, "selected_quantity", items=self.quantities, callback=self._update) box = gui.widgetBox(self.controlArea, "Select") gui.button(box, self, "Correct", callback=self.select_correct, autoDefault=False) gui.button(box, self, "Misclassified", callback=self.select_wrong, autoDefault=False) gui.button(box, self, "None", callback=self.select_none, autoDefault=False) self.outputbox = box = gui.widgetBox(self.controlArea, "Output") gui.checkBox(box, self, "append_predictions", "Predictions", callback=self._invalidate) gui.checkBox(box, self, "append_probabilities", "Probabilities", callback=self._invalidate) gui.auto_commit(self.controlArea, self, "autocommit", "Send Data", "Auto send is on") grid = QGridLayout() self.tablemodel = QStandardItemModel(self) view = self.tableview = QTableView( editTriggers=QTableView.NoEditTriggers) view.setModel(self.tablemodel) view.horizontalHeader().hide() view.verticalHeader().hide() view.horizontalHeader().setMinimumSectionSize(60) view.selectionModel().selectionChanged.connect(self._invalidate) view.setShowGrid(False) view.clicked.connect(self.cell_clicked) grid.addWidget(view, 0, 0) self.mainArea.layout().addLayout(grid) def sizeHint(self): return QSize(750, 490) def _item(self, i, j): return self.tablemodel.item(i, j) or QStandardItem() def _set_item(self, i, j, item): self.tablemodel.setItem(i, j, item) def set_results(self, results): """Set the input results.""" self.clear() self.warning([0, 1]) data = None if results is not None: if results.data is not None: data = results.data if data is not None and not data.domain.has_discrete_class: data = None results = None self.warning( 0, "Confusion Matrix cannot be used for regression results.") self.results = results self.data = data if data is not None: class_values = data.domain.class_var.values elif results is not None: raise NotImplementedError if results is not None: nmodels, ntests = results.predicted.shape self.headers = class_values + \ [unicodedata.lookup("N-ARY SUMMATION")] # NOTE: The 'learner_names' is set in 'Test Learners' widget. if hasattr(results, "learner_names"): self.learners = results.learner_names else: self.learners = ["Learner #%i" % (i + 1) for i in range(nmodels)] item = self._item(0, 2) item.setData("Predicted", Qt.DisplayRole) item.setTextAlignment(Qt.AlignCenter) item.setFlags(Qt.NoItemFlags) self._set_item(0, 2, item) item = self._item(2, 0) item.setData("Actual", Qt.DisplayRole) item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom) item.setFlags(Qt.NoItemFlags) self.tableview.setItemDelegateForColumn( 0, gui.VerticalItemDelegate()) self._set_item(2, 0, item) self.tableview.setSpan(0, 2, 1, len(class_values)) self.tableview.setSpan(2, 0, len(class_values), 1) for i in (0, 1): for j in (0, 1): item = self._item(i, j) item.setFlags(Qt.NoItemFlags) self._set_item(i, j, item) for p, label in enumerate(self.headers): for i, j in ((1, p + 2), (p + 2, 1)): item = self._item(i, j) item.setData(label, Qt.DisplayRole) item.setData(QBrush(QColor(208, 208, 208)), Qt.BackgroundColorRole) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) self._set_item(i, j, item) hor_header = self.tableview.horizontalHeader() if len(' '.join(self.headers)) < 120: hor_header.setResizeMode(QHeaderView.ResizeToContents) else: hor_header.setDefaultSectionSize(60) self.tablemodel.setRowCount(len(class_values) + 3) self.tablemodel.setColumnCount(len(class_values) + 3) self.selected_learner = [0] self._update() def clear(self): self.results = None self.data = None self.tablemodel.clear() self.headers = [] # Clear learners last. This action will invoke `_learner_changed` # method self.learners = [] def select_correct(self): selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): index = self.tablemodel.index(i, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect ) def select_wrong(self): selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): for j in range(i + 1, n): index = self.tablemodel.index(i, j) selection.select(index, index) index = self.tablemodel.index(j, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect ) def select_none(self): self.tableview.selectionModel().clear() def cell_clicked(self, model_index): i, j = model_index.row(), model_index.column() if not i or not j: return n = self.tablemodel.rowCount() index = self.tablemodel.index selection = None if i == j == 1 or i == j == n - 1: selection = QItemSelection(index(2, 2), index(n - 1, n - 1)) elif i in (1, n - 1): selection = QItemSelection(index(2, j), index(n - 1, j)) elif j in (1, n - 1): selection = QItemSelection(index(i, 2), index(i, n - 1)) if selection is not None: self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect ) def commit(self): if self.results is not None and self.data is not None \ and self.selected_learner: indices = self.tableview.selectedIndexes() indices = {(ind.row() - 2, ind.column() - 2) for ind in indices} actual = self.results.actual selected_learner = self.selected_learner[0] learner_name = self.learners[selected_learner] predicted = self.results.predicted[selected_learner] selected = [i for i, t in enumerate(zip(actual, predicted)) if t in indices] row_indices = self.results.row_indices[selected] extra = [] class_var = self.data.domain.class_var metas = self.data.domain.metas if self.append_predictions: predicted = numpy.array(predicted[selected], dtype=object) extra.append(predicted.reshape(-1, 1)) var = Orange.data.DiscreteVariable( "{}({})".format(class_var.name, learner_name), class_var.values ) metas = metas + (var,) if self.append_probabilities and \ self.results.probabilities is not None: probs = self.results.probabilities[selected_learner, selected] extra.append(numpy.array(probs, dtype=object)) pvars = [Orange.data.ContinuousVariable("p({})".format(value)) for value in class_var.values] metas = metas + tuple(pvars) X = self.data.X[row_indices] Y = self.data.Y[row_indices] M = self.data.metas[row_indices] row_ids = self.data.ids[row_indices] M = numpy.hstack((M,) + tuple(extra)) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, metas ) data = Orange.data.Table.from_numpy(domain, X, Y, M) data.ids = row_ids data.name = learner_name else: data = None self.send("Selected Data", data) def _invalidate(self): self.commit() def _learner_changed(self): # The selected learner has changed indices = self.tableview.selectedIndexes() self._update() selection = QItemSelection() for sel in indices: selection.select(sel, sel) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect ) self.commit() def _update(self): # Update the displayed confusion matrix if self.results is not None and self.selected_learner: index = self.selected_learner[0] cmatrix = confusion_matrix(self.results, index) colsum = cmatrix.sum(axis=0) rowsum = cmatrix.sum(axis=1) total = rowsum.sum() if self.selected_quantity == 0: value = lambda i, j: int(cmatrix[i, j]) elif self.selected_quantity == 1: value = lambda i, j: \ ("{:2.1f} %".format(100 * cmatrix[i, j] / colsum[i]) if colsum[i] else "N/A") elif self.selected_quantity == 2: value = lambda i, j: \ ("{:2.1f} %".format(100 * cmatrix[i, j] / rowsum[i]) if colsum[i] else "N/A") else: assert False for i, row in enumerate(cmatrix): for j, _ in enumerate(row): item = self._item(i + 2, j + 2) item.setData(value(i, j), Qt.DisplayRole) item.setToolTip("actual: {}\npredicted: {}".format( self.headers[i], self.headers[j])) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self._set_item(i + 2, j + 2, item) model = self.tablemodel font = model.invisibleRootItem().font() bold_font = QFont(font) bold_font.setBold(True) def sum_item(value): item = QStandardItem() item.setData(value, Qt.DisplayRole) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) item.setFont(bold_font) return item N = len(colsum) for i in range(N): model.setItem(N + 2, i + 2, sum_item(int(colsum[i]))) model.setItem(i + 2, N + 2, sum_item(int(rowsum[i]))) model.setItem(N + 2, N + 2, sum_item(int(total)))
class QMapManager(QDialog): def __init__(self, config, parent=None): QDialog.__init__(self, parent) curdir = os.path.abspath(os.path.dirname(__file__)) PyQt4.uic.loadUi(os.path.join(curdir,'manager.ui'), self) self.model = QStandardItemModel() self.projectsmodel = QStandardItemModel() self.projectlist.setModel(self.projectsmodel) self.clientlist.setModel(self.model) self.clientlist.selectionModel().selectionChanged.connect(self.update) self.installbutton.pressed.connect(self.installToClient) self.mapper = QDataWidgetMapper() self.mapper.setModel(self.model) self.mapper.addMapping(self.installpath, 1) self.config = config self.populateProjects() self.populateClients() def installToClient(self): index = self.clientlist.selectionModel().currentIndex() item = self.model.itemFromIndex(index) print "Deploying to " + item.text() build.deployTargetByName(item.text()) def update(self, selected, deselected ): index = selected.indexes()[0] self.mapper.setCurrentModelIndex(index) item = self.model.itemFromIndex(index) settings = item.data() for row in xrange(0,self.projectsmodel.rowCount()): index = self.projectsmodel.index(row, 0) item = self.projectsmodel.itemFromIndex(index) item.setCheckState(Qt.Unchecked) projects = settings['projects'] for project in projects: if project == "All": i = 0 while self.projectsmodel.item(i): item = self.projectsmodel.item(i) item.setCheckState(Qt.Checked) i += 1 break projectitem = self.projectsmodel.findItems(project)[0] projectitem.setCheckState(Qt.Checked) def populateClients(self): row = 0 for client, settings in self.config['clients'].iteritems(): name = QStandardItem(client) name.setData(settings) path = QStandardItem(settings['path']) self.model.insertRow(row, [name, path]) row += 1 def populateProjects(self): row = 0 for project in getProjects(): projectitem = QStandardItem(project.name) projectitem.setCheckable(True) self.projectsmodel.insertRow(row, projectitem) row += 1
class DlgCharting(QDialog): def __init__(self, parent, data): QDialog.__init__(self, parent) self.ui = Ui_ChartingBase() self.ui.setupUi(self) self.setWindowTitle("Charting Tool 2") # self.ui.btnNext.clicked.connect(self.btnNext_clicked) self.ui.btnPrevious.clicked.connect(self.btnPrevious_clicked) self.ui.btnExit.clicked.connect(self.btnExit_clicked) self.ui.txtText1.textChanged.connect(self.txtText1_textChanged) self.ui.txtText2.textChanged.connect(self.txtText2_textChanged) self.ui.txtText3.textChanged.connect(self.txtText3_textChanged) self.ui.txtText4.textChanged.connect(self.txtText4_textChanged) self.ui.txtText5.textChanged.connect(self.txtText5_textChanged) self.ui.txtText6.textChanged.connect(self.txtText6_textChanged) self.ui.txtText7.textChanged.connect(self.txtText7_textChanged) self.ui.txtText8.textChanged.connect(self.txtText8_textChanged) self.ui.txtText9.textChanged.connect(self.txtText9_textChanged) self.ui.txtText10.textChanged.connect(self.txtText10_textChanged) self.ui.txtText11.textChanged.connect(self.txtText11_textChanged) self.ui.txtText12.textChanged.connect(self.txtText12_textChanged) self.ui.txtText13.textChanged.connect(self.txtText13_textChanged) # self.btnNextAndbtnPreviewSetEnabled() self.setDataDict = None self.parentDlg = parent self.pw = None self.stdModel = None self.data = data self.renderFlag = False self.changedComposerMap = None self.tableChangedValue = None self.straightCount = self.data["StraightCount"] self.catOfAcftCount = self.data["CatOfAcftCount"][0] self.rejected.connect(self.dlgRejected) def dlgRejected(self): self.parentDlg.show() def refreshData(self, data): self.data = data def txtText1_textChanged(self): self.txt1.setText(self.ui.txtText1.text()) def txtText2_textChanged(self): self.txt2.setText(self.ui.txtText2.text()) def txtText3_textChanged(self): self.txt3.setText(self.ui.txtText3.text()) def txtText4_textChanged(self): self.txt4.setText(self.ui.txtText4.toPlainText()) def txtText5_textChanged(self): self.txt5.setText(self.ui.txtText5.toPlainText()) def txtText6_textChanged(self): self.txt6.setText(self.ui.txtText6.toPlainText()) def txtText7_textChanged(self): try: self.txt7.setText(self.ui.txtText7.toPlainText()) except: pass def txtText8_textChanged(self): self.txt8.setText(self.ui.txtText8.text()) def txtText9_textChanged(self): self.txt9.setText(self.ui.txtText9.text()) def txtText10_textChanged(self): self.txt10.setText(self.ui.txtText10.text()) def txtText11_textChanged(self): self.txt11.setText(self.ui.txtText11.text()) def txtText12_textChanged(self): self.txt12.setText(self.ui.txtText12.text()) def txtText13_textChanged(self): self.txt13.setText(self.ui.txtText13.text()) # def btnNextAndbtnPreviewSetEnabled(self): # if self.ui.stackedWidget.currentIndex() == 0: # self.ui.btnPrevious.setEnabled(False) # self.ui.frame_2.setVisible(False) # self.resize(100, 100) # # else: # self.ui.frame_2.setVisible(True) # self.ui.btnPrevious.setEnabled(True) # if self.ui.stackedWidget.currentIndex() == self.ui.stackedWidget.count() - 1: # self.ui.btnNext.setEnabled(False) # else: # self.ui.btnNext.setEnabled(True) def btnExit_clicked(self): # comp = QgsComposer(self, define._canvas) # comp.show() self.setDataDict = dict() for key, val in self.data.iteritems(): self.setDataDict.__setitem__(key, val) self.setDataDict.__setitem__("TextData", [ self.ui.txtText1.text(), self.ui.txtText2.text(), self.ui.txtText3.text(), self.ui.txtText4.toPlainText(), self.ui.txtText5.toPlainText(), self.ui.txtText6.toPlainText(), self.ui.txtText7.toPlainText(), self.ui.txtText8.text(), self.ui.txtText9.text(), self.ui.txtText10.text(), self.ui.txtText11.text(), self.ui.txtText12.text(), self.ui.txtText13.text() ]) # self.setDataDict.__setitem__("StraightCount", self.straightCount) # self.setDataDict.__setitem__("CatOfAcftCount", self.catOfAcftCount) comp = None if self.pw == None or not isinstance(self.pw, ComposerDlg): comp = self.composer(self.setDataDict) else: comp = self.composer(self.setDataDict, False) pwFlag = False if self.pw == None or not isinstance(self.pw, ComposerDlg): self.pw = ComposerDlg(self, comp, self.stdModel, self.setDataDict) pwFlag = True if not self.renderFlag: self.pw.show() if not pwFlag: self.pw.rePresent(comp, self.stdModel, self.setDataDict) self.renderFlag = False def showDlg(self): self.pw.hide() self.show() self.ui.txtText1.setText(self.txt1.text()) self.ui.txtText2.setText(self.txt2.text()) self.ui.txtText3.setText(self.txt3.text()) self.ui.txtText4.setText(self.txt4.text()) self.ui.txtText5.setText(self.txt5.text()) self.ui.txtText6.setText(self.txt6.text()) self.ui.txtText7.setText(self.txt7.text()) self.ui.txtText8.setText(self.txt8.text()) self.ui.txtText9.setText(self.txt9.text()) self.ui.txtText10.setText(self.txt10.text()) self.ui.txtText11.setText(self.txt11.text()) self.ui.txtText12.setText(self.txt12.text()) self.ui.txtText13.setText(self.txt13.text()) # def btnNext_clicked(self): # if self.ui.stackedWidget.currentIndex() + 1 < self.ui.stackedWidget.count(): # self.ui.stackedWidget.setCurrentIndex(self.ui.stackedWidget.currentIndex() + 1) # self.btnNextAndbtnPreviewSetEnabled() def btnPrevious_clicked(self): self.setVisible(False) self.parent().show() # if self.ui.stackedWidget.currentIndex() > 0: # self.ui.stackedWidget.setCurrentIndex(self.ui.stackedWidget.currentIndex() - 1) # self.btnNextAndbtnPreviewSetEnabled() def composer(self, setData, flag=True): paperWidth = setData["Width"] paperHeight = setData["Height"] mapRenderer = define._canvas.mapRenderer() # comp = None comp = QgsComposition(mapRenderer) comp.setPlotStyle(QgsComposition.Print) comp.setPaperSize(paperWidth, paperHeight) # rectangleAll = QgsComposerShape(comp) # rectangleAll.setItemPosition(3, 3, paperWidth - 3, paperHeight - 3) # rectangleAll.setShapeType(1) # comp.addItem(rectangleAll) self.txt1 = QgsComposerLabel(comp) self.txt1.setItemPosition(20, 20) self.txt1.setFrameEnabled(False) font = QFont("Arial", 10) self.txt1.setFont(font) self.txt1.setText(setData["TextData"][0]) self.txt1.adjustSizeToText() comp.addItem(self.txt1) self.txt2 = QgsComposerLabel(comp) self.txt2.setItemPosition(int(paperWidth / 2) + 10, 20) self.txt2.setFrameEnabled(False) font = QFont("Arial", 10) self.txt2.setFont(font) self.txt2.setText(setData["TextData"][1]) self.txt2.adjustSizeToText() comp.addItem(self.txt2) self.txt3 = QgsComposerLabel(comp) self.txt3.setItemPosition(paperWidth - 40, 20) self.txt3.setFrameEnabled(False) font = QFont("Arial", 10) self.txt3.setFont(font) self.txt3.setText(setData["TextData"][2]) self.txt3.adjustSizeToText() comp.addItem(self.txt3) w = int((paperWidth - 40) / 4) self.txt4 = QgsComposerLabel(comp) self.txt4.setItemPosition(20, 35) self.txt4.setFrameEnabled(False) font = QFont("Arial", 10) self.txt4.setFont(font) self.txt4.setText(setData["TextData"][3]) self.txt4.adjustSizeToText() comp.addItem(self.txt4) self.txt5 = QgsComposerLabel(comp) self.txt5.setItemPosition(20 + w, 35) self.txt5.setFrameEnabled(False) font = QFont("Arial", 10) self.txt5.setFont(font) self.txt5.setText(setData["TextData"][4]) self.txt5.adjustSizeToText() comp.addItem(self.txt5) self.txt6 = QgsComposerLabel(comp) self.txt6.setItemPosition(20 + w * 2, 35) self.txt6.setFrameEnabled(False) font = QFont("Arial", 10) self.txt6.setFont(font) self.txt6.setText(setData["TextData"][5]) self.txt6.adjustSizeToText() comp.addItem(self.txt6) self.txt7 = QgsComposerLabel(comp) self.txt7.setItemPosition(20 + w * 3, 35) self.txt7.setFrameEnabled(False) font = QFont("Arial", 10) self.txt7.setFont(font) self.txt7.setText(setData["TextData"][6]) self.txt7.adjustSizeToText() comp.addItem(self.txt7) # if flag: x, y = 20, 45 composerMap = QgsComposerMap(comp, x, y, paperWidth - 40, 150) # composerMap.setPreviewMode(QgsComposerMap.Render) # composerMap.setGridEnabled(False) #rect = composerMap.currentMapExtent () renderer = composerMap.mapRenderer() newExtent = renderer.extent() #Make sure the width/height ratio is the same as in current composer map extent. #This is to keep the map item frame and the page layout fixed currentMapExtent = composerMap.currentMapExtent() currentWidthHeightRatio = currentMapExtent.width( ) / currentMapExtent.height() newWidthHeightRatio = newExtent.width() / newExtent.height() if currentWidthHeightRatio < newWidthHeightRatio: #enlarge height of new extent, ensuring the map center stays the same newHeight = newExtent.width() / currentWidthHeightRatio deltaHeight = newHeight - newExtent.height() newExtent.setYMinimum(newExtent.yMinimum() - deltaHeight / 2) newExtent.setYMaximum(newExtent.yMaximum() + deltaHeight / 2) else: #enlarge width of new extent, ensuring the map center stays the same newWidth = currentWidthHeightRatio * newExtent.height() deltaWidth = newWidth - newExtent.width() newExtent.setXMinimum(newExtent.xMinimum() - deltaWidth / 2) newExtent.setXMaximum(newExtent.xMaximum() + deltaWidth / 2) composerMap.beginCommand("Map extent changed") composerMap.setNewExtent(newExtent) composerMap.endCommand() # composerMap.setNewScale(3500) composerMap.setFrameEnabled(True) composerMap.setFrameOutlineWidth(1.0) composerMap.setPreviewMode(QgsComposerMap.Render) composerMap.updateCachedImage() composerMap.setGridEnabled(True) composerMap.setGridPenColor(QColor(255, 255, 255, 0)) composerMap.setGridPenWidth(0.0) #composerMap.setGridStyle(QgsComposerMap.FrameAnnotationsOnly) composerMap.setGridIntervalX(1.0) composerMap.setGridIntervalY(1.0) # mySymbol1 = composerMap.gridLineSymbol () # mySymbol1.setAlpha(0) #composerMap.setGridLineSymbol(mySymbol1) composerMap.setShowGridAnnotation(True) composerMap.setGridAnnotationFormat(1) composerMap.setGridAnnotationPrecision(0) composerMap.setGridAnnotationDirection(1, 0) composerMap.setGridAnnotationDirection(1, 1) comp.addItem(composerMap) w = int((paperWidth - 40) / 3) self.txt8 = QgsComposerLabel(comp) self.txt8.setItemPosition(20, 225) self.txt8.setFrameEnabled(False) font = QFont("Arial", 10) self.txt8.setFont(font) self.txt8.setText(setData["TextData"][7]) self.txt8.adjustSizeToText() comp.addItem(self.txt8) self.txt9 = QgsComposerLabel(comp) self.txt9.setItemPosition(20 + w, 225) self.txt9.setFrameEnabled(False) font = QFont("Arial", 10) self.txt9.setFont(font) self.txt9.setText(setData["TextData"][8]) self.txt9.adjustSizeToText() comp.addItem(self.txt9) self.txt10 = QgsComposerLabel(comp) self.txt10.setItemPosition(20 + w * 2, 225) self.txt10.setFrameEnabled(False) font = QFont("Arial", 10) self.txt10.setFont(font) self.txt10.setText(setData["TextData"][9]) self.txt10.adjustSizeToText() comp.addItem(self.txt10) # profileRect = QgsComposerPicture(comp) # profileRect.setItemPosition(20, 200, paperWidth - 40, 50) # comp.addItem(profileRect) self.txt11 = QgsComposerLabel(comp) self.txt11.setItemPosition(20, paperHeight - 30) self.txt11.setFrameEnabled(False) font = QFont("Arial", 10) self.txt11.setFont(font) self.txt11.setText(setData["TextData"][10]) self.txt11.adjustSizeToText() comp.addItem(self.txt11) self.txt12 = QgsComposerLabel(comp) self.txt12.setItemPosition(20 + w, paperHeight - 30) self.txt12.setFrameEnabled(False) font = QFont("Arial", 10) self.txt12.setFont(font) self.txt12.setText(setData["TextData"][11]) self.txt12.adjustSizeToText() comp.addItem(self.txt12) self.txt13 = QgsComposerLabel(comp) self.txt13.setItemPosition(20 + w * 2, paperHeight - 30) self.txt13.setFrameEnabled(False) font = QFont("Arial", 10) self.txt13.setFont(font) self.txt13.setText(setData["TextData"][12]) self.txt13.adjustSizeToText() comp.addItem(self.txt13) # gpw = QGraphicsProxyWidget() self.tblView = QTableView() tableHeight = None tableWidth = None if self.tableChangedValue == None: self.tblView.setFixedWidth(paperWidth - 40) tableHeight = 50 tableWidth = paperWidth - 40 self.tblView.setFixedHeight(tableHeight) else: self.tblView.setFixedWidth(self.tableChangedValue["Width"]) self.tblView.setFixedHeight(self.tableChangedValue["Height"]) tableHeight = self.tableChangedValue["Height"] tableWidth = self.tableChangedValue["Width"] self.tblView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.tblView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) hHeder = self.tblView.horizontalHeader() hHeder.setVisible(False) vHeder = self.tblView.verticalHeader() vHeder.setVisible(False) # if flag: self.stdModel = QStandardItemModel() self.data.__setitem__("TableWidth", tableWidth) self.data.__setitem__("TableHeight", tableHeight) self.setTableView(self.tblView, self.stdModel, self.data) self.calcALT() self.calcTimeRate() self.gpw = QGraphicsProxyWidget() self.gpw.setWidget(self.tblView) # gpw.setWidget(tblView) if self.tableChangedValue == None: self.gpw.setPos(20, 210) font = QFont() font.setPixelSize(2) self.gpw.setFont(font) else: self.gpw.setPos(self.tableChangedValue["X"], self.tableChangedValue["Y"]) font = QFont() font.setPixelSize(self.tableChangedValue["FontSize"]) self.gpw.setFont(font) # tblView.setFrameRect(QRect(20, 210, paperWidth - 40, 50)) comp.addItem(self.gpw) self.connect(self.stdModel, SIGNAL("itemChanged(QStandardItem *)"), self.stdModel_itemChanged) return comp def setTableView(self, tblView, stdModel, data): for i in range(7): for j in range(12 + data["CatOfAcftCount"][0]): item = QStandardItem("") item.setEditable(True) item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(i, j, item) item = QStandardItem("O C A ( H )") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(0, 0, item) item = QStandardItem("C a t of A C F T") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 0, item) item = QStandardItem("S t r a i g h t-I n A p p r o a c h") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(2, 0, item) if data["Template"][0] >= 0 and data["Template"][0] <= 4: item = QStandardItem("C i r c l i n g") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(4, 0, item) item = QStandardItem( "F i n a l A p p r o a c h L O C D i s t a n c e F A F-M A P t" ) item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(0, data["CatOfAcftCount"][0] + 3, item) else: item = QStandardItem("F i n a l A p p r o a c h F A F-M A P t") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(0, data["CatOfAcftCount"][0] + 3, item) if data["Template"][0] == 5: item = QStandardItem("LPV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(2, 0, item) item = QStandardItem("LNAV / VNAV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, 0, item) item = QStandardItem("LNAV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(4, 0, item) item = QStandardItem("C i r c l i n g") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(5, 0, item) elif data["Template"][0] == 6: item = QStandardItem("LNAV / VNAV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(2, 0, item) item = QStandardItem("LNAV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, 0, item) item = QStandardItem("C i r c l i n g") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(4, 0, item) elif data["Template"][0] == 7: item = QStandardItem("LPV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(2, 0, item) item = QStandardItem("LNAV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, 0, item) item = QStandardItem("C i r c l i n g") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(4, 0, item) elif data["Template"][0] == 8: item = QStandardItem("LNAV") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(2, 0, item) item = QStandardItem("C i r c l i n g") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, 0, item) elif data["Template"][0] == 9: item = QStandardItem("RNP 0.3") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(2, 0, item) item = QStandardItem("C i r c l i n g") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, 0, item) if data["CatOfAcftCount"][0] == 1: item = QStandardItem("A") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 3, item) elif data["CatOfAcftCount"][0] == 2: item = QStandardItem("A") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 3, item) item = QStandardItem("B") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 4, item) elif data["CatOfAcftCount"][0] == 3: item = QStandardItem("A") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 3, item) item = QStandardItem("B") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 4, item) item = QStandardItem("C") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 5, item) elif data["CatOfAcftCount"][0] == 4: item = QStandardItem("A") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 3, item) item = QStandardItem("B") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 4, item) item = QStandardItem("C") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 5, item) item = QStandardItem("D") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 6, item) elif data["CatOfAcftCount"][0] == 5: if data["CatOfAcftCount"][1] == 4: item = QStandardItem("A") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 3, item) item = QStandardItem("B") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 4, item) item = QStandardItem("C") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 5, item) item = QStandardItem("D") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 6, item) item = QStandardItem("DL") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 7, item) else: item = QStandardItem("A") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 3, item) item = QStandardItem("B") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 4, item) item = QStandardItem("C") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 5, item) item = QStandardItem("D") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 6, item) item = QStandardItem("E") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 7, item) elif data["CatOfAcftCount"][0] == 6: item = QStandardItem("A") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 3, item) item = QStandardItem("B") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 4, item) item = QStandardItem("C") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 5, item) item = QStandardItem("D") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 6, item) item = QStandardItem("DL") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 7, item) item = QStandardItem("E") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, 8, item) # item = QStandardItem("DME MX NM") # item.setTextAlignment(Qt.AlignCenter) # stdModel.setItem(1, 6, item) item = QStandardItem("DME SSA") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, data["CatOfAcftCount"][0] + 3, item) item = QStandardItem("6") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, data["CatOfAcftCount"][0] + 5, item) item = QStandardItem("5") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, data["CatOfAcftCount"][0] + 6, item) item = QStandardItem("4") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, data["CatOfAcftCount"][0] + 7, item) item = QStandardItem("3") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, data["CatOfAcftCount"][0] + 8, item) item = QStandardItem("2") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, data["CatOfAcftCount"][0] + 9, item) item = QStandardItem("1") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(1, data["CatOfAcftCount"][0] + 10, item) item = QStandardItem("A L T(HGT)") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(2, data["CatOfAcftCount"][0] + 3, item) item = QStandardItem("G S") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 3, item) item = QStandardItem("kt") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 5, item) item = QStandardItem("80") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 6, item) item = QStandardItem("100") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 7, item) item = QStandardItem("120") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 8, item) item = QStandardItem("140") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 9, item) item = QStandardItem("160") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 10, item) item = QStandardItem("180") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(3, data["CatOfAcftCount"][0] + 11, item) item = QStandardItem("T i me") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(4, data["CatOfAcftCount"][0] + 3, item) item = QStandardItem("mi n:s") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(4, data["CatOfAcftCount"][0] + 5, item) item = QStandardItem("Rate Of D e s c e n t") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(5, data["CatOfAcftCount"][0] + 3, item) item = QStandardItem("ft/mi n") item.setTextAlignment(Qt.AlignCenter) stdModel.setItem(5, data["CatOfAcftCount"][0] + 5, item) tblView.setModel(stdModel) for i in range(7): tblView.setRowHeight(i, int(data["TableHeight"] / 7)) for j in range(12 + data["CatOfAcftCount"][0]): tblView.setColumnWidth( j, int(data["TableWidth"] / float(12 + data["CatOfAcftCount"][0]))) # tblView.setColumnWidth(0, 25) # tblView.setColumnWidth(6, 20) tblView.setSpan(0, 0, 1, data["CatOfAcftCount"][0] + 3) tblView.setSpan(1, 0, 1, 3) if data["Template"][0] >= 0 and data["Template"][0] <= 4: tblView.setSpan(2, 0, 1, 3) tblView.setSpan(2, 3, 1, data["CatOfAcftCount"][0]) tblView.setSpan(3, 0, 1, data["CatOfAcftCount"][0] + 3) tblView.setSpan(4, 0, 1, 3) tblView.setSpan(5, 0, 1, 3) tblView.setSpan(6, 0, 1, 3) else: tblView.setSpan(2, 0, 1, 3) tblView.setSpan(3, 0, 1, 3) tblView.setSpan(4, 0, 1, 3) tblView.setSpan(5, 0, 1, 3) tblView.setSpan(6, 0, 1, 3) # tblView.setSpan(data["StraightCount"] + 2, 0, 1, 3) tblView.setSpan(0, data["CatOfAcftCount"][0] + 3, 1, 9) # tblView.setSpan(1, data["CatOfAcftCount"][0] + 4, 1, 5) # tblView.setSpan(1, data["CatOfAcftCount"][0] + 9, 1, 3) # tblView.setSpan(2, data["CatOfAcftCount"][0] + 5, 1, 4) # tblView.setSpan(2, data["CatOfAcftCount"][0] + 9, 1, 3) tblView.setSpan(1, data["CatOfAcftCount"][0] + 3, 1, 2) tblView.setSpan(2, data["CatOfAcftCount"][0] + 3, 1, 2) tblView.setSpan(3, data["CatOfAcftCount"][0] + 3, 1, 2) tblView.setSpan(4, data["CatOfAcftCount"][0] + 3, 1, 2) tblView.setSpan(5, data["CatOfAcftCount"][0] + 3, 1, 2) tblView.setSpan(6, data["CatOfAcftCount"][0] + 3, 1, 2) def stdModel_itemChanged(self, item): if item.row() != 1 and item.row() != 3: return self.calcTimeRate() self.calcALT() def calcALT(self): thrAlt = Unit.ConvertFeetToMeter(self.data["ThrAltitude"]) rdhAlt = Unit.ConvertFeetToMeter(self.data["RDHAltitude"]) gradient = self.data["DescentGradient"] dx = self.data["dX"] for i in range(7): item = self.stdModel.item(1, self.data["CatOfAcftCount"][0] + 5 + i) val = 0.0 try: val = float(item.text()) except: continue dist = val * 1852 valueHgt = Unit.ConvertFeetToMeter( (dist - dx) * math.tan(Unit.ConvertDegToRad(gradient))) valueAlt = valueHgt + thrAlt + rdhAlt if valueAlt > int(valueAlt): valueAlt = int(valueAlt) + 1 if valueHgt > int(valueHgt): valueHgt = int(valueHgt) + 1 itemTemp = QStandardItem( str(valueAlt) + "\n(" + str(valueHgt) + ")") itemTemp.setTextAlignment(Qt.AlignCenter) self.stdModel.setItem(2, self.data["CatOfAcftCount"][0] + 5 + i, itemTemp) def calcTimeRate(self): for i in range(6): item = self.stdModel.item(3, self.data["CatOfAcftCount"][0] + 6 + i) val = 0.0 try: val = float(item.text()) except: continue time = (3600 * self.data["Distance"]) / val minute = int(time / 60) second = int(time % 60) timeStr = str(minute) + " : " + str(second) if second == 0: timeStr = str(minute) + " : " + "00" elif second < 10: timeStr = str(minute) + " : 0" + str(second) itemTemp = QStandardItem(timeStr) itemTemp.setTextAlignment(Qt.AlignCenter) self.stdModel.setItem(4, self.data["CatOfAcftCount"][0] + 6 + i, itemTemp) rate = int( (val * 6076.1 * (AngleGradientSlope(self.data["DescentGradient"]).Percent / float(100))) / float(60)) itemTemp = QStandardItem(str(rate)) itemTemp.setTextAlignment(Qt.AlignCenter) self.stdModel.setItem(5, self.data["CatOfAcftCount"][0] + 6 + i, itemTemp)
class CandidateCrawlerUI(object): def setupUi(self, MainWindow): self.centralwidget = QtGui.QWidget(MainWindow) self.qbox = QBoxLayout(QBoxLayout.TopToBottom, self.centralwidget) self.centralwidget.setLayout(self.qbox) #####Mots-clés### self.keywords_label = QtGui.QLabel(self.centralwidget) self.keywords_label.setText(_translate("AdminWindow", "Mots-clés de recherche", None)) self.keywords_help = QtGui.QPushButton(self.centralwidget) self.keywords_help.setIcon(QIcon('./share/icon/point interrogation.png')) self.keywords_help.setIconSize(QSize(10,10)) self.hbox_keywords = QtGui.QHBoxLayout() self.hbox_keywords.addWidget(self.keywords_label) self.hbox_keywords.addWidget(self.keywords_help) self.hbox_keywords.setContentsMargins(0, 0, 120, 0) self.keywords_entry = QtGui.QLineEdit(self.centralwidget) self.vbox_keywords = QtGui.QVBoxLayout() self.vbox_keywords.addLayout(self.hbox_keywords) self.vbox_keywords.addWidget(self.keywords_entry) self.vbox_keywords.setContentsMargins(0, 0, 0, 5) ###Région### self.region_label = QtGui.QLabel(self.centralwidget) self.region_label.setText(_translate("AdminWindow", "Région (5 choix maximum)", None)) self.region_list = QtGui.QListView(self.centralwidget) self.vbox_region = QtGui.QVBoxLayout() self.vbox_region.addWidget(self.region_label) self.vbox_region.addWidget(self.region_list) self.vbox_region.setContentsMargins(0, 0, 0, 5) ###Mobilité### self.mobilite_label = QtGui.QLabel(self.centralwidget) self.mobilite_label.setText(_translate("AdminWindow", "Mobilité", None)) self.mobilite_combobox = QtGui.QComboBox(self.centralwidget) self.vbox_mobilite = QtGui.QVBoxLayout() self.vbox_mobilite.addWidget(self.mobilite_label) self.vbox_mobilite.addWidget(self.mobilite_combobox) self.vbox_mobilite.setContentsMargins(0, 0, 0, 5) ###Salaire### self.salaire_label = QtGui.QLabel(self.centralwidget) self.salaire_label.setText(_translate("AdminWindow", "Salaire", None)) self.salaire_combobox = QtGui.QComboBox(self.centralwidget) self.vbox_salaire = QtGui.QVBoxLayout() self.vbox_salaire.addWidget(self.salaire_label) self.vbox_salaire.addWidget(self.salaire_combobox) self.vbox_salaire.setContentsMargins(0, 0, 0, 5) ###Disponibilité### self.disponibilite_label = QtGui.QLabel(self.centralwidget) self.disponibilite_label.setText(_translate("AdminWindow", "Disponibilité", None)) self.disponibilite_list = QtGui.QListView(self.centralwidget) self.vbox_disponibilite = QtGui.QVBoxLayout() self.vbox_disponibilite.addWidget(self.disponibilite_label) self.vbox_disponibilite.addWidget(self.disponibilite_list) self.vbox_disponibilite.setContentsMargins(0, 0, 0, 5) ###Fraîcheur### self.fraicheur_label = QtGui.QLabel(self.centralwidget) self.fraicheur_label.setText(_translate("AdminWindow", "Fraîcheur", None)) self.fraicheur_combobox = QtGui.QComboBox(self.centralwidget) self.vbox_fraicheur = QtGui.QVBoxLayout() self.vbox_fraicheur.addWidget(self.fraicheur_label) self.vbox_fraicheur.addWidget(self.fraicheur_combobox) self.vbox_fraicheur.setContentsMargins(0, 0, 0, 5) ###Nombre de CVs### self.cv_number_label = QtGui.QLabel(self.centralwidget) self.cv_number_label.setText(_translate("AdminWindow", "Nombre de CV", None)) self.cv_number_entry = QtGui.QLineEdit(self.centralwidget) self.cv_number_entry.setInputMethodHints(QtCore.Qt.ImhNone) self.cv_number_entry.setText("50") self.vbox_cv_number = QtGui.QVBoxLayout() self.vbox_cv_number.addWidget(self.cv_number_label) self.vbox_cv_number.addWidget(self.cv_number_entry) self.vbox_cv_number.setContentsMargins(0, 0, 0, 5) ###Progression### self.progression_label = QtGui.QLabel(self.centralwidget) self.progression_label.setText(_translate("AdminWindow", "Progression", None)) self.progression_text = QtGui.QTextBrowser(self.centralwidget) self.vbox_progression = QtGui.QVBoxLayout() self.vbox_progression.addWidget(self.progression_label) self.vbox_progression.addWidget(self.progression_text) self.vbox_progression.setContentsMargins(0, 0, 0, 5) ###Bouton de lancement### self.run_button = QtGui.QPushButton(self.centralwidget) self.run_button.setText(_translate("AdminWindow", "Lancer la recherche", None)) ###Ajout a la fenetre principale### self.qbox.addLayout(self.vbox_keywords) self.qbox.addLayout(self.vbox_region) self.qbox.addLayout(self.vbox_mobilite) self.qbox.addLayout(self.vbox_salaire) self.qbox.addLayout(self.vbox_disponibilite) self.qbox.addLayout(self.vbox_fraicheur) self.qbox.addLayout(self.vbox_cv_number) self.qbox.addLayout(self.vbox_progression) self.qbox.addWidget(self.run_button) MainWindow.setCentralWidget(self.centralwidget) ###Barre de menu### MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menuFichier = QtGui.QMenu(self.menubar) self.menuEdition = QtGui.QMenu(self.menubar) self.menuAide = QtGui.QMenu(self.menubar) MainWindow.setMenuBar(self.menubar) self.about_action = QtGui.QAction(MainWindow) self.admin_action = QtGui.QAction(MainWindow) self.exit_action = QtGui.QAction(MainWindow) self.menuFichier.addAction(self.admin_action) self.menuFichier.addAction(self.exit_action) self.menuAide.addAction(self.about_action) self.menubar.addAction(self.menuFichier.menuAction()) self.menubar.addAction(self.menuAide.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) # Values for combobox staticsxmlfile = "statics.xml" region_list = tuple(toolbox.xml_reader(staticsxmlfile, "regions").split(',')) mobilite_list = tuple(toolbox.xml_reader(staticsxmlfile, "mobilite").split(',')) salaire_list = tuple(toolbox.xml_reader(staticsxmlfile, "salaire").split(',')) disponibilite_list = tuple(toolbox.xml_reader(staticsxmlfile, "disponibilite").split(',')) fraicheur_list = tuple(toolbox.xml_reader(staticsxmlfile, "fraicheur").split(',')) self.model = QStandardItemModel(self.region_list) for region in region_list: item = QStandardItem(region) item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole) self.model.appendRow(item) self.region_list.setModel(self.model) self.model2 = QStandardItemModel(self.disponibilite_list) for disponibilite in disponibilite_list: item = QStandardItem(disponibilite) item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole) self.model2.appendRow(item) self.disponibilite_list.setModel(self.model2) for element in mobilite_list: self.mobilite_combobox.addItem(element) for element in salaire_list: self.salaire_combobox.addItem(element) for element in fraicheur_list: self.fraicheur_combobox.addItem(element) # Action attached to buttons #################################################################### self.about_action.triggered.connect(self.about_window) self.admin_action.triggered.connect(self.admin_window) self.exit_action.triggered.connect(self.close) self.run_button.clicked.connect(self.run_program) self.keywords_help.clicked.connect(self.ouvrirDialogue) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "Candidate Crawler APEC", None)) self.menuFichier.setTitle(_translate("MainWindow", "Fichier", None)) self.menuAide.setTitle(_translate("MainWindow", "Aide", None)) self.about_action.setText(_translate("MainWindow", "A propos", None)) self.admin_action.setText(_translate("MainWindow", "Administration", None)) self.exit_action.setText(_translate("MainWindow", "Quitter", None)) # Methods for class CandidateCrawlerUI def about_window(self): """Method to generate About window""" self.about_w = About_window.AboutWindowGUI() self.about_w.show() def admin_window(self): """Method to generate About window""" self.admin_w = Admin_window.AdminWindowGUI() self.admin_w.show() def reset(self): """Method to reset main window""" self.progression_text.clear() def close(self): """Method to close main window""" self.close() def ouvrirDialogue(self): QMessageBox.information(self, self.trUtf8("Aide mots-clés"),self.trUtf8("Vous pouvez entrer plusieurs mots-clés, sans accents, en les séparant par des espaces.")) def _entries_retriever(self): """Method to get user entries""" self.keywords = self.trUtf8(self.keywords_entry.text()) self.region = [] for row in range(self.model.rowCount()): item = self.model.item(row) if item.checkState() == QtCore.Qt.Checked: self.region = [str(item.text())]+self.region self.mobilite = self.mobilite_combobox.currentText() self.salaire = self.salaire_combobox.currentText() self.disponibilite = [] for row in range(self.model2.rowCount()): item = self.model2.item(row) if item.checkState() == QtCore.Qt.Checked: self.disponibilite = [str(item.text())]+self.disponibilite self.fraicheur = self.fraicheur_combobox.currentText() self.nombreCV = self.trUtf8(self.cv_number_entry.text()) def _entries_checker(self): """Method to check user entries""" error_code = False error_list = [] if self.keywords[0] == "": error_code = True error_list.append(_translate("MainWindow", "Veuillez entrer des mots-clés", None)) if self.nombreCV[0] == "": error_code = True error_list.append(_translate("MainWindow", "Veuillez entrer un nombre de CVs", None)) return error_code, error_list def run_program(self): """Method to run program on tab1: ponctual search""" self.progression_text.append("Lancement du programme") self.progression_text.append("Programme en cours ...") app.processEvents() # Window refresh try: self._entries_retriever() if self._entries_checker()[0]: self.progression_text.setTextColor(QtGui.QColor("red")) for element in self._entries_checker()[1]: self.progression_text.append(element) self.progression_text.setTextColor(QtGui.QColor("black")) self.progression_text.append(_translate("MainWindow", "Programme stoppé", None)) return runapp = core.CandidateCrawlerCore(toolbox.getconfigvalue("APEC", "login"), toolbox.getconfigvalue("APEC", "password"),self.keywords, self.region , self.mobilite, self.salaire, self.disponibilite, self.fraicheur, self.nombreCV) print(self.keywords) print(self.region) print(self.mobilite) print(self.salaire) print(self.disponibilite) print(self.fraicheur) print(self.nombreCV) runapp.crawl() self.progression_text.append(self.trUtf8("Fin du programme\n")) except: self.progression_text.append(self.trUtf8("Oups, quelque chose s'est mal passé")) self.progression_text.append(self.trUtf8("Veuillez vérifier les champs de l'adiministration")) self.progression_text.append(self.trUtf8("Fin du programme\n")) raise
class QtWidgetRegistry(QObject, WidgetRegistry): """ A QObject wrapper for `WidgetRegistry` A QStandardItemModel instance containing the widgets in a tree (of depth 2). The items in a model can be quaries using standard roles (DisplayRole, BackgroundRole, DecorationRole ToolTipRole). They also have QtWidgetRegistry.CATEGORY_DESC_ROLE, QtWidgetRegistry.WIDGET_DESC_ROLE, which store Category/WidgetDescription respectfully. Furthermore QtWidgetRegistry.WIDGET_ACTION_ROLE stores an default QAction which can be used for widget creation action. """ CATEGORY_DESC_ROLE = Qt.UserRole + 1 """Category Description Role""" WIDGET_DESC_ROLE = Qt.UserRole + 2 """Widget Description Role""" WIDGET_ACTION_ROLE = Qt.UserRole + 3 """Widget Action Role""" BACKGROUND_ROLE = Qt.UserRole + 4 """Background color for widget/category in the canvas (different from Qt.BackgroundRole) """ category_added = Signal(str, CategoryDescription) """signal: category_added(name: str, desc: CategoryDescription) """ widget_added = Signal(str, str, WidgetDescription) """signal widget_added(category_name: str, widget_name: str, desc: WidgetDescription) """ reset = Signal() """signal: reset() """ def __init__(self, other_or_parent=None, parent=None): if isinstance(other_or_parent, QObject) and parent is None: parent, other_or_parent = other_or_parent, None QObject.__init__(self, parent) WidgetRegistry.__init__(self, other_or_parent) # Should the QStandardItemModel be subclassed? self.__item_model = QStandardItemModel(self) for i, desc in enumerate(self.categories()): cat_item = self._cat_desc_to_std_item(desc) self.__item_model.insertRow(i, cat_item) for j, wdesc in enumerate(self.widgets(desc.name)): widget_item = self._widget_desc_to_std_item(wdesc, desc) cat_item.insertRow(j, widget_item) def model(self): """ Return the widget descriptions in a Qt Item Model instance (QStandardItemModel). .. note:: The model should not be modified outside of the registry. """ return self.__item_model def item_for_widget(self, widget): """Return the QStandardItem for the widget. """ if isinstance(widget, str): widget = self.widget(widget) cat = self.category(widget.category) cat_ind = self.categories().index(cat) cat_item = self.model().item(cat_ind) widget_ind = self.widgets(cat).index(widget) return cat_item.child(widget_ind) def action_for_widget(self, widget): """ Return the QAction instance for the widget (can be a string or a WidgetDescription instance). """ item = self.item_for_widget(widget) return item.data(self.WIDGET_ACTION_ROLE) def create_action_for_item(self, item): """ Create a QAction instance for the widget description item. """ name = item.text() tooltip = item.toolTip() whatsThis = item.whatsThis() icon = item.icon() if icon: action = QAction(icon, name, self, toolTip=tooltip, whatsThis=whatsThis, statusTip=name) else: action = QAction(name, self, toolTip=tooltip, whatsThis=whatsThis, statusTip=name) widget_desc = item.data(self.WIDGET_DESC_ROLE) action.setData(widget_desc) action.setProperty("item", item) return action def _insert_category(self, desc): """ Override to update the item model and emit the signals. """ priority = desc.priority priorities = [c.priority for c, _ in self.registry] insertion_i = bisect.bisect_right(priorities, priority) WidgetRegistry._insert_category(self, desc) cat_item = self._cat_desc_to_std_item(desc) self.__item_model.insertRow(insertion_i, cat_item) self.category_added.emit(desc.name, desc) def _insert_widget(self, category, desc): """ Override to update the item model and emit the signals. """ assert (isinstance(category, CategoryDescription)) categories = self.categories() cat_i = categories.index(category) _, widgets = self._categories_dict[category.name] priorities = [w.priority for w in widgets] insertion_i = bisect.bisect_right(priorities, desc.priority) WidgetRegistry._insert_widget(self, category, desc) cat_item = self.__item_model.item(cat_i) widget_item = self._widget_desc_to_std_item(desc, category) cat_item.insertRow(insertion_i, widget_item) self.widget_added.emit(category.name, desc.name, desc) def _cat_desc_to_std_item(self, desc): """ Create a QStandardItem for the category description. """ item = QStandardItem() item.setText(desc.name) if desc.icon: icon = desc.icon else: icon = "icons/default-category.svg" icon = icon_loader.from_description(desc).get(icon) item.setIcon(icon) if desc.background: background = desc.background else: background = DEFAULT_COLOR background = NAMED_COLORS.get(background, background) brush = QBrush(QColor(background)) item.setData(brush, self.BACKGROUND_ROLE) tooltip = desc.description if desc.description else desc.name item.setToolTip(tooltip) item.setFlags(Qt.ItemIsEnabled) item.setData(desc, self.CATEGORY_DESC_ROLE) return item def _widget_desc_to_std_item(self, desc, category): """ Create a QStandardItem for the widget description. """ item = QStandardItem(desc.name) item.setText(desc.name) if desc.icon: icon = desc.icon else: icon = "icons/default-widget.svg" icon = icon_loader.from_description(desc).get(icon) item.setIcon(icon) # This should be inherited from the category. background = None if desc.background: background = desc.background elif category.background: background = category.background else: background = DEFAULT_COLOR if background is not None: background = NAMED_COLORS.get(background, background) brush = QBrush(QColor(background)) item.setData(brush, self.BACKGROUND_ROLE) tooltip = tooltip_helper(desc) style = "ul { margin-top: 1px; margin-bottom: 1px; }" tooltip = TOOLTIP_TEMPLATE.format(style=style, tooltip=tooltip) item.setToolTip(tooltip) item.setWhatsThis(whats_this_helper(desc)) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) item.setData(desc, self.WIDGET_DESC_ROLE) # Create the action for the widget_item action = self.create_action_for_item(item) item.setData(action, self.WIDGET_ACTION_ROLE) return item
class ModelAtrributesView(QListView): """ Custom QListView implementation that displays checkable model attributes. """ def __init__(self, parent=None, dataModel=None): QListView.__init__(self, parent) self._dataModel = dataModel self._selectedDisplayMapping = OrderedDict() self._attrModel = QStandardItemModel(self) def dataModel(self): """ Returns the data model instance. """ return self._dataModel def setDataModel(self, dataModel): """ Sets the data model. Should be a callable class rather than the class instance. """ if callable(dataModel): self._dataModel = dataModel else: self._dataModel = dataModel.__class__ def load(self): """ Load the model's attributes into the list view. """ if self._dataModel == None: return try: self._loadAttrs(self._dataModel.displayMapping()) except AttributeError: #Ignore error if model does not contain the displayMapping static method pass def _loadAttrs(self, attrMapping): """ Loads display mapping into the list view. """ self._attrModel.clear() self._attrModel.setColumnCount(2) for attrName, displayName in attrMapping.iteritems(): #Exclude row ID in the list, other unique identifier attributes in the model can be used if attrName != "id": displayNameItem = QStandardItem(displayName) displayNameItem.setCheckable(True) attrNameItem = QStandardItem(attrName) self._attrModel.appendRow([displayNameItem, attrNameItem]) self.setModel(self._attrModel) def selectedMappings(self): """ Return a dictionary of field names and their corresponding display values. """ selectedAttrs = {} for i in range(self._attrModel.rowCount()): displayNameItem = self._attrModel.item(i, 0) if displayNameItem.checkState() == Qt.Checked: attrNameItem = self._attrModel.item(i, 1) selectedAttrs[attrNameItem.text()] = displayNameItem.text() return selectedAttrs
class ImportUpdateDialog(QDialog, Ui_ImportUpdate): """ Class responsible for handling the update() function. """ def __init__(self, iface): QDialog.__init__(self) self.setupUi(self) self.iface = iface self.dbconn = DBConn(iface) self.get_attributes() self.set_importable_tables() def get_attributes(self): """Place excludable attributes in model list""" # Model Structure used from Tutorial at # http://pythoncentral.io/pyside-pyqt-tutorial-qlistview-and-qstandarditemmodel/ self.model = QStandardItemModel(self.listTblAttrib) self.hasGeometry = self.iface.activeLayer().hasGeometryType() self.provider = self.iface.activeLayer().dataProvider() fields = self.iface.activeLayer().pendingFields() for field in fields: item = QStandardItem(field.name()) item.setCheckable(True) self.model.appendRow(item) self.listTblAttrib.setModel(self.model) def get_checked_attributes(self): """Creates a list of checked elements to be excluded""" i = 0 exclList = list() while self.model.item(i): if self.model.item(i).checkState(): exclList.append(self.model.item(i).text()) i += 1 return exclList def set_importable_tables(self): """Populates combobox with importable tables Name Structure <schema.tablename>""" self.uri = QgsDataSourceURI(self.provider.dataSourceUri()) self.execute = SQLExecute( self.iface, self.iface.mainWindow(), self.uri) # Returns Result to be parsed schemaTableList = self.execute.retrieve_all_importable_tables() cmbList = list() if schemaTableList: for entry in schemaTableList: cmbEntry = entry[0] + '.' + entry[1] cmbList.append(cmbEntry) self.cmbImportTable.addItems(cmbList) @pyqtSignature("") def on_buttonBox_accepted(self): """ Run hist_tabs.update() SQL function with given parameters """ select = self.cmbImportTable.currentText() exclList = self.get_checked_attributes() # Split the user selection for querying splitString = select.split('.') importSchema = splitString[0] importTable = splitString[1] self.execute.update_table_entries( importSchema, importTable, self.uri.schema(), self.iface.activeLayer().name(), self.hasGeometry, exclList) @pyqtSignature("") def on_buttonBox_rejected(self): """ Slot documentation goes here. """ self.close()
class LogDialog(QDialogWithDpi): """LogDialog for the Freeseer project. It is the dialog window for the log. There is an instance for every FreeseerApp. It has a LogHandler which calls LogDialog's message() method when a new log message is received. The call to message() causes a call to add_entry() which adds the information to a new row in the table. """ def __init__(self, parent=None): super(LogDialog, self).__init__(parent) self.resize(800, 500) self.app = QApplication.instance() icon = QIcon() icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) layout = QVBoxLayout() self.setLayout(layout) self.level = 0 self.handler = LogHandler() self.table_model = QStandardItemModel(0, 5) header_names = ["Date", "Level", "Module", "Message", "LevelNo"] date_column = header_names.index("Date") level_column = header_names.index("Level") module_column = header_names.index("Module") self.level_num_column = header_names.index("LevelNo") self.table_model.setHorizontalHeaderLabels(header_names) self.table_view = QTableView() self.table_view.setModel(self.table_model) self.table_view.horizontalHeader().setStretchLastSection(True) self.table_view.setColumnWidth(date_column, self.set_width_with_dpi(125)) self.table_view.setColumnWidth(level_column, self.set_width_with_dpi(60)) self.table_view.setColumnWidth(module_column, self.set_width_with_dpi(250)) self.table_view.setColumnHidden(self.level_num_column, True) self.table_view.setShowGrid(False) self.table_view.horizontalHeader().setClickable(False) self.table_view.verticalHeader().hide() self.table_view.setStyleSheet("""Qtable_view::item { border-bottom: 1px solid lightgrey; selection-background-color: white; selection-color: black; }""") top_panel = QHBoxLayout() self.log_levels = ["Debug", "Info", "Warning", "Error"] self.level_colors = ["#3E4C85", "#269629", "#B0AB21", "#B32020"] self.levels_label = QLabel("Filter Level: ") self.levels_label.setStyleSheet("QLabel { font-weight: bold }") self.current_level_label = QLabel(self.log_levels[0]) self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format( self.level_colors[0])) self.clear_button = QPushButton("Clear Log") self.levels_slider = QSlider(Qt.Horizontal) self.levels_slider.setStyleSheet(""" QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FFFFFF, stop:1 #E3E3E3); border: 1px solid #707070; width: 10px; margin-top: -4px; margin-bottom: -4px; border-radius: 4px; } QSlider::handle:horizontal:hover { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #DEDEDE, stop:1 #C9C9C9); border: 1px solid #4F4F4F; border-radius: 4px; } QSlider::sub-page:horizontal { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #BFBFBF, stop: 1 #9E9E9E); background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1, stop: 0 #9E9E9E, stop: 1 #858585); border: 1px solid #777; height: 10px; border-radius: 4px; } QSlider::add-page:horizontal { background: #fff; border: 1px solid #707070; height: 10px; border-radius: 4px; }""") self.levels_slider.setRange(0, len(self.log_levels) - 1) self.levels_slider.setTickPosition(QSlider.TicksBelow) self.levels_slider.setTickInterval(1) top_panel.addSpacerItem(self.qspacer_item_with_dpi(10, 0)) top_panel.addWidget(self.levels_label, 3) top_panel.addWidget(self.current_level_label, 2) top_panel.addWidget(self.levels_slider, 8) top_panel.addSpacerItem(self.qspacer_item_with_dpi(25, 0)) top_panel.addWidget(self.clear_button, 10) layout.addLayout(top_panel) layout.addWidget(self.table_view) self.connect(self.clear_button, SIGNAL('clicked()'), functools.partial(self.table_model.setRowCount, 0)) self.connect(self.levels_slider, SIGNAL('valueChanged(int)'), self.slider_set_level) self.setWindowTitle("Log") self.handler.add_listener(self) def __del__(self): self.handler.remove_listener(self) def retranslate(self): self.setWindowTitle(self.app.translate("LogDialog", "Log")) self.clear_button.setText(self.app.translate("LogDialog", "Clear Log")) self.levels_label.setText("{}: ".format( self.app.translate("LogDialog", "Filter Level"))) def message(self, message): """Passes the log fields to add_entry() It is called by LogHandler when a log message is received""" self.add_entry(message["time"], message["level"], message["full_module_name"], message["message"], str(message["levelno"])) def add_entry(self, date, level, module, message, levelno): """Adds the given fields to a new row in the log table It is called by message() when a log message is received""" items = [ QStandardItem(date), QStandardItem(level), QStandardItem(module), QStandardItem(message), QStandardItem(levelno) ] for item in items: item.setEditable(False) self.table_model.appendRow(items) def slider_set_level(self, level): self.current_level_label.setText(self.log_levels[level]) self.current_level_label.setStyleSheet("QLabel {{ color: {} }}".format( self.level_colors[level])) self.set_level(level + 1) def set_level(self, level): """Sets the current level of the LogDialog. Level is based on the selection made in the levels_combo_box. It hides all messages with a lower level.""" self.level = level * 10 for i in range(self.table_model.rowCount()): if int(str(self.table_model.item( i, self.level_num_column).text())) < self.level: self.table_view.setRowHidden(i, True) else: self.table_view.setRowHidden(i, False)
class MultipleSelectTreeView(QListView): """ Custom QListView implementation that displays checkable items from a multiple select column type. """ def __init__(self, column, parent=None): """ Class constructor. :param column: Multiple select column object. :type column: MultipleSelectColumn :param parent: Parent widget for the control. :type parent: QWidget """ QListView.__init__(self, parent) #Disable editing of lookup values self.setEditTriggers(QAbstractItemView.NoEditTriggers) self.column = column self._item_model = QStandardItemModel(self) self._value_list = self.column.value_list #Stores lookup objects based on primary keys self._lookup_cache = {} self._initialize() self._association = self.column.association self._first_parent_col = self._association.first_reference_column.name self._second_parent_col = self._association.second_reference_column.name #Association model self._assoc_cls = entity_model(self._association) def reset_model(self): """ Resets the item model. """ self._item_model.clear() self._item_model.setColumnCount(2) def clear(self): """ Clears all items in the model. """ self._item_model.clear() @property def association(self): """ :return: Returns the association object corresponding to the column. :rtype: AssociationEntity """ return self._association @property def value_list(self): """ :return: Returns the ValueList object corresponding to the configured column object. :rtype: ValueList """ return self._value_list @property def item_model(self): """ :return: Returns the model corresponding to the checkable items. :rtype: QStandardItemModel """ return self._item_model def _add_item(self, id, value): """ Adds a row corresponding to id and corresponding value from a lookup table. :param id: Primary key of a lookup record. :type id: int :param value: Lookup value :type value: str """ value_item = QStandardItem(value) value_item.setCheckable(True) id_item = QStandardItem(str(id)) self._item_model.appendRow([value_item, id_item]) def _initialize(self): #Populate list with lookup items self.reset_model() #Add all lookup values in the value list table vl_cls = entity_model(self._value_list) if not vl_cls is None: vl_obj = vl_cls() res = vl_obj.queryObject().all() for r in res: self._lookup_cache[r.id] = r self._add_item(r.id, r.value) self.setModel(self._item_model) def clear_selection(self): """ Unchecks all items in the view. """ for i in range(self._item_model.rowCount()): value_item = self._item_model.item(i, 0) if value_item.checkState() == Qt.Checked: value_item.setCheckState(Qt.Unchecked) if value_item.rowCount() > 0: value_item.removeRow(0) def selection(self): """ :return: Returns a list of selected items. :rtype: list """ selection = [] for i in range(self._item_model.rowCount()): value_item = self._item_model.item(i, 0) if value_item.checkState() == Qt.Checked: id_item = self._item_model.item(i, 1) id = int(id_item.text()) #Get item from the lookup cache and append to selection if id in self._lookup_cache: lookup_rec = self._lookup_cache[id] selection.append(lookup_rec) return selection def set_selection(self, models): """ Checks items corresponding to the specified models. :param models: List containing model values in the view for selection. :type models: list """ for m in models: search_value = m.value v_items = self._item_model.findItems(search_value) #Loop through result and check items for vi in v_items: if vi.checkState() == Qt.Unchecked: vi.setCheckState(Qt.Checked)
class DefaultsDlg(QDialog, Ui_Dialog): """ Class documentation goes here. """ def __init__(self, defaults, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super().__init__(parent) self.setupUi(self) self.setAttribute(Qt.WA_DeleteOnClose) self.defaults = defaults self.fillScalars() self.fillPlots() self.fillCalculations() def updateDefaults(self): self.defaults['defaultScalars'] = self.setDefaultScalars() self.defaults['defaultPlots'] = self.setDefaultPlots() self.defaults['defaultCalculations'] = self.setDefaultCalculations() def fillScalars(self): scalars = [ 'absorbance (%)', 'reflectance (%)', 'transmittance (%)', 'absorbance (mA/cm²)', 'reflectance (mA/cm²)', 'transmittance (mA/cm²)', 'generation', 'Jmax (mA/cm²)', 'absorption layerwise (%)', 'absorption layerwise (mA/cm²)', 'collection layerwise (%)', 'collection layerwise (mA/cm²)', 'calc. time (s)' ] self.scalarListModel = QStandardItemModel() scalarsToShow = self.defaults['defaultScalars'] for value in scalars: item = QStandardItem(value) check = Qt.Checked if value in scalarsToShow else Qt.Unchecked item.setCheckState(check) item.setCheckable(True) self.scalarListModel.appendRow(item) self.scalarListView.setModel(self.scalarListModel) def setDefaultScalars(self): setVisible = [] for row in range(self.scalarListModel.rowCount()): item = self.scalarListModel.item(row) if item.checkState() == Qt.Checked: setVisible.append(item.text()) return setVisible def fillPlots(self): plots = [ 'total A,R,T', # requires calc [0] 'Ellipsometry', # requires nothing 'absorption (layerwise)', # requires calc [2] 'collection (layerwise)', # requires calc [2] 'QE', # requires calc [2] 'reflection (interfacewise)', 'generation' # requires calc [3] ] self.plotListModel = QStandardItemModel() plotsToShow = self.defaults['defaultPlots'] for value in plots: item = QStandardItem(value) check = Qt.Checked if value in plotsToShow else Qt.Unchecked item.setCheckState(check) item.setCheckable(True) self.plotListModel.appendRow(item) self.plotListView.setModel(self.plotListModel) def setDefaultPlots(self): setVisible = [] for row in range(self.plotListModel.rowCount()): item = self.plotListModel.item(row) if item.checkState() == Qt.Checked: setVisible.append(item.text()) return setVisible def fillCalculations(self): self.calculations = [ 'Stack optics (A,R,T)', 'Ellipsometry', 'Field intensity', 'Layerwise optics (absorption, collection, QE)', 'Generation' ] self.calcListModel = QStandardItemModel() calculationsToShow = self.defaults['defaultCalculations'] for value in self.calculations: item = QStandardItem(value) check = Qt.Checked if value in calculationsToShow else Qt.Unchecked item.setCheckState(check) item.setCheckable(True) #item.setEnabled(False) self.calcListModel.appendRow(item) self.calculationsListView.setModel(self.calcListModel) def setDefaultCalculations(self): for row in range(self.calcListModel.rowCount()): item = self.calcListModel.item(row) if item.checkState() == Qt.Checked: highestRow = row setCalcOn = self.calculations[:highestRow + 1] return setCalcOn
class OWConfusionMatrix(widget.OWWidget): name = "Confusion Matrix" description = "Display confusion matrix constructed from results " \ "of evaluation of classifiers." icon = "icons/ConfusionMatrix.svg" priority = 1001 inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")] outputs = [("Selected Data", Orange.data.Table)] quantities = [ "Number of instances", "Proportion of predicted", "Proportion of actual" ] selected_learner = settings.Setting([]) selected_quantity = settings.Setting(0) append_predictions = settings.Setting(True) append_probabilities = settings.Setting(False) autocommit = settings.Setting(True) def __init__(self): super().__init__() self.data = None self.results = None self.learners = [] self.headers = [] box = gui.widgetBox(self.controlArea, "Learners") self.learners_box = gui.listBox(box, self, "selected_learner", "learners", callback=self._learner_changed) box = gui.widgetBox(self.controlArea, "Show") gui.comboBox(box, self, "selected_quantity", items=self.quantities, callback=self._update) box = gui.widgetBox(self.controlArea, "Select") gui.button(box, self, "Correct", callback=self.select_correct, autoDefault=False) gui.button(box, self, "Misclassified", callback=self.select_wrong, autoDefault=False) gui.button(box, self, "None", callback=self.select_none, autoDefault=False) self.outputbox = box = gui.widgetBox(self.controlArea, "Output") gui.checkBox(box, self, "append_predictions", "Predictions", callback=self._invalidate) gui.checkBox(box, self, "append_probabilities", "Probabilities", callback=self._invalidate) gui.auto_commit(self.controlArea, self, "autocommit", "Send Data", "Auto send is on") grid = QGridLayout() self.tablemodel = QStandardItemModel(self) view = self.tableview = QTableView( editTriggers=QTableView.NoEditTriggers) view.setModel(self.tablemodel) view.horizontalHeader().hide() view.verticalHeader().hide() view.horizontalHeader().setMinimumSectionSize(60) view.selectionModel().selectionChanged.connect(self._invalidate) view.setShowGrid(False) view.clicked.connect(self.cell_clicked) grid.addWidget(view, 0, 0) self.mainArea.layout().addLayout(grid) def sizeHint(self): return QSize(750, 490) def _item(self, i, j): return self.tablemodel.item(i, j) or QStandardItem() def _set_item(self, i, j, item): self.tablemodel.setItem(i, j, item) def set_results(self, results): """Set the input results.""" self.clear() self.warning([0, 1]) data = None if results is not None: if results.data is not None: data = results.data if data is not None and not data.domain.has_discrete_class: data = None results = None self.warning( 0, "Confusion Matrix cannot be used for regression results.") self.results = results self.data = data if data is not None: class_values = data.domain.class_var.values elif results is not None: raise NotImplementedError if results is not None: nmodels, ntests = results.predicted.shape self.headers = class_values + \ [unicodedata.lookup("N-ARY SUMMATION")] # NOTE: The 'learner_names' is set in 'Test Learners' widget. if hasattr(results, "learner_names"): self.learners = results.learner_names else: self.learners = [ "Learner #%i" % (i + 1) for i in range(nmodels) ] item = self._item(0, 2) item.setData("Predicted", Qt.DisplayRole) item.setTextAlignment(Qt.AlignCenter) item.setFlags(Qt.NoItemFlags) self._set_item(0, 2, item) item = self._item(2, 0) item.setData("Actual", Qt.DisplayRole) item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom) item.setFlags(Qt.NoItemFlags) self.tableview.setItemDelegateForColumn(0, gui.VerticalItemDelegate()) self._set_item(2, 0, item) self.tableview.setSpan(0, 2, 1, len(class_values)) self.tableview.setSpan(2, 0, len(class_values), 1) for i in (0, 1): for j in (0, 1): item = self._item(i, j) item.setFlags(Qt.NoItemFlags) self._set_item(i, j, item) for p, label in enumerate(self.headers): for i, j in ((1, p + 2), (p + 2, 1)): item = self._item(i, j) item.setData(label, Qt.DisplayRole) item.setData(QBrush(QColor(208, 208, 208)), Qt.BackgroundColorRole) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) self._set_item(i, j, item) hor_header = self.tableview.horizontalHeader() if len(' '.join(self.headers)) < 120: hor_header.setResizeMode(QHeaderView.ResizeToContents) else: hor_header.setDefaultSectionSize(60) self.tablemodel.setRowCount(len(class_values) + 3) self.tablemodel.setColumnCount(len(class_values) + 3) self.selected_learner = [0] self._update() def clear(self): self.results = None self.data = None self.tablemodel.clear() self.headers = [] # Clear learners last. This action will invoke `_learner_changed` # method self.learners = [] def select_correct(self): selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): index = self.tablemodel.index(i, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def select_wrong(self): selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): for j in range(i + 1, n): index = self.tablemodel.index(i, j) selection.select(index, index) index = self.tablemodel.index(j, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def select_none(self): self.tableview.selectionModel().clear() def cell_clicked(self, model_index): i, j = model_index.row(), model_index.column() if not i or not j: return n = self.tablemodel.rowCount() index = self.tablemodel.index selection = None if i == j == 1 or i == j == n - 1: selection = QItemSelection(index(2, 2), index(n - 1, n - 1)) elif i in (1, n - 1): selection = QItemSelection(index(2, j), index(n - 1, j)) elif j in (1, n - 1): selection = QItemSelection(index(i, 2), index(i, n - 1)) if selection is not None: self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def commit(self): if self.results is not None and self.data is not None \ and self.selected_learner: indices = self.tableview.selectedIndexes() indices = {(ind.row() - 2, ind.column() - 2) for ind in indices} actual = self.results.actual selected_learner = self.selected_learner[0] learner_name = self.learners[selected_learner] predicted = self.results.predicted[selected_learner] selected = [ i for i, t in enumerate(zip(actual, predicted)) if t in indices ] row_indices = self.results.row_indices[selected] extra = [] class_var = self.data.domain.class_var metas = self.data.domain.metas if self.append_predictions: predicted = numpy.array(predicted[selected], dtype=object) extra.append(predicted.reshape(-1, 1)) var = Orange.data.DiscreteVariable( "{}({})".format(class_var.name, learner_name), class_var.values) metas = metas + (var, ) if self.append_probabilities and \ self.results.probabilities is not None: probs = self.results.probabilities[selected_learner, selected] extra.append(numpy.array(probs, dtype=object)) pvars = [ Orange.data.ContinuousVariable("p({})".format(value)) for value in class_var.values ] metas = metas + tuple(pvars) X = self.data.X[row_indices] Y = self.data.Y[row_indices] M = self.data.metas[row_indices] row_ids = self.data.ids[row_indices] M = numpy.hstack((M, ) + tuple(extra)) domain = Orange.data.Domain(self.data.domain.attributes, self.data.domain.class_vars, metas) data = Orange.data.Table.from_numpy(domain, X, Y, M) data.ids = row_ids data.name = learner_name else: data = None self.send("Selected Data", data) def _invalidate(self): self.commit() def _learner_changed(self): # The selected learner has changed indices = self.tableview.selectedIndexes() self._update() selection = QItemSelection() for sel in indices: selection.select(sel, sel) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) self.commit() def _update(self): # Update the displayed confusion matrix if self.results is not None and self.selected_learner: index = self.selected_learner[0] cmatrix = confusion_matrix(self.results, index) colsum = cmatrix.sum(axis=0) rowsum = cmatrix.sum(axis=1) total = rowsum.sum() if self.selected_quantity == 0: value = lambda i, j: int(cmatrix[i, j]) elif self.selected_quantity == 1: value = lambda i, j: \ ("{:2.1f} %".format(100 * cmatrix[i, j] / colsum[i]) if colsum[i] else "N/A") elif self.selected_quantity == 2: value = lambda i, j: \ ("{:2.1f} %".format(100 * cmatrix[i, j] / rowsum[i]) if colsum[i] else "N/A") else: assert False for i, row in enumerate(cmatrix): for j, _ in enumerate(row): item = self._item(i + 2, j + 2) item.setData(value(i, j), Qt.DisplayRole) item.setToolTip("actual: {}\npredicted: {}".format( self.headers[i], self.headers[j])) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self._set_item(i + 2, j + 2, item) model = self.tablemodel font = model.invisibleRootItem().font() bold_font = QFont(font) bold_font.setBold(True) def sum_item(value): item = QStandardItem() item.setData(value, Qt.DisplayRole) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) item.setFont(bold_font) return item N = len(colsum) for i in range(N): model.setItem(N + 2, i + 2, sum_item(int(colsum[i]))) model.setItem(i + 2, N + 2, sum_item(int(rowsum[i]))) model.setItem(N + 2, N + 2, sum_item(int(total)))
class DirDocumentTypeSelector(QDialog): """ Dialog for selecting supporting documents from a given directory. Default filter searches for PDF files only. """ def __init__(self, dir, doc_types, parent=None, filters=None): super(DirDocumentTypeSelector, self).__init__(parent) self.setWindowTitle( self.tr('Documents in Folder') ) self._filters = filters # Use PDF as default filter if not self._filters: self._filters = ['*.pdf'] self._init_ui() self._dir = QDir(dir) self._dir.setNameFilters(self._filters) self._doc_types = doc_types self._attr_model = QStandardItemModel(self) self._sel_doc_types = OrderedDict() # Notification bar self._notif_bar = NotificationBar(self.vl_notif) self.resize(320, 350) # Load documents self.load_document_types() @property def selected_document_types(self): """ :return: Returns a dictionary of the document types and the corresponding file paths as selected by the user. :rtype: dict """ return self._sel_doc_types def _init_ui(self): # Draw UI widgets layout = QVBoxLayout() # Add layout for notification bar self.vl_notif = QVBoxLayout() layout.addLayout(self.vl_notif) self.lbl_info = QLabel() self.lbl_info.setObjectName('lbl_info') self.lbl_info.setText(self.tr( 'The selected document types have been found in the directory, ' 'check/uncheck to specify which ones to upload.' )) self.lbl_info.setWordWrap(True) layout.addWidget(self.lbl_info) self.lst_docs = QListView() layout.addWidget(self.lst_docs) self.lbl_warning = QLabel() self.lbl_warning.setTextFormat(Qt.RichText) self.lbl_warning.setText(self.tr( '<html><head/><body><p><span style=" font-style:italic;">' '* Previously uploaded documents will be replaced.</span></p>' '</body></html>' )) self.lbl_warning.setWordWrap(True) layout.addWidget(self.lbl_warning) self.btn_box = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) layout.addWidget(self.btn_box) self.setLayout(layout) # Connect signals self.btn_box.accepted.connect( self.set_selected_document_types ) self.btn_box.rejected.connect( self.reject ) def set_selected_document_types(self): """ Sets the collections of accepted document types and their corresponding file paths and accepts the dialog. """ self._sel_doc_types = OrderedDict() for i in range(self._attr_model.rowCount()): doc_type_item = self._attr_model.item(i, 0) if doc_type_item.checkState() == Qt.Checked: path_item = self._attr_model.item(i, 1) self._sel_doc_types[doc_type_item.text()] = path_item.text() if len(self._sel_doc_types) == 0: self._notif_bar.clear() msg = self.tr('No matching documents found or selected.') self._notif_bar.insertWarningNotification(msg) return self.accept() def load_document_types(self): """ Load all document types to the list view and enable/check the items for those types that have been found. """ self._attr_model.clear() self._attr_model.setColumnCount(2) file_infos = self._dir.entryInfoList( QDir.Readable | QDir.Files, QDir.Name ) # Index file info based on name idx_file_infos = {fi.completeBaseName().lower(): fi for fi in file_infos} for d in self._doc_types: doc_type_item = QStandardItem(d) doc_type_item.setCheckable(True) path_item = QStandardItem() item_enabled = False check_state = Qt.Unchecked dl = d.lower() if dl in idx_file_infos: item_enabled = True check_state = Qt.Checked path = idx_file_infos[dl].filePath() path_item.setText(path) doc_type_item.setToolTip(path) doc_type_item.setEnabled(item_enabled) doc_type_item.setCheckState(check_state) self._attr_model.appendRow([doc_type_item, path_item]) self.lst_docs.setModel(self._attr_model)
class QMapManager(QDialog): def __init__(self, config, parent=None): QDialog.__init__(self, parent) curdir = os.path.abspath(os.path.dirname(__file__)) PyQt4.uic.loadUi(os.path.join(curdir, 'manager.ui'), self) self.model = QStandardItemModel() self.projectsmodel = QStandardItemModel() self.projectlist.setModel(self.projectsmodel) self.clientlist.setModel(self.model) self.clientlist.selectionModel().selectionChanged.connect(self.update) self.installbutton.pressed.connect(self.installToClient) self.mapper = QDataWidgetMapper() self.mapper.setModel(self.model) self.mapper.addMapping(self.installpath, 1) self.config = config self.populateProjects() self.populateClients() def installToClient(self): index = self.clientlist.selectionModel().currentIndex() item = self.model.itemFromIndex(index) print "Deploying to " + item.text() build.deployTargetByName(item.text()) def update(self, selected, deselected): index = selected.indexes()[0] self.mapper.setCurrentModelIndex(index) item = self.model.itemFromIndex(index) settings = item.data() for row in xrange(0, self.projectsmodel.rowCount()): index = self.projectsmodel.index(row, 0) item = self.projectsmodel.itemFromIndex(index) item.setCheckState(Qt.Unchecked) projects = settings['projects'] for project in projects: if project == "All": i = 0 while self.projectsmodel.item(i): item = self.projectsmodel.item(i) item.setCheckState(Qt.Checked) i += 1 break projectitem = self.projectsmodel.findItems(project)[0] projectitem.setCheckState(Qt.Checked) def populateClients(self): row = 0 for client, settings in self.config['clients'].iteritems(): name = QStandardItem(client) name.setData(settings) path = QStandardItem(settings['path']) self.model.insertRow(row, [name, path]) row += 1 def populateProjects(self): row = 0 for project in getProjects(): projectitem = QStandardItem(project.name) projectitem.setCheckable(True) self.projectsmodel.insertRow(row, projectitem) row += 1
class PluginRepositoriesGUI(QWidget): PATH_COLUMN = 1 ACTIVE_COLUMN = 0 AUTO_UPDATE_COLUMN = 2 STATUS_COLUMN = 3 addRepository = pyqtSignal() checkForUpdates = pyqtSignal() def __init__(self, logger, parent): super(PluginRepositoriesGUI, self).__init__(parent) self.logger = logger self._gitHandler = GitHandler(logger) layout = QVBoxLayout(self) self._reposTable = QTreeView(self) self._reposTable.setIndentation(0) self._reposTable.header().setStretchLastSection(False) self._reposModel = QStandardItemModel(self._reposTable) self._initModel() self._reposTable.setModel(self._reposModel) self._reposTable.setSelectionMode(QTreeView.ExtendedSelection) self._reposTable.selectionModel().selectionChanged.connect(self._selectionChanged) layout.addWidget(self._reposTable) buttonLayout = QHBoxLayout() addButton = QPushButton("Add...") addButton.clicked.connect(self.addRepository) self._removeButton = QPushButton("Remove") self._removeButton.setEnabled(False) self._removeButton.clicked.connect(self._removeSelected) refreshButton = QPushButton("Check Status") refreshButton.clicked.connect(self.checkForUpdates) buttonLayout.addWidget(addButton) buttonLayout.addWidget(self._removeButton) buttonLayout.addWidget(refreshButton) layout.addLayout(buttonLayout) self._statusWidget = QWidget(self) self._statusWidget.setVisible(False) statusLayout = QHBoxLayout(self._statusWidget) statusLayout.setContentsMargins(0, 0, 0, 0) self._statusLabel = QLabel(self) statusLayout.addWidget(self._statusLabel) layout.addWidget(self._statusWidget) def clear(self): self._initModel() def _updateStatusItem(self, item, path, outdated=None, upToDate=None): # first check fresh results, then the ones from repositories if upToDate and path in upToDate: item.setText(upToDate[path]) if upToDate[path] == GitHandler.UP_TO_DATE_REASON: item.setData(QColor(0, 255, 0), Qt.DecorationRole) else: item.setData(QColor(255, 0, 0), Qt.DecorationRole) elif outdated and path in outdated: item.setText("Repository can be updated") item.setData(QColor(255, 215, 0), Qt.DecorationRole) elif get_settings().get_plugin_repositories().isUpToDate(path): item.setText("No updates (for details, check status)") item.setData(QColor(0, 255, 0), Qt.DecorationRole) elif get_settings().get_plugin_repositories().isOutdated(path): item.setText("Repository can be updated") item.setData(QColor(255, 215, 0), Qt.DecorationRole) else: item.setData(None, Qt.DecorationRole) def updateStatusItems(self, outdated=None, upToDate=None): for row in xrange(self._reposModel.rowCount()): path = convert_string(self._reposModel.item(row, self.PATH_COLUMN).data(Qt.DisplayRole).toString()) self._updateStatusItem(self._reposModel.item(row, self.STATUS_COLUMN), path, outdated, upToDate) def _initModel(self): from PyQt4.QtCore import QStringList self._reposModel.clear() stringList = QStringList([u"Active", u"Path", u"Auto Update", u"Status"]) self._reposModel.setColumnCount(stringList.count()) self._reposModel.setHorizontalHeaderLabels(stringList) def appendRepository(self, path, active, autoUpdate, canAutoUpdate = None): activeItem = QStandardItem() activeItem.setEditable(False) activeItem.setCheckState(Qt.Checked if active else Qt.Unchecked) activeItem.setCheckable(True) pathItem = QStandardItem() pathItem.setData(path, Qt.DisplayRole) pathItem.setEditable(False) autoUpdateItem = QStandardItem() autoUpdateItem.setEditable(False) if canAutoUpdate == None: canAutoUpdate = self._gitHandler.hasGit(path) if canAutoUpdate: autoUpdateItem.setCheckState(Qt.Checked if autoUpdate else Qt.Unchecked) autoUpdateItem.setCheckable(True) statusItem = QStandardItem() self._updateStatusItem(statusItem, path) self._reposModel.appendRow([activeItem, pathItem, autoUpdateItem, statusItem]) def resizeColumns(self): self._reposTable.resizeColumnToContents(self.ACTIVE_COLUMN) self._reposTable.resizeColumnToContents(self.AUTO_UPDATE_COLUMN) self._reposTable.header().setResizeMode(self.PATH_COLUMN, QHeaderView.Stretch) self._reposTable.header().setResizeMode(self.STATUS_COLUMN, QHeaderView.ResizeToContents) def getTable(self): return self._reposTable @loggingSlot(QItemSelection, QItemSelection) def _selectionChanged(self, _sel, _desel): selection = self._reposTable.selectionModel().selectedRows() self._removeButton.setEnabled(len(selection) > 0) @loggingSlot() def _removeSelected(self): selection = self._reposTable.selectionModel().selectedRows() for index in selection: self._reposTable.model().removeRow(index.row()) def setStatus(self, msg, _progress=False): if msg: self._statusLabel.setText(msg) self._statusWidget.setVisible(True) else: self._statusWidget.setVisible(False)
class DetailsTreeView(DetailsDBHandler, DetailsDockWidget): def __init__(self, iface, spatial_unit_dock): """ The method initializes the dockwidget. :param iface: QGIS user interface class :type class qgis.utils.iface :param plugin: The STDM plugin :type class :return: None """ from stdm.ui.entity_browser import _EntityDocumentViewerHandler DetailsDockWidget.__init__(self, iface, spatial_unit_dock) DetailsDBHandler.__init__(self) self.spatial_unit_dock = spatial_unit_dock self.view = QTreeView() self.view.setSelectionBehavior( QAbstractItemView.SelectRows ) #self.feature_ids = [] self.layer_table = None self.entity = None self.feature_models = {} self.party_models = {} self.STR_models = {} self.feature_STR_model = {} self.removed_feature = None self.selected_root = None self.model = QStandardItemModel() self.view.setModel(self.model) self.view.setUniformRowHeights(True) self.view.setRootIsDecorated(True) self.view.setAlternatingRowColors(True) self.view.setWordWrap(True) self.view.setHeaderHidden(True) self.view.setEditTriggers( QAbstractItemView.NoEditTriggers ) self.current_profile = current_profile() self.social_tenure = self.current_profile.social_tenure self.spatial_unit = self.social_tenure.spatial_unit self.party = self.social_tenure.party self.view.setMinimumWidth(250) self.doc_viewer_title = QApplication.translate( 'EntityBrowser', 'Document Viewer' ) self.doc_viewer = _EntityDocumentViewerHandler( self.doc_viewer_title, self.iface.mainWindow() ) def set_layer_entity(self): self.layer_table = self.get_layer_source( self.iface.activeLayer() ) if self.layer_table in spatial_tables(): self.entity = self.current_profile.entity_by_name( self.layer_table ) else: self.treeview_error('The layer is not a spatial entity layer. ') def activate_feature_details(self, button_clicked=True): """ Action for showing feature details. :return: """ # Get the active layer. active_layer = self.iface.activeLayer() # TODO fix feature_details_btn is deleted error. if active_layer is not None and \ self.spatial_unit_dock.feature_details_btn.isChecked(): # if feature detail dock is not defined or hidden, create empty dock. if self is None or self.isHidden(): # if the selected layer is not a feature layer, show not # feature layer. (implicitly included in the if statement). if not self.feature_layer(active_layer): self.spatial_unit_dock.feature_details_btn.setChecked(False) return # If the selected layer is feature layer, get data and # display treeview in a dock widget else: select_feature = QApplication.translate( "STDMQGISLoader", "Please select a feature to view their details." ) self.init_dock() self.add_tree_view() self.model.clear() self.treeview_error(select_feature) # enable the select tool self.activate_select_tool() # set entity from active layer in the child class self.set_layer_entity() # set entity for the super class DetailModel self.set_entity(self.entity) # Registery column widget self.set_formatter() #set formatter for social tenure relationship. self.set_formatter(self.social_tenure) self.set_formatter(self.party) # pull data, show treeview active_layer.selectionChanged.connect( self.show_tree ) self.steam_signals(self.entity) # if feature_detail dock is open, toggle close else: self.close_dock( self.spatial_unit_dock.feature_details_btn ) self.feature_details = None # if no active layer, show error message and uncheck the feature tool else: if button_clicked: self.active_layer_check() self.spatial_unit_dock.feature_details_btn.setChecked(False) def add_tree_view(self): """ Adds tree view to the dock widget and sets style. :return: None """ self.tree_scrollArea.setWidget(self.view) def clear_feature_models(self): self.feature_models.clear() def reset_tree_view(self, no_feature=False): #clear feature_ids list, model and highlight self.model.clear() self.clear_sel_highlight() # remove sel_highlight self.disable_buttons(no_feature) if self.removed_feature is None: self.STR_models.clear() self.feature_models.clear() else: self.removed_feature = None features = self.selected_features() # if the selected feature is over 1, # activate multi_select_highlight if not features is None: self.view.clicked.connect( self.multi_select_highlight ) # if there is at least one selected feature if len(features) > 0: self.add_tree_view() #self.feature_ids = features def disable_buttons(self, bool): self.edit_btn.setDisabled(bool) self.delete_btn.setDisabled(bool) def show_tree(self): selected_features = self.selected_features() if len(selected_features) < 1: self.reset_tree_view(True) return if not self.entity is None: self.reset_tree_view() if len(selected_features) < 1: self.disable_buttons(True) return layer_icon = QIcon(':/plugins/stdm/images/icons/layer.gif') roots = self.add_parent_tree( layer_icon, format_name(self.entity.short_name) ) if roots is None: return for id, root in roots.iteritems(): db_model = entity_id_to_model(self.entity, id) self.add_roots(db_model, root, id) def add_parent_tree(self, icon, title): roots = OrderedDict() for feature_id in self.selected_features(): root = QStandardItem(icon, title) root.setData(feature_id) self.set_bold(root) self.model.appendRow(root) roots[feature_id] = root return roots def add_roots(self, model, parent, feature_id): self.feature_models[feature_id] = model if model is None: return self.column_widget_registry(model, self.entity) for i, (col, row) in enumerate(self.formatted_record.iteritems()): child = QStandardItem('{}: {}'.format(col, row)) child.setSelectable(False) parent.appendRow([child]) # Add Social Tenure Relationship steam as a last child if i == len(self.formatted_record)-1: self.add_STR_child(parent, feature_id) self.expand_node(parent) def add_STR_steam(self, parent, STR_id): str_icon = QIcon( ':/plugins/stdm/images/icons/social_tenure.png' ) title = 'Social Tenure Relationship' str_root = QStandardItem(str_icon, title) str_root.setData(STR_id) self.set_bold(str_root) parent.appendRow([str_root]) return str_root def add_no_STR_steam(self, parent): if self.entity.name == self.spatial_unit.name: no_str_icon = QIcon( ':/plugins/stdm/images/icons/remove.png' ) title = 'No STR Defined' no_str_root = QStandardItem(no_str_icon, title) self.set_bold(no_str_root) parent.appendRow([no_str_root]) def add_STR_child(self, parent, feature_id): if len(self.feature_STR_link(feature_id)) < 1: self.add_no_STR_steam(parent) return for record in self.feature_STR_link(feature_id): self.STR_models[record.id] = record str_root = self.add_STR_steam(parent, record.id) # add STR children self.column_widget_registry(record, self.social_tenure) for i, (col, row) in enumerate( self.formatted_record.iteritems() ): STR_child = QStandardItem( '{}: {}'.format(col, row) ) STR_child.setSelectable(False) str_root.appendRow([STR_child]) if i == len(self.formatted_record)-1: self.add_party_child( str_root, record.party_id ) self.feature_STR_model[feature_id] = self.STR_models.keys() def add_party_steam(self, parent, party_id): party_icon = QIcon( ':/plugins/stdm/images/icons/table.png' ) title = format_name(self.party.short_name) party_root = QStandardItem(party_icon, title) party_root.setData(party_id) self.set_bold(party_root) parent.appendRow([party_root]) party_root.setEditable(False) return party_root def add_party_child(self, parent, party_id): db_model = entity_id_to_model(self.party, party_id) self.party_models[party_id] = db_model party_root = self.add_party_steam(parent, party_id) # add STR children self.column_widget_registry(db_model, self.party) for col, row in self.formatted_record.iteritems(): party_child = QStandardItem('{}: {}'.format(col, row)) party_child.setSelectable(False) party_root.appendRow([party_child]) def set_bold(self, standard_item): """ Make a text of Qstandaritem to bold. :param standard_item: Qstandaritem :type: Qstandaritem :return: None """ font = standard_item.font() font.setBold(True) standard_item.setFont(font) def treeview_error(self, message, icon=None): """ Displays error message in feature details treeview. :param title: the title of the treeview. :type: String :param message: The message to be displayed. :type: String :param icon: The icon of the item. :type: Resource string :return: None """ not_feature_ft_msg = QApplication.translate( 'FeatureDetails', message ) if icon== None: root = QStandardItem(not_feature_ft_msg) else: root = QStandardItem(icon, not_feature_ft_msg) self.view.setRootIsDecorated(False) self.model.appendRow(root) self.view.setRootIsDecorated(True) def expand_node(self, parent): """ Make the last tree node expand. :param parent: The parent to expand :type QStandardItem :return:None """ index = self.model.indexFromItem(parent) self.view.expand(index) def multi_select_highlight(self, index): """ Highlights a feature with rubberBald class when selecting features are more than one. :param index: Selected QTreeView item index :type Integer :return: None """ map = self.iface.mapCanvas() try: # Get the selected item text using the index selected_item = self.model.itemFromIndex(index) # Use mutli-select only when more than 1 items are selected. if self.layer.selectedFeatures() < 2: return self.selected_root = selected_item # Split the text to get the key and value. selected_item_text = selected_item.text() selected_value = selected_item.data() # If the first word is feature, expand & highlight. if selected_item_text == format_name(self.spatial_unit.short_name): self.view.expand(index) # expand the item # Clear any existing highlight self.clear_sel_highlight() # Insert highlight # Create expression to target the selected feature expression = QgsExpression( "\"id\"='" + str(selected_value) + "'" ) # Get feature iteration based on the expression ft_iteration = self.layer.getFeatures( QgsFeatureRequest(expression) ) # Retrieve geometry and attributes for feature in ft_iteration: # Fetch geometry geom = feature.geometry() self.sel_highlight = QgsHighlight(map, geom, self.layer) self.sel_highlight.setFillColor(selection_color()) self.sel_highlight.setWidth(4) self.sel_highlight.setColor(QColor(212,95,0, 255)) self.sel_highlight.show() break except AttributeError: # pass attribute error on child items such as party pass except IndexError: pass def steam_signals(self, entity): self.edit_btn.clicked.connect( lambda : self.edit_selected_steam( entity ) ) self.delete_btn.clicked.connect( self.delete_selected_item ) self.view_document_btn.clicked.connect( lambda : self.view_steam_document( entity ) ) def steam_data(self, mode): item = None # if self.view.currentIndex().text() == format_name(self.party): # return None, None # One item is selected and number of feature is also 1 if len(self.layer.selectedFeatures()) == 1 and \ len(self.view.selectedIndexes()) == 1: index = self.view.selectedIndexes()[0] item = self.model.itemFromIndex(index) result = item.data() # One item is selected on the map but not on the treeview elif len(self.layer.selectedFeatures()) == 1 and \ len(self.view.selectedIndexes()) == 0: item = self.model.item(0, 0) result = item.data() # multiple features are selected but one treeview item is selected elif len(self.layer.selectedFeatures()) > 1 and \ len(self.view.selectedIndexes()) == 1: item = self.selected_root result = self.selected_root.data() # multiple features are selected but no treeview item is selected elif len(self.layer.selectedFeatures()) > 1 and \ len(self.view.selectedIndexes()) == 0: result = 'Please, select an item to {}.'.format(mode) else: result = 'Please, select at least one feature to {}.'.format(mode) if result is None: if item is None: item = self.model.item(0, 0) result = item.data() else: result = item.parent().data() return result, item def edit_selected_steam(self, entity): id, item = self.steam_data('edit') feature_edit = True if id is None: return if isinstance(id, str): data_error = QApplication.translate('DetailsTreeView', id) QMessageBox.warning( self.iface.mainWindow(), "Edit Error", data_error ) return if item.text() == 'Social Tenure Relationship': model = self.STR_models[id] feature_edit = False ##TODO add STR wizard edit mode here. elif item.text() == format_name(self.party.short_name): feature_edit = False model = self.party_models[id] editor = EntityEditorDialog( self.party, model, self.iface.mainWindow() ) editor.exec_() else: model = self.feature_models[id] editor = EntityEditorDialog( entity, model, self.iface.mainWindow() ) editor.exec_() #root = self.find_root(entity, id) self.view.expand(item.index()) if feature_edit: self.update_edited_steam(entity, id) else: self.update_edited_steam(self.social_tenure, id) def delete_selected_item(self): str_edit = False id, item = self.steam_data('delete') if isinstance(id, str): data_error = QApplication.translate( 'DetailsTreeView', id ) QMessageBox.warning( self.iface.mainWindow(), 'Delete Error', data_error ) return if item.text() == 'Social Tenure Relationship': str_edit = True db_model = self.STR_models[id] elif item.text() == format_name(self.spatial_unit.short_name) and \ id not in self.feature_STR_model.keys(): db_model = self.feature_models[id] # if spatial unit is linked to STR, don't allow delete elif item.text() == format_name(self.spatial_unit.short_name) and \ id in self.feature_STR_model.keys(): delete_warning = QApplication.translate( 'DetailsTreeView', 'You have to first delete the social tenure \n' 'relationship to delete the {} record.'.format( item.text() ) ) QMessageBox.warning( self.iface.mainWindow(), 'Delete Error', delete_warning ) return # If it is party node, STR exists and don't allow delete. elif item.text() == format_name(self.party.short_name): delete_warning = QApplication.translate( 'DetailsTreeView', 'You have to first delete the social tenure \n' 'relationship to delete the {} record.'.format( item.text() ) ) QMessageBox.warning( self.iface.mainWindow(), 'Delete Error', delete_warning ) return else: return delete_warning = QApplication.translate( 'DetailsTreeView', 'Are you sure you want to delete ' 'the selected record(s)?\n' 'This action cannot be undone.' ) delete_question = QMessageBox.warning( self.iface.mainWindow(), "Delete Warning", delete_warning, QMessageBox.Yes | QMessageBox.No ) if delete_question == QMessageBox.Yes: db_model.delete() if str_edit: del self.STR_models[id] else: self.removed_feature = id del self.feature_models[id] self.updated_removed_steam(str_edit, item) else: return def update_edited_steam(self, entity, feature_id): # remove rows before adding the updated ones. self.layer.setSelectedFeatures( self.feature_models.keys() ) root = self.find_root(entity, feature_id) if root is None: return self.view.selectionModel().select( root.index(), self.view.selectionModel().Select ) self.expand_node(root) self.multi_select_highlight(root.index()) def find_root(self, entity, feature_id): all_roots = self.model.findItems( format_name(entity.short_name) ) root = None for item in all_roots: if item.data() == feature_id: root = item break return root def updated_removed_steam(self, STR_edit, item): if not STR_edit: if len(self.feature_models) > 1: self.refresh_layers() feature_ids = self.feature_models.keys() self.layer.setSelectedFeatures( feature_ids ) else: item.removeRows(0, 2) item.setText('No STR Definded') no_str_icon = QIcon( ':/plugins/stdm/images/icons/remove.png' ) item.setIcon(no_str_icon) def view_steam_document(self, entity): # Slot raised to show the document viewer for the selected entity id, item = self.steam_data('edit') if id is None: return if isinstance(id, str): data_error = QApplication.translate('DetailsTreeView', id) QMessageBox.warning( self.iface.mainWindow(), "Edit Error", data_error ) return if item.text() == 'Social Tenure Relationship': db_model = self.STR_models[id] else: db_model = self.feature_models[id] if not db_model is None: docs = db_model.documents # Notify there are no documents for the selected doc if len(docs) == 0: msg = QApplication.translate( 'EntityBrowser', 'There are no supporting documents ' 'for the selected record.' ) QMessageBox.warning( self, self.doc_viewer_title, msg ) else: self.doc_viewer.load(docs)
class DlgSqlLayerWindow(QWidget, Ui_Dialog): nameChanged = pyqtSignal(str) def __init__(self, iface, layer, parent=None): QWidget.__init__(self, parent) self.iface = iface self.layer = layer uri = QgsDataSourceUri(layer.source()) dbplugin = None db = None if layer.dataProvider().name() == 'postgres': dbplugin = createDbPlugin('postgis', 'postgres') elif layer.dataProvider().name() == 'spatialite': dbplugin = createDbPlugin('spatialite', 'spatialite') elif layer.dataProvider().name() == 'oracle': dbplugin = createDbPlugin('oracle', 'oracle') elif layer.dataProvider().name() == 'virtual': dbplugin = createDbPlugin('vlayers', 'virtual') if dbplugin: dbplugin.connectToUri(uri) db = dbplugin.db self.dbplugin = dbplugin self.db = db self.filter = "" self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostgreSQL allows a primary key to span multiple columns, spatialite doesn't self.aliasSubQuery = isinstance(db, PGDatabase) # only PostgreSQL requires subqueries to be aliases self.setupUi(self) self.setWindowTitle( u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString())) self.defaultLayerName = 'QueryLayer' if self.allowMultiColumnPk: self.uniqueColumnCheck.setText(self.trUtf8("Column(s) with unique values")) else: self.uniqueColumnCheck.setText(self.trUtf8("Column with unique values")) self.editSql.setFocus() self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.editSql.setMarginVisible(True) self.initCompleter() # allow copying results copyAction = QAction("copy", self) self.viewResult.addAction(copyAction) copyAction.setShortcuts(QKeySequence.Copy) copyAction.triggered.connect(self.copySelectedResults) self.btnExecute.clicked.connect(self.executeSql) self.btnSetFilter.clicked.connect(self.setFilter) self.btnClear.clicked.connect(self.clearSql) self.presetStore.clicked.connect(self.storePreset) self.presetDelete.clicked.connect(self.deletePreset) self.presetCombo.activated[str].connect(self.loadPreset) self.presetCombo.activated[str].connect(self.presetName.setText) self.updatePresetsCombobox() self.geomCombo.setEditable(True) self.geomCombo.lineEdit().setReadOnly(True) self.uniqueCombo.setEditable(True) self.uniqueCombo.lineEdit().setReadOnly(True) self.uniqueModel = QStandardItemModel(self.uniqueCombo) self.uniqueCombo.setModel(self.uniqueModel) if self.allowMultiColumnPk: self.uniqueCombo.setItemDelegate(QStyledItemDelegate()) self.uniqueModel.itemChanged.connect(self.uniqueChanged) # react to the (un)checking of an item self.uniqueCombo.lineEdit().textChanged.connect(self.uniqueTextChanged) # there are other events that change the displayed text and some of them can not be caught directly self.layerTypeWidget.hide() # show if load as raster is supported #self.loadLayerBtn.clicked.connect(self.loadSqlLayer) self.updateLayerBtn.clicked.connect(self.updateSqlLayer) self.getColumnsBtn.clicked.connect(self.fillColumnCombos) self.queryBuilderFirst = True self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif")) self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder) self.presetName.textChanged.connect(self.nameChanged) # Update from layer # Fisrtly the SQL from QgsDataSourceUri table sql = uri.table() if uri.keyColumn() == '_uid_': match = re.search('^\(SELECT .+ AS _uid_,\* FROM \((.*)\) AS _subq_.+_\s*\)$', sql, re.S) if match: sql = match.group(1) else: match = re.search('^\((SELECT .+ FROM .+)\)$', sql, re.S) if match: sql = match.group(1) self.editSql.setText(sql) self.executeSql() # Then the columns self.geomCombo.setCurrentIndex(self.geomCombo.findText(uri.geometryColumn(), Qt.MatchExactly)) if uri.keyColumn() != '_uid_': self.uniqueColumnCheck.setCheckState(Qt.Checked) if self.allowMultiColumnPk: itemsData = uri.keyColumn().split(',') for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.data() in itemsData: item.setCheckState(Qt.Checked) else: keyColumn = uri.keyColumn() for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.data() == keyColumn: self.uniqueCombo.setCurrentIndex(self.uniqueModel.indexFromItem(item).row()) # Finally layer name, filter and selectAtId self.layerNameEdit.setText(layer.name()) self.filter = uri.sql() if uri.selectAtIdDisabled(): self.avoidSelectById.setCheckState(Qt.Checked) def updatePresetsCombobox(self): self.presetCombo.clear() names = [] entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries') for entry in entries: name = QgsProject.instance().readEntry('DBManager', 'savedQueries/' + entry + '/name')[0] names.append(name) for name in sorted(names): self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(-1) def storePreset(self): query = self._getSqlQuery() if query == "": return name = self.presetName.text() QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name', name) QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query', query) index = self.presetCombo.findText(name) if index == -1: self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1) else: self.presetCombo.setCurrentIndex(index) def deletePreset(self): name = self.presetCombo.currentText() QgsProject.instance().removeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__())) self.presetCombo.removeItem(self.presetCombo.findText(name)) self.presetCombo.setCurrentIndex(-1) def loadPreset(self, name): query = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query')[0] name = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name')[0] self.editSql.setText(query) def clearSql(self): self.editSql.clear() self.editSql.setFocus() self.filter = "" def executeSql(self): sql = self._getSqlQuery() if sql == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # delete the old model old_model = self.viewResult.model() self.viewResult.setModel(None) if old_model: old_model.deleteLater() cols = [] quotedCols = [] try: # set the new model model = self.db.sqlResultModel(sql, self) self.viewResult.setModel(model) self.lblResult.setText(self.tr("%d rows, %.1f seconds") % (model.affectedRows(), model.secs())) cols = self.viewResult.model().columnNames() for col in cols: quotedCols.append(self.db.connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return self.setColumnCombos(cols, quotedCols) self.update() QApplication.restoreOverrideCursor() def _getSqlLayer(self, _filter): hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked if hasUniqueField: if self.allowMultiColumnPk: checkedCols = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedCols.append(item.data()) uniqueFieldName = ",".join(checkedCols) elif self.uniqueCombo.currentIndex() >= 0: uniqueFieldName = self.uniqueModel.item(self.uniqueCombo.currentIndex()).data() else: uniqueFieldName = None else: uniqueFieldName = None hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked if hasGeomCol: geomFieldName = self.geomCombo.currentText() else: geomFieldName = None query = self._getSqlQuery() if query == "": return None # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] from qgis.core import QgsMapLayer, QgsMapLayerRegistry layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer # get a new layer name names = [] for layer in QgsMapLayerRegistry.instance().mapLayers().values(): names.append(layer.name()) layerName = self.layerNameEdit.text() if layerName == "": layerName = self.defaultLayerName newLayerName = layerName index = 1 while newLayerName in names: index += 1 newLayerName = u"%s_%d" % (layerName, index) # create the layer layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType, self.avoidSelectById.isChecked(), _filter) if layer.isValid(): return layer else: return None def loadSqlLayer(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: layer = self._getSqlLayer(self.filter) if layer == None: return from qgis.core import QgsMapLayerRegistry QgsMapLayerRegistry.instance().addMapLayers([layer], True) finally: QApplication.restoreOverrideCursor() def updateSqlLayer(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: layer = self._getSqlLayer(self.filter) if layer == None: return #self.layer.dataProvider().setDataSourceUri(layer.dataProvider().dataSourceUri()) #self.layer.dataProvider().reloadData() XMLDocument = QDomDocument("style") XMLMapLayers = XMLDocument.createElement("maplayers") XMLMapLayer = XMLDocument.createElement("maplayer") self.layer.writeLayerXML(XMLMapLayer, XMLDocument) XMLMapLayer.firstChildElement("datasource").firstChild().setNodeValue(layer.source()) XMLMapLayers.appendChild(XMLMapLayer) XMLDocument.appendChild(XMLMapLayers) self.layer.readLayerXML(XMLMapLayer) self.layer.reload() self.iface.actionDraw().trigger() self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(layer) finally: QApplication.restoreOverrideCursor() def fillColumnCombos(self): query = self._getSqlQuery() if query == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] # get all the columns cols = [] quotedCols = [] connector = self.db.connector if self.aliasSubQuery: # get a new alias aliasIndex = 0 while True: alias = "_subQuery__%d" % aliasIndex escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b') if not escaped.search(query): break aliasIndex += 1 sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % (unicode(query), connector.quoteId(alias)) else: sql = u"SELECT * FROM (%s\n) WHERE 1=0" % unicode(query) c = None try: c = connector._execute(None, sql) cols = connector._get_cursor_columns(c) for col in cols: quotedCols.append(connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return finally: if c: c.close() del c self.setColumnCombos(cols, quotedCols) QApplication.restoreOverrideCursor() def setColumnCombos(self, cols, quotedCols): # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first) try: defaultGeomCol = next(col for col in cols if col in ['geom', 'geometry', 'the_geom', 'way']) except: defaultGeomCol = None try: defaultUniqueCol = [col for col in cols if 'id' in col][0] except: defaultUniqueCol = None colNames = sorted(zip(cols, quotedCols)) newItems = [] uniqueIsFilled = False for (col, quotedCol) in colNames: item = QStandardItem(col) item.setData(quotedCol) item.setEnabled(True) item.setCheckable(self.allowMultiColumnPk) item.setSelectable(not self.allowMultiColumnPk) if self.allowMultiColumnPk: matchingItems = self.uniqueModel.findItems(col) if matchingItems: item.setCheckState(matchingItems[0].checkState()) uniqueIsFilled = uniqueIsFilled or matchingItems[0].checkState() == Qt.Checked else: item.setCheckState(Qt.Unchecked) newItems.append(item) if self.allowMultiColumnPk: self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) self.uniqueChanged() else: previousUniqueColumn = self.uniqueCombo.currentText() self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) if self.uniqueModel.findItems(previousUniqueColumn): self.uniqueCombo.setEditText(previousUniqueColumn) uniqueIsFilled = True oldGeometryColumn = self.geomCombo.currentText() self.geomCombo.clear() self.geomCombo.addItems(cols) self.geomCombo.setCurrentIndex(self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly)) # set sensible default columns if the columns are not already set try: if self.geomCombo.currentIndex() == -1: self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol)) except: pass items = self.uniqueModel.findItems(defaultUniqueCol) if items and not uniqueIsFilled: if self.allowMultiColumnPk: items[0].setCheckState(Qt.Checked) else: self.uniqueCombo.setEditText(defaultUniqueCol) try: pass except: pass def copySelectedResults(self): if len(self.viewResult.selectedIndexes()) <= 0: return model = self.viewResult.model() # convert to string using tab as separator text = model.headerToString("\t") for idx in self.viewResult.selectionModel().selectedRows(): text += "\n" + model.rowToString(idx.row(), "\t") QApplication.clipboard().setText(text, QClipboard.Selection) QApplication.clipboard().setText(text, QClipboard.Clipboard) def initCompleter(self): dictionary = None if self.db: dictionary = self.db.connector.getSqlDictionary() if not dictionary: # use the generic sql dictionary from .sql_dictionary import getSqlDictionary dictionary = getSqlDictionary() wordlist = [] for name, value in dictionary.iteritems(): wordlist += value # concat lists wordlist = list(set(wordlist)) # remove duplicates api = QsciAPIs(self.editSql.lexer()) for word in wordlist: api.add(word) api.prepare() self.editSql.lexer().setAPIs(api) def displayQueryBuilder(self): dlg = QueryBuilderDlg(self.iface, self.db, self, reset=self.queryBuilderFirst) self.queryBuilderFirst = False r = dlg.exec_() if r == QDialog.Accepted: self.editSql.setText(dlg.query) def _getSqlQuery(self): sql = self.editSql.selectedText() if len(sql) == 0: sql = self.editSql.text() return sql def uniqueChanged(self): # when an item is (un)checked, simply trigger an update of the combobox text self.uniqueTextChanged(None) def uniqueTextChanged(self, text): # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one. checkedItems = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedItems.append(item.text()) label = ", ".join(checkedItems) if text != label: self.uniqueCombo.setEditText(label) def setFilter(self): from qgis.gui import QgsQueryBuilder layer = self._getSqlLayer("") if not layer: return dlg = QgsQueryBuilder(layer) dlg.setSql(self.filter) if dlg.exec_(): self.filter = dlg.sql() layer.deleteLater()
class FormItem(QStandardItem): def __init__(self, name, fields, setup): super(FormItem, self).__init__(name) fields = [("Name", str, name)] + fields self.name = lambda: str(self.text()) self.names, _, _ = zip(*fields) self.dtypes = {} self.widgets = {} self.method_names = [] self.val_items = {} self.expr_items = {} self.group_items = {} self.setup = setup self.params_model = QStandardItemModel() self.params_model.itemChanged.connect(self.update_name) self.params_model.setHorizontalHeaderLabels(["Name", "Formula", "Evaluated"]) self.params_widget = QTableView() self.params_widget.setModel(self.params_model) self.params_widget.setItemDelegate(FormDelegate(self.params_model, self.widgets)) self.params_widget.verticalHeader().hide() for name, item_type, default in fields: self.add_field(name, item_type, default) self.params_widget.resizeRowsToContents() self.context_menu = ActionsMenu([]) self.params_model.itemChanged.connect(self.notify_group_item_children) def notify_group_item_children(self, item): method_name = method_style(self.params_model.item(item.row(), 0).text()) if method_name in self.group_items: current_item = self.dtypes[method_name](item.text()) previous_item = self.dtypes[method_name](self.group_items[method_name]) self.group_items[method_name] = current_item current_item.register_dependency(self) previous_item.unregister_dependency(self) def add_field(self, word_name, item_type, value): word_name = word_style(word_name) method_name = method_style(word_name) if item_type is int: self.dtypes[method_name] = int self.widgets[word_name] = lambda: IntVarLineEdit(self.setup) elif item_type is float: self.dtypes[method_name] = float self.widgets[word_name] = lambda: VarLineEdit(self.setup) elif isinstance(item_type, bool): self.dtypes[method_name] = bool self.widgets[word_name] = QCheckBox elif isinstance(item_type, (list, tuple)): self.dtypes[method_name] = str self.widgets[word_name] = \ lambda grp=item_type, **kwargs: MyComboBox(grp, **kwargs) elif isinstance(item_type, GroupItem): group = item_type value = group.items_list()[0].text() self.dtypes[method_name] = lambda i_name, grp=group: grp.item_from_name(i_name) self.widgets[word_name] = \ lambda grp=group, **kwargs: ItemsComboBox(grp, **kwargs) self.group_items[method_name] = value group.item_from_name(value).register_dependency(self) self.expr_items[method_name] = QStandardItem(str(value)) self.val_items[method_name] = ConstantItem("") self.params_model.appendRow([ConstantItem(word_name), self.expr_items[method_name], self.val_items[method_name]]) self.method_names.append(method_name) def set_name(self, name): self.setText(name) self.params_model.item(0, 1).setText(name) def update_name(self): self.setText(self.params_model.item(0, 1).text()) def eval_item(self, item): if item in self.method_names: dtype = self.dtypes[item] text = self.val_items[item].text() if text == "": text = self.expr_items[item].text() return dtype(text) else: raise AttributeError(item) def __getattr__(self, item): return self.eval_item(item)
class PosiviewProperties(QgsOptionsDialogBase, Ui_PosiviewPropertiesBase): ''' GUI class classdocs for the Configuration dialog ''' applyChanges = pyqtSignal(dict) def __init__(self, project, parent=None): ''' Setup dialog widgets with the project properties ''' super(PosiviewProperties, self).__init__("PosiViewProperties", parent) self.setupUi(self) self.groupBox_6.hide() self.initOptionsBase(False) self.restoreOptionsBaseUi() self.comboBoxParser.addItems(PARSERS) self.comboBoxProviderType.addItems(DEVICE_TYPES) self.project = project self.projectProperties = project.properties() self.mToolButtonLoad.setDefaultAction(self.actionLoadConfiguration) self.mToolButtonSave.setDefaultAction(self.actionSaveConfiguration) self.mobileModel = QStringListModel() self.mobileListModel = QStringListModel() self.mMobileListView.setModel(self.mobileListModel) self.mobileProviderModel = QStandardItemModel() self.mobileProviderModel.setHorizontalHeaderLabels(('Provider', 'Filter')) self.mMobileProviderTableView.setModel(self.mobileProviderModel) self.providerListModel = QStringListModel() self.mDataProviderListView.setModel(self.providerListModel) self.comboBoxProviders.setModel(self.providerListModel) self.setupModelData(self.projectProperties) self.setupGeneralData(self.projectProperties) def setupModelData(self, properties): self.mobileListModel.setStringList(sorted(properties['Mobiles'].keys())) self.providerListModel.setStringList(sorted(properties['Provider'].keys())) def setupGeneralData(self, properties): self.lineEditCruise.setText(properties['Mission']['cruise']) self.lineEditDive.setText(properties['Mission']['dive']) self.lineEditStation.setText(properties['Mission']['station']) self.lineEditRecorderPath.setText(properties['RecorderPath']) self.checkBoxAutoRecording.setChecked(properties['AutoRecord']) self.spinBoxNotifyDuration.setValue(properties['NotifyDuration']) self.checkBoxUtcClock.setChecked((properties['ShowUtcClock'])) def updateGeneralData(self): self.projectProperties['Mission']['cruise'] = self.lineEditCruise.text() self.projectProperties['Mission']['dive'] = self.lineEditDive.text() self.projectProperties['Mission']['station'] = self.lineEditStation.text() self.projectProperties['RecorderPath'] = self.lineEditRecorderPath.text() self.projectProperties['AutoRecord'] = self.checkBoxAutoRecording.isChecked() self.projectProperties['NotifyDuration'] = self.spinBoxNotifyDuration.value() self.projectProperties['ShowUtcClock'] = self.checkBoxUtcClock.isChecked() def getColor(self, value): try: return QColor.fromRgba(int(value)) except ValueError: return QColor(value) @pyqtSlot(QAbstractButton, name='on_buttonBox_clicked') def onButtonBoxClicked(self, button): role = self.buttonBox.buttonRole(button) if role == QDialogButtonBox.ApplyRole or role == QDialogButtonBox.AcceptRole: self.updateGeneralData() self.applyChanges.emit(self.projectProperties) @pyqtSlot(name='on_actionSaveConfiguration_triggered') def onActionSaveConfigurationTriggered(self): ''' Save the current configuration ''' fn = QFileDialog.getSaveFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)') self.project.store(fn) @pyqtSlot(name='on_actionLoadConfiguration_triggered') def onActionLoadConfigurationTriggered(self): ''' Load configuration from file ''' fn = QFileDialog.getOpenFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)') self.projectProperties = self.project.read(fn) self.setupModelData(self.projectProperties) self.setupGeneralData(self.projectProperties) @pyqtSlot(QModelIndex, name='on_mMobileListView_clicked') def editMobile(self, index): ''' Populate the widgets with the selected mobiles properties ''' if index.isValid(): self.populateMobileWidgets(index) @pyqtSlot(str, name='on_comboBoxMobileType_currentIndexChanged') def mobileTypeChanged(self, mType): if mType == 'SHAPE': # self.lineEditMobileShape.setText(str(mobile['shape'])) self.lineEditMobileShape.setEnabled(True) else: self.lineEditMobileShape.setEnabled(False) @pyqtSlot(QModelIndex, name='on_mMobileListView_activated') def activated(self, index): pass @pyqtSlot(name='on_toolButtonAddMobile_clicked') def addMobile(self): self.mobileListModel.insertRow(self.mobileListModel.rowCount()) index = self.mobileListModel.index(self.mobileListModel.rowCount() - 1) self.lineEditMobileName.setText('NewMobile') self.mobileListModel.setData(index, 'NewMobile', Qt.DisplayRole) self.mMobileListView.setCurrentIndex(index) self.applyMobile() @pyqtSlot(name='on_pushButtonApplyMobile_clicked') def applyMobile(self): index = self.mMobileListView.currentIndex() if index.isValid() and not self.lineEditMobileName.text() == '': mobile = dict() mobile['Name'] = self.lineEditMobileName.text() mobile['type'] = self.comboBoxMobileType.currentText() try: t = eval(self.lineEditMobileShape.text()) if t.__class__ is tuple or t.__class__ is dict: mobile['shape'] = t except SyntaxError: mobile['shape'] = ((0.0, -0.5), (0.3, 0.5), (0.0, 0.2), (-0.5, 0.5)) mobile['length'] = self.doubleSpinBoxMobileLength.value() mobile['width'] = self.doubleSpinBoxMobileWidth.value() mobile['zValue'] = self.spinBoxZValue.value() mobile['color'] = self.mColorButtonMobileColor.color().rgba() mobile['fillColor'] = self.mColorButtonMobileFillColor.color().rgba() mobile['timeout'] = self.spinBoxMobileTimeout.value() * 1000 mobile['nofixNotify'] = self.spinBoxMobileNotification.value() mobile['trackLength'] = self.spinBoxTrackLength.value() mobile['trackColor'] = self.mColorButtonMobileTrackColor.color().rgba() provs = dict() for r in range(self.mobileProviderModel.rowCount()): try: fil = int(self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole)) except: fil = self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole) if not fil: fil = None provs[self.mobileProviderModel.item(r, 0).data(Qt.DisplayRole)] = fil mobile['provider'] = provs currName = self.mobileListModel.data(index, Qt.DisplayRole) if not currName == mobile['Name']: del self.projectProperties['Mobiles'][currName] self.mobileListModel.setData(index, mobile['Name'], Qt.DisplayRole) self.projectProperties['Mobiles'][mobile['Name']] = mobile def populateMobileWidgets(self, index): mobile = self.projectProperties['Mobiles'][self.mobileListModel.data(index, Qt.DisplayRole)] self.lineEditMobileName.setText(mobile.get('Name')) self.comboBoxMobileType.setCurrentIndex(self.comboBoxMobileType.findText(mobile.setdefault('type', 'BOX').upper())) if mobile['type'] == 'SHAPE': self.lineEditMobileShape.setText(str(mobile['shape'])) self.lineEditMobileShape.setEnabled(True) else: self.lineEditMobileShape.setEnabled(False) self.lineEditMobileShape.clear() self.doubleSpinBoxMobileLength.setValue(mobile.get('length', 20.0)) self.doubleSpinBoxMobileWidth.setValue(mobile.get('width', 5.0)) self.spinBoxZValue.setValue(mobile.get('zValue', 100)) self.mColorButtonMobileColor.setColor(self.getColor(mobile.get('color', 'black'))) self.mColorButtonMobileFillColor.setColor(self.getColor(mobile.get('fillColor', 'green'))) self.spinBoxMobileTimeout.setValue(mobile.get('timeout', 3000) / 1000) self.spinBoxMobileNotification.setValue(mobile.get('nofixNotify', 0)) self.spinBoxTrackLength.setValue(mobile.get('trackLength', 100)) self.mColorButtonMobileTrackColor.setColor(self.getColor(mobile.get('trackColor', 'green'))) r = 0 self.mobileProviderModel.removeRows(0, self.mobileProviderModel.rowCount()) if 'provider' in mobile: for k, v in mobile['provider'].items(): prov = QStandardItem(k) val = QStandardItem(str(v)) self.mobileProviderModel.setItem(r, 0, prov) self.mobileProviderModel.setItem(r, 1, val) r += 1 @pyqtSlot(name='on_toolButtonRemoveMobile_clicked') def removeMobile(self): idx = self.mMobileListView.currentIndex() if idx.isValid(): self.projectProperties['Mobiles'].pop(self.mobileListModel.data(idx, Qt.DisplayRole)) self.mobileListModel.removeRows(idx.row(), 1) idx = self.mMobileListView.currentIndex() if idx.isValid(): self.populateMobileWidgets(idx) @pyqtSlot(name='on_toolButtonRefreshMobileProvider_clicked') def refreshMobileProvider(self): prov = self.comboBoxProviders.currentText() if prov == '': return fil = None if self.lineEditProviderFilter.text() != '': fil = self.lineEditProviderFilter.text() items = self.mobileProviderModel.findItems(prov, Qt.MatchExactly, 0) if items: for item in items: self.mobileProviderModel.setItem(item.row(), 1, QStandardItem(fil)) else: self.mobileProviderModel.appendRow([QStandardItem(prov), QStandardItem(fil)]) @pyqtSlot(name='on_toolButtonRemoveMobileProvider_clicked') def removeMobileProvider(self): idx = self.mMobileProviderTableView.currentIndex() if idx.isValid(): self.mobileProviderModel.removeRow(idx.row()) @pyqtSlot(name='on_pushButtonApplyDataProvider_clicked') def applyDataProvider(self): index = self.mDataProviderListView.currentIndex() if index.isValid() and not self.lineEditProviderName.text() == '': provider = dict() provider['Name'] = self.lineEditProviderName.text() provider['DataDeviceType'] = self.comboBoxProviderType.currentText() if provider['DataDeviceType'] in NETWORK_TYPES: provider['Host'] = self.lineEditProviderHostName.text() provider['Port'] = self.spinBoxProviderPort.value() provider['Parser'] = self.comboBoxParser.currentText() currName = self.providerListModel.data(index, Qt.DisplayRole) if not currName == provider['Name']: del self.projectProperties['Provider'][currName] self.providerListModel.setData(index, provider['Name'], Qt.DisplayRole) self.projectProperties['Provider'][provider['Name']] = provider @pyqtSlot(QModelIndex, name='on_mDataProviderListView_clicked') def editDataProvider(self, index): ''' ''' if index.isValid(): self.populateDataProviderWidgets(index) def populateDataProviderWidgets(self, index): provider = self.projectProperties['Provider'][self.providerListModel.data(index, Qt.DisplayRole)] self.lineEditProviderName.setText(provider.get('Name')) self.comboBoxProviderType.setCurrentIndex(self.comboBoxProviderType.findText(provider.setdefault('DataDeviceType', 'UDP').upper())) if provider['DataDeviceType'] in NETWORK_TYPES: self.stackedWidgetDataDevice.setCurrentIndex(0) self.lineEditProviderHostName.setText(provider.setdefault('Host', '0.0.0.0')) self.spinBoxProviderPort.setValue(int(provider.setdefault('Port', 2000))) self.comboBoxParser.setCurrentIndex(self.comboBoxParser.findText(provider.setdefault('Parser', 'NONE').upper())) @pyqtSlot(name='on_toolButtonAddDataProvider_clicked') def addDataProvider(self): self.providerListModel.insertRow(self.providerListModel.rowCount()) index = self.providerListModel.index(self.providerListModel.rowCount() - 1) self.lineEditProviderName.setText('NewDataProvider') self.providerListModel.setData(index, 'NewDataProvider', Qt.DisplayRole) self.mDataProviderListView.setCurrentIndex(index) self.applyDataProvider() @pyqtSlot(name='on_toolButtonRemoveDataProvider_clicked') def removeDataProvider(self): idx = self.mDataProviderListView.currentIndex() if idx.isValid(): self.projectProperties['Provider'].pop(self.providerListModel.data(idx, Qt.DisplayRole)) self.providerListModel.removeRows(idx.row(), 1) idx = self.mDataProviderListView.currentIndex() if idx.isValid(): self.populateDataProviderWidgets(idx) @pyqtSlot(name='on_toolButtonSelectLogPath_clicked') def selectRecorderPath(self): path = QFileDialog.getExistingDirectory(self, self.tr('Select Recorder Path'), self.lineEditRecorderPath.text(), QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if path != '': self.lineEditRecorderPath.setText(path) @pyqtSlot(QPoint, name='on_lineEditMobileShape_customContextMenuRequested') def mobileShapeContextMenu(self, pos): menu = QMenu(self.lineEditMobileShape) vesselAction = menu.addAction(self.tr('Vessel')) rovAction = menu.addAction(self.tr('ROV')) auvAction = menu.addAction(self.tr('AUV')) arrowAction = menu.addAction(self.tr('Arrow')) selectedAction = menu.exec_(self.lineEditMobileShape.mapToGlobal(pos)) if selectedAction == vesselAction: self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))') elif selectedAction == rovAction: self.lineEditMobileShape.setText(u'((0.3, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3), (-0.3, -0.5))') elif selectedAction == auvAction: self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))') elif selectedAction == arrowAction: self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, 0.5), (0, 0), (-0.5, 0.5))') @pyqtSlot(name='on_buttonBox_helpRequested') def showHelp(self): """Display application help to the user.""" help_file = os.path.join(os.path.split(os.path.dirname(__file__))[0], 'help', 'index.html') QDesktopServices.openUrl(QUrl.fromLocalFile(help_file))
class Browser(QWidget): entrytype = type("EntryType", (object,), dict((v,k) for k,v in enumerate( ["directory", "playlist", "mediafile", "url"] ))) col = type("BrowserColumns", (object,), dict((v,k) for k,v in enumerate( ["name", "last_modified", "entrytype", "uri"] ))) @staticmethod def columns(): return len(dict((k,v) for k,v in Browser.col.__dict__.items() if not k.startswith("__"))) def __init__(self,app): super(Browser,self).__init__() self.mpd = app.mpd self.ih = app.imagehelper self.model = QStandardItemModel(0,self.columns(),self) self.initGUI() self.initActions() def initGUI(self): self.setWindowTitle(QApplication.applicationName()) layout = QVBoxLayout() headerlayout = QHBoxLayout() homeBtn = QToolButton() homeBtn.setIcon(self.ih.homeButton) homeBtn.setFixedSize(64,64) homeBtn.clicked.connect(self.home) headerlayout.addWidget(homeBtn) label = QLabel("<b>Location</b>") label.setMargin(10) label.setFixedSize(label.sizeHint()) headerlayout.addWidget(label) self.currentLocation = ClickableLabel("") self.currentLocation.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.currentLocation.setWordWrap(True) self.currentLocation.setFixedSize(400,64) self.currentLocation.clicked.connect(self.back) headerlayout.addWidget(self.currentLocation) headerlayout.addStretch() layout.addLayout(headerlayout) self.view = QListView() self.view.setSelectionMode( QAbstractItemView.SingleSelection) self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.view.setContextMenuPolicy(Qt.CustomContextMenu) self.view.customContextMenuRequested.connect(self.contextMenu) self.view.setModel(self.model) self.view.setModelColumn(0) #self.view.doubleClicked.connect(self.doubleClicked) self.view.activated.connect(self.activated) layout.addWidget(self.view) self.setLayout(layout) def initActions(self): self.actionAdd = QAction("Add", self) self.actionAddPlay = QAction("Add and Play", self) self.actionInsert = QAction("Insert", self) self.actionReplace = QAction("Replace", self) self.actionReplacePlay = QAction("Replace and Play", self) self.actionUpdate = QAction("Update", self) self.actionUpdateAll = QAction("Update all", self) # playlist actions self.actionPlsRename = QAction("Rename", self) self.actionPlsDelete = QAction("Delete", self) def contextMenu(self,pos): if self.model.rowCount() == 0: return mi = self.view.selectionModel().currentIndex() if not mi.isValid(): return uri = self.model.item(mi.row(),self.col.uri).text() entrytype = int(self.model.item(mi.row(),self.col.entrytype).text()) addfunc = None if entrytype != self.entrytype.playlist: addfunc = self.mpd.add else: addfunc = self.mpd.load popup = QMenu() popup.addAction(self.actionAdd) popup.addAction(self.actionAddPlay) if entrytype == self.entrytype.mediafile or \ entrytype == self.entrytype.url: popup.addAction(self.actionInsert) popup.addAction(self.actionReplace) popup.addAction(self.actionReplacePlay) if entrytype == self.entrytype.playlist: popup.addAction(self.actionPlsRename) popup.addAction(self.actionPlsDelete) else: popup.addAction(self.actionUpdate) popup.addAction(self.actionUpdateAll) action = popup.exec_(self.mapToGlobal(pos)) status = self.mpd.status() if action == self.actionAdd: addfunc(uri) elif action == self.actionAddPlay: addfunc(uri) self.mpd.play(int(status['playlistlength'])) elif action == self.actionInsert: song = int(status.get('song',-1))+1 self.mpd.addid(uri,song) elif action == self.actionReplace: self.mpd.clear() addfunc(uri) elif action == self.actionReplacePlay: self.mpd.clear() addfunc(uri) self.mpd.play() elif action == self.actionUpdate: ans = QMessageBox.question( self, "Update", "Trigger update for '%s'?" % uri, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ans == QMessageBox.Yes: self.mpd.update(uri) elif action == self.actionUpdateAll: self.mpd.update() elif action == self.actionPlsRename: ans, ok = QInputDialog.getText( self, "Rename playlist", "Rename playlist '%s':" % uri) plsname = unicode(ans) if ok and plsname != uri: for pls in self.mpd.listplaylists(): if pls['playlist'] == plsname: overwrite = QMessageBox.question( self, "Rename playlist", "Playlist exists, overwrite?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if overwrite == QMessageBox.Yes: self.mpd.rm(plsname) self.mpd.rename(uri,plsname) break else: self.mpd.rename(uri, plsname) self.home() elif action == self.actionPlsDelete: ans = QMessageBox.question( self, "Delete '%s'" % uri, "Are you sure?" % uri, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ans == QMessageBox.Yes: self.mpd.rm(uri) self.home() def showDirectory(self,uri): try: info = self.mpd.lsinfo(uri) except MPDError, e: print e return rows = [] for entry in [ d for d in info if not d.has_key('playlist')]: row = self.createRow(entry) if not row: continue rows += [row] for entry in sorted([ d for d in info if d.has_key('playlist')], key=operator.itemgetter('playlist')): row = self.createRow(entry) if not row: continue rows += [row] self.currentLocation.setText(uri) self.updateModel(rows)
class QgsAttributeTableDialog(QDialog): ''' classdocs ''' def __init__(self, parent, vectorlayer): QDialog.__init__(self, parent) # self.w = QDialog(self) self.baseLayer = vectorlayer self.canChangeAttributes = self.validate( QgsVectorDataProvider.ChangeAttributeValues) self.canDeleteFeatures = self.validate( QgsVectorDataProvider.DeleteFeatures) self.canAddAttributes = self.validate( QgsVectorDataProvider.AddAttributes) self.canDeleteAttributes = self.validate( QgsVectorDataProvider.DeleteAttributes) self.canAddFeatures = self.validate(QgsVectorDataProvider.AddFeatures) gridLayout = QGridLayout(self) self.setLayout(gridLayout) self.setWindowTitle("Attribute Table") self.setFixedSize(QSize(800, 600)) editorToolbar = QToolBar() editorToolbar.setFixedSize(QSize(768, 48)) self.actionToggleEditing = QAction(QIcon("Resource\\edit.png"), "ToggleEditing", self) self.actionToggleEditing.triggered.connect(self.toggleEditing) if (self.canChangeAttributes or self.canDeleteFeatures or self.canAddAttributes or self.canDeleteAttributes or self.canAddFeatures) and (not self.baseLayer.isReadOnly()): self.actionToggleEditing.setEnabled(True) else: self.actionToggleEditing.setEnabled(False) self.actionToggleEditing.setCheckable(True) editorToolbar.addAction(self.actionToggleEditing) self.actionSave = QAction(QIcon("Resource\\filesave.png"), "Save Edits", self) self.actionSave.triggered.connect(self.saveEditing) self.actionSave.setCheckable(False) self.actionSave.setEnabled(False) editorToolbar.addAction(self.actionSave) self.actiondeleteRows = QAction( QIcon("Resource\\mActionDeleteSelected.png"), "Delete selected features", self) self.actiondeleteRows.triggered.connect(self.deleteRows) self.actiondeleteRows.setCheckable(False) self.actiondeleteRows.setEnabled(False) editorToolbar.addAction(self.actiondeleteRows) self.actionUnselectAll = QAction( QIcon("Resource\\mActionDeselectAll.png"), "Unselect All", self) self.actionUnselectAll.triggered.connect(self.unselectAll) self.actionUnselectAll.setCheckable(False) self.actionUnselectAll.setEnabled(True) editorToolbar.addAction(self.actionUnselectAll) self.actionSelectedToZoom = QAction( QIcon("Resource\\mActionZoomToSelected.png"), "Zoom map to the selected rows", self) self.actionSelectedToZoom.triggered.connect(self.selectedToZoom) self.actionSelectedToZoom.setCheckable(False) self.actionSelectedToZoom.setEnabled(True) editorToolbar.addAction(self.actionSelectedToZoom) gridLayout.addWidget(editorToolbar, 0, 0, 1, 1) self.model = QStandardItemModel() # self.model.itemChanged.connect(self.attributeChanged) self.attributeTable = QTableView(self) self.attributeTable.setModel(self.model) self.attributeTable.setColumnWidth(0, 200) self.attributeTable.setColumnWidth(1, 160) self.attributeTable.clicked.connect(self.tableSelectionChanged) self.attributeTable.setSortingEnabled(True) self.changeItemList = [] self.selectRows = [] self.isSave = True self.initTable() gridLayout.addWidget(self.attributeTable, 1, 0, 1, 1) # self.attributeTable.selectionChanged.connect(self.selectFeature) def tableSelectionChanged(self): idxList = self.attributeTable.selectedIndexes() if idxList != None and len(idxList) > 0: self.baseLayer.removeSelection() fidList = [] for idx in idxList: fid = int(self.model.item(idx.row()).text()) fidList.append(fid) self.baseLayer.setSelectedFeatures(fidList) def toggleEditing(self): if self.baseLayer != None: if not self.actionToggleEditing.isChecked(): if self.isSave: self.baseLayer.commitChanges() self.actionSave.setEnabled(False) self.actiondeleteRows.setEnabled(False) self.model.itemChanged.disconnect(self.attributeChanged) self.toggleEditingTable(False) else: button = QMessageBox.warning( self, "Stop Editing", "Do you want to save the changes to layer?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if (button == QMessageBox.Cancel): self.actionToggleEditing.setChecked(True) elif button == QMessageBox.Save: self.saveEditing() self.baseLayer.commitChanges() self.actionSave.setEnabled(False) self.actiondeleteRows.setEnabled(False) self.model.itemChanged.disconnect( self.attributeChanged) self.toggleEditingTable(False) else: self.initTable() self.baseLayer.commitChanges() self.actionSave.setEnabled(False) self.actiondeleteRows.setEnabled(False) self.model.itemChanged.disconnect( self.attributeChanged) self.toggleEditingTable(False) # self.isEditable = False else: self.actionSave.setEnabled(True) self.actiondeleteRows.setEnabled(True) self.baseLayer.startEditing() self.toggleEditingTable(True) self.model.itemChanged.connect(self.attributeChanged) # self.isEditable = True def toggleEditingTable(self, isEditable): columnCount = self.model.columnCount() rowCount = self.model.rowCount() col = 0 while col < columnCount: row = 0 while row < rowCount: self.model.item(row, col).setEditable(isEditable) row += 1 col += 1 def attributeChanged(self, standardItem): self.isSave = False # if not self.isDelete: self.changeItemList.append(standardItem) # featureId = standardItem.row() # self.baseLayer.changeAttributeValue(featureId, # standardItem.column(), standardItem.text()) def saveEditing(self): self.isSave = True if len(self.changeItemList) > 0: for standardItem in self.changeItemList: featureId = standardItem.row() self.baseLayer.changeAttributeValue(featureId, standardItem.column(), standardItem.text()) self.changeItemList = [] if len(self.selectRows) > 0: for id in self.selectRows: self.baseLayer.deleteFeature(id) self.selectRows = [] def initTable(self): self.model.clear() # header = QHeaderView(Qt.Horizontal) # headerModel = QStandardItemModel() layer = self.baseLayer fields = layer.pendingFields() headersList = ["fid"] for field in fields: headersList.append(field.name()) self.model.setHorizontalHeaderLabels(headersList) # headerModel.setHorizontalHeaderLabels(headersList) # header.setModel(headerModel) # self.attributeTable.setHorizontalHeader(header) if len(layer.selectedFeatures()) > 0: features = layer.selectedFeatures() else: features = layer.getFeatures() for feature in features: record = [QStandardItem(str(feature.id()))] for field in feature.fields(): name = field.name() attribute = feature.attribute(name).toString() stdItemValue = QStandardItem(attribute) stdItemValue.setEditable(False) record.append(stdItemValue) self.model.appendRow(record) def deleteRows(self): if len(self.attributeTable.selectedIndexes()) > 0: self.isSave = False selectedIndexs = self.attributeTable.selectedIndexes() k = -1 self.selectRows = [] for index in selectedIndexs: if k != index.row(): k = index.row() self.selectRows.append(k) for row in self.selectRows: self.model.takeRow(row) def unselectAll(self): if len(self.attributeTable.selectedIndexes()) > 0: self.attributeTable.clearSelection() def selectedToZoom(self): if len(self.attributeTable.selectedIndexes()) > 0: self.baseLayer.removeSelection() selectedIndexs = self.attributeTable.selectedIndexes() k = -1 self.selectRows = [] for index in selectedIndexs: if k != index.row(): k = index.row() self.selectRows.append(k) self.baseLayer.setSelectedFeatures(self.selectRows) # for row in self.selectRows: # self.model.takeRow(row) define._canvas.zoomToSelected(self.baseLayer) def validate(self, condition): if self.baseLayer.dataProvider().capabilities() & condition: return True else: return False
class OrderSelectorModel(QObject): """""" #---------------------------------------------------------------------- def __init__(self, full_string_list, init_selected_string_list=None, permanently_selected_string_list=None): """Constructor""" QObject.__init__(self) self.output = [] if not self.hasNoDuplicateStrings(full_string_list): raise ValueError('Duplicate strings detected in full string list.') else: self.full_string_list = full_string_list[:] if init_selected_string_list is not None: if not self.allStringsInList1FoundInList2( init_selected_string_list, self.full_string_list): raise ValueError( 'Some of the strings in initially selected string list are not in full string list.' ) else: init_selected_string_list = [] if permanently_selected_string_list is not None: if not self.allStringsInList1FoundInList2( permanently_selected_string_list, init_selected_string_list): raise ValueError( 'Some of the strings in permanently selected string list are not in initially selected string list.' ) else: permanently_selected_string_list = [] self.permanently_selected_string_list = permanently_selected_string_list[:] self.model_Selected = QStandardItemModel() self.model_NotSelected = QStandardItemModel() Selected_item_list = [None for s in init_selected_string_list] NotSelected_item_list = [] for s in self.full_string_list: item = QStandardItem(s) try: Selected_item_list[init_selected_string_list.index(s)] = item except: NotSelected_item_list.append(item) for item in NotSelected_item_list: self.model_NotSelected.appendRow(item) for item in Selected_item_list: self.model_Selected.appendRow(item) #---------------------------------------------------------------------- def getSelectedList(self): """""" selectedList = [] for i in range(self.model_Selected.rowCount()): selectedList.append(self.model_Selected.item(i, 0).text()) return selectedList #---------------------------------------------------------------------- def hasNoDuplicateStrings(self, full_string_list): """""" str_list = full_string_list str_set = set(full_string_list) if len(str_list) == len(str_set): return True else: return False #---------------------------------------------------------------------- def allStringsInList1FoundInList2(self, str_list_1, str_list_2): """""" stringsNotFound = [s for s in str_list_1 if s not in str_list_2] if stringsNotFound != []: return False else: return True
class SubPowerWidget(QWidget): """ @brief Zeigt alle Unterkräfte in einer Baumstruktur an. """ def __init__(self, template, character, parent=None): super(SubPowerWidget, self).__init__(parent) self.__storage = template self.__character = character self.__model = QStandardItemModel() # Das ungenutzte Model dient dazu, alle Unterkräfte aufzunehmen, die ich nicht darstellen möchte. Ist einfacher, als diese im View zu verstecken. self.__modelUnused = QStandardItemModel() self._layout = QVBoxLayout() self.setLayout(self._layout) self.__view = QTreeView() self.__view.setHeaderHidden(True) self.__view.setModel(self.__model) self._layout.addWidget(self.__view) self._typ = "Subpower" categories = self.__storage.categories(self._typ) self.__items = {} self.__rootItem = QStandardItem() self.__rootItem = self.__model.invisibleRootItem() self.__rootItemUnused = QStandardItem() self.__rootItemUnused = self.__modelUnused.invisibleRootItem() for item in categories: categoryItem = QStandardItem(item) self.__rootItem.appendRow(categoryItem) ## Ich benötige diese Items auch im ungenutzten Model. categoryItemUnused = QStandardItem(item) self.__rootItemUnused.appendRow(categoryItemUnused) traitList = list(self.__character.traits[self._typ][item].items()) traitList.sort() for trait in traitList: traitItem = QStandardItem(trait[1].name) traitItem.setCheckable(True) ## Unhashable Type self.__items[trait[1]] = traitItem categoryItem.appendRow(traitItem) ## Funktioniert mit PySide nicht: #trait[1].availableChanged.connect(traitItem.setEnabled) ## Funktioniert auch mit PySide: trait[1].availableChanged.connect( lambda enable, item=traitItem: item.setEnabled(enable)) trait[1].valueChanged.connect(lambda val, trait=trait[ 1], item=traitItem: self.__setItemValue(trait, item)) self.__model.itemChanged.connect(self.__getItemValue) self.__character.speciesChanged.connect(self.hideOrShowToolPage) self.__character.breedChanged.connect(self.hideOrShowToolPage) self.__character.factionChanged.connect(self.hideOrShowToolPage) def __setItemValue(self, trait, item): """ Setzt den Wert der Angezeigten Items. """ if trait.value == 0: item.setCheckState(Qt.Unchecked) elif trait.value == 1: item.setCheckState(Qt.PartiallyChecked) else: item.setCheckState(Qt.Checked) def __getItemValue(self, item): """ Setzt den Wert der Eigenschaft im Speicher. """ for trait in self.__items.items(): if id(trait[1]) == id(item): trait[0].value = item.checkState() break def hideOrShowToolPage(self, res): """ Alle Eigenschaften, die nicht zur Verfügung stehen, werden verborgen, indem sie in ein anderes Model verschoben werden. \bug Möglicher Fehler in PySide: Der Aufruf von QStandardItem.model() führt beim Beenden des Programms zu einem Segmentation Fault. """ # Versteckt alle Unterkräfte, die zu gewähltem Charakter nicht passen. for item in self.__items.items(): if ((item[0].species and item[0].species != self.__character.species) or (item[0].only and self.__character.breed not in item[0].only and self.__character.faction not in item[0].only)): #self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), True) #Debug.debug(item[1].model()) ## Hier wird beispielsweise besagter Aufruf getätigt, der zu einem segfault führt. if item[1].model() == self.__model: parent = item[1].parent() itemUnused = parent.takeRow(item[1].index().row()) parentUnused = self.__modelUnused.findItems( parent.text())[0] parentUnused.appendRow(itemUnused) else: #self.__view.setRowHidden(item[1].index().row(), item[1].parent().index(), False) if item[1].model() == self.__modelUnused: parent = item[1].parent() itemUsed = parent.takeRow(item[1].index().row()) parentUsed = self.__model.findItems(parent.text())[0] parentUsed.appendRow(itemUsed) ## Versteckt alle Elternzeilen, wenn sie keine Kinder enthalten. for i in range(self.__model.rowCount()): categoryItem = self.__model.item(i) if categoryItem.hasChildren(): self.__view.setRowHidden(categoryItem.index().row(), self.__rootItem.index(), False) else: self.__view.setRowHidden(categoryItem.index().row(), self.__rootItem.index(), True)
class DialListCheckBox(object): """ Dialog with list check box example : 1,2,4,6,8 """ def __init__(self, values, checked_values=[]): self.dial = QDialog() self.result = "" # Layout Principal m_vbl = QVBoxLayout(self.dial) # List item checkable view = QListView() m_vbl.addWidget(view) self.m_sim = QStandardItemModel() view.setModel(self.m_sim) self._load_item(values, checked_values) # List buttons bt_all = QPushButton(self.tr("All")) bt_all.clicked.connect(lambda: self._check_all()) bt_nothing = QPushButton(self.tr("Nothing")) bt_nothing.clicked.connect(lambda: self._check_nothing()) bt_print = QPushButton(self.tr("Ok")) bt_print.clicked.connect(lambda: self._check_ok()) # Sub layout for buttons m_vbh = QHBoxLayout() m_vbl.addLayout(m_vbh) m_vbh.addWidget(bt_all) m_vbh.addWidget(bt_nothing) m_vbh.addWidget(bt_print) def _load_item(self, values, checked_values): """Load item list""" for v in values: item = QStandardItem(str(v)) if v in checked_values: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) item.setCheckable(True) self.m_sim.appendRow(item) def _check_all(self): """Check all item""" for index in range(self.m_sim.rowCount( )): ## Iteration sur le model (contient la list des items) item = self.m_sim.item(index) if item.isCheckable() and item.checkState( ) == Qt.Unchecked: # Si Unchecked item.setCheckState(Qt.Checked) def _check_nothing(self): """Uncheck all item""" for index in range(self.m_sim.rowCount( )): ## Iteration sur le model (contient la list des items) item = self.m_sim.item(index) if item.isCheckable() and item.checkState( ) == Qt.Checked: # Si Checked item.setCheckState(Qt.Unchecked) def _check_ok(self): """Get value of checked items and exit""" l_value = [] for index in range(self.m_sim.rowCount( )): ## Iteration sur le model (contient la list des items) item = self.m_sim.item(index) if item.isCheckable() and item.checkState( ) == Qt.Checked: # Si Checked l_value.append(str(item.text())) if l_value: s_value = ";".join(l_value) else: s_value = "" self.result = s_value self.dial.close() def run(self): self.dial.setWindowTitle(self.tr("Select values")) self.dial.exec_() return self.result def tr(self, string, context=''): if context == '' or context == None: context = self.__class__.__name__ return QCoreApplication.translate(context, string)
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setCentralWidget(self.ui.mangaTableView) self.newMangaDialog = NewMangaDialog() self.mangaDownloadDialog = MangaDownloadDialog() self.mangaTableModel = QStandardItemModel(0, 3, self) self.mangaTableModel.setHorizontalHeaderItem(0, QStandardItem(QString("Manga"))) self.mangaTableModel.setHorizontalHeaderItem(1, QStandardItem(QString("Latest Chapter"))) self.mangaTableModel.setHorizontalHeaderItem(2, QStandardItem(QString("Status"))) self.ui.mangaTableView.setModel(self.mangaTableModel) newMangaAction = QAction(QIcon("./icon/add.ico"),'New Manga', self) newMangaAction.setShortcut('Ctrl+N') newMangaAction.triggered.connect(self.newMangaDialog.show) removeMangaAction = QAction(QIcon("./icon/delete.ico"),'Remove Manga', self) removeMangaAction.setShortcut('Delete') preferencesAction = QAction(QIcon("./icon/preferences.ico"),'Preferences', self) aboutAction = QAction(QIcon("./icon/about.ico"),'About', self) self.ui.toolBar.addAction(newMangaAction) self.ui.toolBar.addAction(removeMangaAction) self.ui.toolBar.addSeparator() self.ui.toolBar.addAction(preferencesAction) self.ui.toolBar.addSeparator() self.ui.toolBar.addAction(aboutAction) self.progressBar = QProgressBar(self.ui.statusbar) self.ui.statusbar.addPermanentWidget(self.progressBar) self.progressBar.hide() def closeEvent(self, QCloseEvent): mangaList = [] for i in range(self.mangaTableModel.rowCount()): mangaList.append({ "name" : str(self.mangaTableModel.item(i, 0).text()), "latestChapter" : str(self.mangaTableModel.item(i, 1).text()), "status" : "Updated", "link" : "/trial.html" }) self.emit(SIGNAL("applicationClosed"),mangaList) def initializeProgressBar(self, size): self.progressBar.setRange(0, size) self.progressBar.setValue(0) self.progressBar.show() def updateProgressBar(self, value): self.progressBar.setValue(value) def updateStatusBar(self, msg): self.ui.statusbar.showMessage(msg) def updateMangaTable(self, chapter): isFound = False for i in range(self.mangaTableModel.rowCount()): mangaItem = self.mangaTableModel.item(i) if mangaItem.text() == chapter["name"]: self.mangaTableModel.item(i, 1).setText(chapter["latestChapter"]) self.mangaTableModel.item(i, 2).setText(chapter["status"]) isFound = True break if not isFound: self.addRowToMangaTable(chapter) def addMangaListToMangaTable(self, mangaList): for i in range(len(mangaList)): self.addRowToMangaTable(mangaList[i]) def addRowToMangaTable(self, manga): i = self.mangaTableModel.rowCount() mangaItem = QStandardItem(QString(manga["name"])) latestChapterItem = QStandardItem(QString(manga["latestChapter"])) statusItem = QStandardItem(QString(manga["status"])) brush = QBrush(QColor(255, 255, 255)) if i%2==0 else QBrush(QColor(200, 200, 200)) mangaItem.setBackground(brush) latestChapterItem.setBackground(brush) statusItem.setBackground(brush) self.mangaTableModel.setItem(i, 0, mangaItem) self.mangaTableModel.setItem(i, 1, latestChapterItem) self.mangaTableModel.setItem(i, 2, statusItem)
class CheckedListBox(QWidget): def __init__(self, parent): QWidget.__init__(self, parent) while not isinstance(parent, QDialog): parent = parent.parent() self.setObjectName("CheckedListBox" + str(len(parent.findChildren(CheckedListBox)))) self.setObjectName("checkBoxWidget") self.hLayout = QHBoxLayout(self) self.hLayout.setObjectName("hLayout") sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) # self.frame = Frame() self.listView = QListView(self) self.hLayout.addWidget(self.listView) self.stdModel = QStandardItemModel() self.listView.setModel(self.stdModel) self.hasObject = False self.objList = [] self.checkBoxList = [] self.listView.pressed.connect(self.listView_clicked) def listView_clicked(self, index): self.emit(SIGNAL("ItemCheck"), self.stdModel.itemFromIndex(index)) def mouseMoveEvent(self, mouseEvent): pt = mouseEvent.pos() pass def Clear(self): self.stdModel.clear() self.hasObject = False self.objList = [] def Add(self, caption, isCheckedFlag=False): captionStr = "" if isinstance(caption, str) or isinstance(caption, QString): captionStr = caption else: captionStr = caption.ToString() self.hasObject = True self.objList.append([self.stdModel.rowCount(), caption]) item = QStandardItem(captionStr) item.setCheckable(True) if isCheckedFlag: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) self.stdModel.setItem(self.stdModel.rowCount(), item) # checkBox = QCheckBox(self) # checkBox.setText(captionStr) # checkBox.setChecked(isCheckedFlag) # checkBox.clicked.connect(self.checkBox_clicked) # self.hLayout.addWidget(checkBox) def GetItemChecked(self, index): if self.stdModel.rowCount() > 0: item = self.stdModel.item(index) if item.checkState() == Qt.Unchecked: return False return True return False def get_CheckedItems(self): if not self.stdModel.rowCount() > 0: return [] resultCheckedItems = [] for i in range(self.stdModel.rowCount()): item = self.stdModel.item(i) if item.checkState() == Qt.Checked: flag = False if self.hasObject: for obj in self.objList: if obj[0] == i: resultCheckedItems.append(obj) flag = True break if not flag: resultCheckedItems.append(item) return resultCheckedItems CheckedItems = property(get_CheckedItems, None, None, None) def get_Items(self): if not self.stdModel.rowCount() > 0: return None resultItems = [] for i in range(self.stdModel.rowCount()): item = self.stdModel.item(i) flag = False if self.hasObject: for obj in self.objList: if obj[0] == i: resultItems.append(obj) flag = True break if not flag: resultItems.append(item.text()) return resultItems Items = property(get_Items, None, None, None) def get_Enabled(self): return self.isEnabled() def set_Enabled(self, bool): self.setEnabled(bool) Enabled = property(get_Enabled, set_Enabled, None, None) def get_Visible(self): return self.isVisible() def set_Visible(self, bool): self.setVisible(bool) Visible = property(get_Visible, set_Visible, None, None)
class Regression_PLOT_PyQt(QDialog): """ This calss return a PyQt GUI with a regression plot """ def __init__(self, Minerals=None, string=None, flag=None): super(Regression_PLOT_PyQt, self).__init__() if string is not None: self.stringK, self.stringG, self.stringRho, self.user_input = string else: self.stringK = None self.stringG = None self.stringRho = None self.user_input = False self.resize(1400, 600) self.Minerals = Minerals self.dirty = False #self.user_input = user_input self.Minerals.original_flag() self.Minerals.read_data() self.table = QTableView() self.model = QStandardItemModel(25, 7, self) self.model.setHorizontalHeaderLabels([ 'flag', 'Water Content', 'Iron Content', 'K (Gpa)', 'G (Gpa)', 'Rho (g/cm³)', 'Reference' ]) for i in range(len(self.Minerals.Flag)): a = self.Minerals.Return_original_data(i) for j in range(0, 7): item = QStandardItem(str(a[j])) self.model.setItem(i, j, item) if j != 0: item.setFlags(Qt.ItemIsEnabled) item.setBackground(QColor(211, 211, 211)) if flag is not None: self.Minerals.change_flag(flag) for i in range(len(self.Minerals.Flag)): item = QStandardItem(str(self.Minerals.Flag[i])) self.model.setItem(i, 0, item) self.table.setModel(self.model) self.button = QPushButton('Update and use in thermoelastic model') self.button.clicked.connect(self.Update) self.button.setAutoDefault(False) self.button1 = QPushButton('Add data file ') self.button1.clicked.connect(self.Export) self.button1.setAutoDefault(False) self.layout = QGridLayout() self.label = QLabel() self.label.setText(''' Please input equation, Water: water content (wt%) and Fe: iron content (mol%) for example -2.41*Water-30*Fe+81,K'=4.1, ''') self.Kinput_formula = QLineEdit() self.Ginput_formula = QLineEdit() self.Rhoinput_formula = QLineEdit() if self.stringK is not None: self.Kinput_formula.setText(self.stringK) self.Ginput_formula.setText(self.stringG) self.Rhoinput_formula.setText(self.stringRho) self.Userinput() else: self.Kinput_formula.setText( self.Minerals.Show_fit_function(self.Minerals.function_K()[0], self.Minerals.function_K()[1], "K'", error=False)) self.Ginput_formula.setText( self.Minerals.Show_fit_function(self.Minerals.function_G()[0], self.Minerals.function_G()[1], "G'", error=False)) self.Rhoinput_formula.setText( self.Minerals.Show_fit_function( self.Minerals.function_Rho()[0], self.Minerals.function_Rho()[1], '', error=False)) self.Kinput_formula.returnPressed.connect(self.Kformula) self.Ginput_formula.returnPressed.connect(self.Gformula) self.Rhoinput_formula.returnPressed.connect(self.Rhoformula) #self.connect(self.Kinput_formula,SIGNAL("returnPressed()"),self.Kformula) #self.connect(self.Ginput_formula,SIGNAL("returnPressed()"),self.Gformula) #self.connect(self.Rhoinput_formula,SIGNAL("returnPressed()"),self.Rhoformula) self.user_change_confrim = QPushButton('Change to user input') self.user_change_confrim.clicked.connect(self.Userinput) self.user_change_confrim.setAutoDefault(False) self.extension = QWidget() self.extensionLayout = QGridLayout() self.extensionLayout.setContentsMargins(0, 0, 0, 0) labelK = QLabel() labelK.setText('K<sub>0</sub>=') labelG = QLabel() labelG.setText('G<sub>0</sub>=') labelRho = QLabel() labelRho.setText('Rho<sub>0</sub>=') self.extensionLayout.addWidget(labelK, 0, 0, 1, 3) self.extensionLayout.addWidget(labelG, 1, 0, 1, 3) self.extensionLayout.addWidget(labelRho, 2, 0, 1, 3) self.extensionLayout.addWidget(self.Kinput_formula, 0, 1, 1, 3) self.extensionLayout.addWidget(self.Ginput_formula, 1, 1, 1, 3) self.extensionLayout.addWidget(self.Rhoinput_formula, 2, 1, 1, 3) self.extensionLayout.addWidget(self.user_change_confrim, 3, 0, 9, 4) self.extension.setLayout(self.extensionLayout) self.check_change = QCheckBox("user input") self.check_change.setChecked(False) self.check_change.toggled.connect(self.extension.setVisible) #self.PLOT(switch=True) self.PLOT() self.layout.addWidget(self.table, 0, 1, 1, 17) self.layout.addWidget(self.button, 2, 0, 1, 9) self.layout.addWidget(self.button1, 2, 9, 1, 9) self.layout.addWidget(self.check_change, 3, 0, 1, 1) self.layout.addWidget(self.label, 3, 3, 1, 5) self.layout.addWidget(self.extension, 4, 0, 1, 9) self.setLayout(self.layout) self.extension.hide() def Kformula(self): self.stringK = str(self.Kinput_formula.text()) self.K0 = np.array( re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", self.stringK)) return self.K0, self.stringK def Gformula(self): self.stringG = str(self.Ginput_formula.text()) self.G0 = np.array( re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", self.stringG)) return self.G0, self.stringG def Rhoformula(self): self.stringRho = str(self.Rhoinput_formula.text()) self.Rho0 = np.array( re.findall(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", self.stringRho)) return self.Rho0, self.stringRho def Userinput(self): self.Minerals.User_Change(self.Kformula(), self.Gformula(), self.Rhoformula()) self.user_input = True self.PLOT() def PLOT(self, switch=True): if self.dirty == False: #self.Minerals.Clean_content() params = [] for i in range(20): index = self.model.index(i, 0) try: aa = (float(self.model.itemData(index)[0])) #print (aa) params.append(aa) except: break #print (params) self.Minerals.Change_data_from_table(params) #print ('wf') else: self.model.setHorizontalHeaderLabels([ 'flag', 'Water Content', 'Iron Content', 'K (Gpa)', 'G (Gpa)', 'Rho (g/cm3)', 'Reference' ]) for i in range(len(self.Minerals.Flag)): #a=self.Minerals.Return_original_data(i) item = QStandardItem(str(self.Minerals.Flag[i])) self.model.setItem(i, 0, item) #============================================================================== # for j in range(1,7): # item = QStandardItem(str(a[j])) # self.model.setItem(i, j,item) # if j != 0: # item.setFlags(Qt.ItemIsEnabled) # item.setBackground(QColor(211,211,211)) #============================================================================== #print (self.Minerals.Change) if self.user_input == False: self.a, self.b, self.c = self.Minerals.PLOT(return_fig=False) #print (self.Minerals.number_of_data) self.Kinput_formula.setText( self.Minerals.Show_fit_function(self.Minerals.function_K()[0], self.Minerals.function_K()[1], "K'", error=False)) self.Ginput_formula.setText( self.Minerals.Show_fit_function(self.Minerals.function_G()[0], self.Minerals.function_G()[1], "G'", error=False)) self.Rhoinput_formula.setText( self.Minerals.Show_fit_function( self.Minerals.function_Rho()[0], self.Minerals.function_Rho()[1], '', error=False)) else: self.a, self.b, self.c = self.Minerals.PLOT_input_formula( return_fig=False) self.canvas1 = FigureCanvas3D(self.a) self.canvas2 = FigureCanvas3D(self.b) self.canvas3 = FigureCanvas3D(self.c) self.canvas1.mpl_connect('pick_event', self.onpick) self.canvas2.mpl_connect('pick_event', self.onpick) self.canvas3.mpl_connect('pick_event', self.onpick) self.toolbar1 = NavigationToolbar(self.canvas1, self) self.toolbar2 = NavigationToolbar(self.canvas2, self) self.toolbar3 = NavigationToolbar(self.canvas3, self) self.layout1_widget = QWidget() self.layout1 = QGridLayout(self.layout1_widget) self.layout1_widget.setFixedSize(600, 600) self.layout1.addWidget(self.canvas1, 0, 1, 5, 5) self.layout1.addWidget(self.toolbar1, 5, 1, 1, 5) self.layout1.addWidget(self.canvas2, 6, 1, 5, 5) self.layout1.addWidget(self.toolbar2, 11, 1, 1, 5) self.layout1.addWidget(self.canvas3, 12, 1, 5, 5) self.layout1.addWidget(self.toolbar3, 17, 1, 1, 5) self.layout.addWidget(self.layout1_widget, 0, 0, 1, 1) def onpick(self, event): try: for i in range(6): self.model.item(self.ind, i + 1).setBackground(QColor(211, 211, 211)) except: pass count = -1 for j in range(len((self.Minerals.Flag))): if self.Minerals.Flag[j] == 1: count += 1 if count == event.ind[0]: self.ind = j break #print (self.ind) #self.ind = event.ind for i in range(6): self.model.item(self.ind, i + 1).setBackground(QColor(111, 111, 111)) def Update(self): self.user_input = False self.dirty = False self.check_change.setChecked(False) self.PLOT() def Export(self): self.dirty = True dialog = TextEditor(name=self.Minerals.name) if dialog.exec_(): pass self.Minerals.read_data() self.PLOT() def ReturnString(self): aa = self.Minerals.Flag bb = str(int(aa[0])) for i in range(1, len(aa)): bb += str(int(aa[i])) return [self.stringK, self.stringG, self.stringRho, self.user_input], bb
class OWConfusionMatrix(widget.OWWidget): """Confusion matrix widget""" name = "Confusion Matrix" description = "Display a confusion matrix constructed from " \ "the results of classifier evaluations." icon = "icons/ConfusionMatrix.svg" priority = 1001 inputs = [("Evaluation Results", Orange.evaluation.Results, "set_results")] outputs = [("Selected Data", Orange.data.Table)] quantities = ["Number of instances", "Proportion of predicted", "Proportion of actual"] settingsHandler = settings.ClassValuesContextHandler() selected_learner = settings.Setting([0], schema_only=True) selection = settings.ContextSetting(set()) selected_quantity = settings.Setting(0) append_predictions = settings.Setting(True) append_probabilities = settings.Setting(False) autocommit = settings.Setting(True) UserAdviceMessages = [ widget.Message( "Clicking on cells or in headers outputs the corresponding " "data instances", "click_cell")] def __init__(self): super().__init__() self.data = None self.results = None self.learners = [] self.headers = [] box = gui.vBox(self.controlArea, "Learners") self.learners_box = gui.listBox( box, self, "selected_learner", "learners", callback=self._learner_changed ) box = gui.vBox(self.controlArea, "Show") gui.comboBox(box, self, "selected_quantity", items=self.quantities, callback=self._update) box = gui.vBox(self.controlArea, "Select") gui.button(box, self, "Select Correct", callback=self.select_correct, autoDefault=False) gui.button(box, self, "Select Misclassified", callback=self.select_wrong, autoDefault=False) gui.button(box, self, "Clear Selection", callback=self.select_none, autoDefault=False) self.outputbox = box = gui.vBox(self.controlArea, "Output") gui.checkBox(box, self, "append_predictions", "Predictions", callback=self._invalidate) gui.checkBox(box, self, "append_probabilities", "Probabilities", callback=self._invalidate) gui.auto_commit(self.controlArea, self, "autocommit", "Send Selected", "Send Automatically") grid = QGridLayout() self.tablemodel = QStandardItemModel(self) view = self.tableview = QTableView( editTriggers=QTableView.NoEditTriggers) view.setModel(self.tablemodel) view.horizontalHeader().hide() view.verticalHeader().hide() view.horizontalHeader().setMinimumSectionSize(60) view.selectionModel().selectionChanged.connect(self._invalidate) view.setShowGrid(False) view.setItemDelegate(BorderedItemDelegate(Qt.white)) view.clicked.connect(self.cell_clicked) grid.addWidget(view, 0, 0) self.mainArea.layout().addLayout(grid) def sizeHint(self): """Initial size""" return QSize(750, 490) def _item(self, i, j): return self.tablemodel.item(i, j) or QStandardItem() def _set_item(self, i, j, item): self.tablemodel.setItem(i, j, item) def _init_table(self, nclasses): item = self._item(0, 2) item.setData("Predicted", Qt.DisplayRole) item.setTextAlignment(Qt.AlignCenter) item.setFlags(Qt.NoItemFlags) self._set_item(0, 2, item) item = self._item(2, 0) item.setData("Actual", Qt.DisplayRole) item.setTextAlignment(Qt.AlignHCenter | Qt.AlignBottom) item.setFlags(Qt.NoItemFlags) self.tableview.setItemDelegateForColumn(0, gui.VerticalItemDelegate()) self._set_item(2, 0, item) self.tableview.setSpan(0, 2, 1, nclasses) self.tableview.setSpan(2, 0, nclasses, 1) font = self.tablemodel.invisibleRootItem().font() bold_font = QFont(font) bold_font.setBold(True) for i in (0, 1): for j in (0, 1): item = self._item(i, j) item.setFlags(Qt.NoItemFlags) self._set_item(i, j, item) for p, label in enumerate(self.headers): for i, j in ((1, p + 2), (p + 2, 1)): item = self._item(i, j) item.setData(label, Qt.DisplayRole) item.setFont(bold_font) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) if p < len(self.headers) - 1: item.setData("br"[j == 1], BorderRole) item.setData(QColor(192, 192, 192), BorderColorRole) self._set_item(i, j, item) hor_header = self.tableview.horizontalHeader() if len(' '.join(self.headers)) < 120: hor_header.setResizeMode(QHeaderView.ResizeToContents) else: hor_header.setDefaultSectionSize(60) self.tablemodel.setRowCount(nclasses + 3) self.tablemodel.setColumnCount(nclasses + 3) def set_results(self, results): """Set the input results.""" prev_sel_learner = self.selected_learner.copy() self.clear() self.warning() self.closeContext() data = None if results is not None and results.data is not None: data = results.data if data is not None and not data.domain.has_discrete_class: self.warning("Confusion Matrix cannot show regression results.") self.results = results self.data = data if data is not None: class_values = data.domain.class_var.values elif results is not None: raise NotImplementedError if results is None: self.report_button.setDisabled(True) else: self.report_button.setDisabled(False) nmodels = results.predicted.shape[0] self.headers = class_values + \ [unicodedata.lookup("N-ARY SUMMATION")] # NOTE: The 'learner_names' is set in 'Test Learners' widget. if hasattr(results, "learner_names"): self.learners = results.learner_names else: self.learners = ["Learner #{}".format(i + 1) for i in range(nmodels)] self._init_table(len(class_values)) self.openContext(data.domain.class_var) if not prev_sel_learner or prev_sel_learner[0] >= len(self.learners): self.selected_learner[:] = [0] else: self.selected_learner[:] = prev_sel_learner self._update() self._set_selection() self.unconditional_commit() def clear(self): """Reset the widget, clear controls""" self.results = None self.data = None self.tablemodel.clear() self.headers = [] # Clear learners last. This action will invoke `_learner_changed` self.learners = [] def select_correct(self): """Select the diagonal elements of the matrix""" selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): index = self.tablemodel.index(i, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def select_wrong(self): """Select the off-diagonal elements of the matrix""" selection = QItemSelection() n = self.tablemodel.rowCount() for i in range(2, n): for j in range(i + 1, n): index = self.tablemodel.index(i, j) selection.select(index, index) index = self.tablemodel.index(j, i) selection.select(index, index) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def select_none(self): """Reset selection""" self.tableview.selectionModel().clear() def cell_clicked(self, model_index): """Handle cell click event""" i, j = model_index.row(), model_index.column() if not i or not j: return n = self.tablemodel.rowCount() index = self.tablemodel.index selection = None if i == j == 1 or i == j == n - 1: selection = QItemSelection(index(2, 2), index(n - 1, n - 1)) elif i in (1, n - 1): selection = QItemSelection(index(2, j), index(n - 1, j)) elif j in (1, n - 1): selection = QItemSelection(index(i, 2), index(i, n - 1)) if selection is not None: self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def commit(self): """Output data instances corresponding to selected cells""" if self.results is not None and self.data is not None \ and self.selected_learner: indices = self.tableview.selectedIndexes() indices = {(ind.row() - 2, ind.column() - 2) for ind in indices} actual = self.results.actual learner_name = self.learners[self.selected_learner[0]] predicted = self.results.predicted[self.selected_learner[0]] selected = [i for i, t in enumerate(zip(actual, predicted)) if t in indices] row_indices = self.results.row_indices[selected] extra = [] class_var = self.data.domain.class_var metas = self.data.domain.metas if self.append_predictions: predicted = numpy.array(predicted[selected], dtype=object) extra.append(predicted.reshape(-1, 1)) var = Orange.data.DiscreteVariable( "{}({})".format(class_var.name, learner_name), class_var.values ) metas = metas + (var,) if self.append_probabilities and \ self.results.probabilities is not None: probs = self.results.probabilities[self.selected_learner[0], selected] extra.append(numpy.array(probs, dtype=object)) pvars = [Orange.data.ContinuousVariable("p({})".format(value)) for value in class_var.values] metas = metas + tuple(pvars) X = self.data.X[row_indices] Y = self.data.Y[row_indices] M = self.data.metas[row_indices] row_ids = self.data.ids[row_indices] M = numpy.hstack((M,) + tuple(extra)) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, metas ) data = Orange.data.Table.from_numpy(domain, X, Y, M) data.ids = row_ids data.name = learner_name else: data = None self.send("Selected Data", data) def _invalidate(self): indices = self.tableview.selectedIndexes() self.selection = {(ind.row() - 2, ind.column() - 2) for ind in indices} self.commit() def _set_selection(self): selection = QItemSelection() index = self.tableview.model().index for row, col in self.selection: sel = index(row + 2, col + 2) selection.select(sel, sel) self.tableview.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def _learner_changed(self): self._update() self._set_selection() self.commit() def _update(self): def _isinvalid(x): return isnan(x) or isinf(x) # Update the displayed confusion matrix if self.results is not None and self.selected_learner: cmatrix = confusion_matrix(self.results, self.selected_learner[0]) colsum = cmatrix.sum(axis=0) rowsum = cmatrix.sum(axis=1) n = len(cmatrix) diag = numpy.diag_indices(n) colors = cmatrix.astype(numpy.double) colors[diag] = 0 if self.selected_quantity == 0: normalized = cmatrix.astype(numpy.int) formatstr = "{}" div = numpy.array([colors.max()]) else: if self.selected_quantity == 1: normalized = 100 * cmatrix / colsum div = colors.max(axis=0) else: normalized = 100 * cmatrix / rowsum[:, numpy.newaxis] div = colors.max(axis=1)[:, numpy.newaxis] formatstr = "{:2.1f} %" div[div == 0] = 1 colors /= div colors[diag] = normalized[diag] / normalized[diag].max() for i in range(n): for j in range(n): val = normalized[i, j] col_val = colors[i, j] item = self._item(i + 2, j + 2) item.setData( "NA" if _isinvalid(val) else formatstr.format(val), Qt.DisplayRole) bkcolor = QColor.fromHsl( [0, 240][i == j], 160, 255 if _isinvalid(col_val) else int(255 - 30 * col_val)) item.setData(QBrush(bkcolor), Qt.BackgroundRole) item.setData("trbl", BorderRole) item.setToolTip("actual: {}\npredicted: {}".format( self.headers[i], self.headers[j])) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self._set_item(i + 2, j + 2, item) bold_font = self.tablemodel.invisibleRootItem().font() bold_font.setBold(True) def _sum_item(value, border=""): item = QStandardItem() item.setData(value, Qt.DisplayRole) item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) item.setFlags(Qt.ItemIsEnabled) item.setFont(bold_font) item.setData(border, BorderRole) item.setData(QColor(192, 192, 192), BorderColorRole) return item for i in range(n): self._set_item(n + 2, i + 2, _sum_item(int(colsum[i]), "t")) self._set_item(i + 2, n + 2, _sum_item(int(rowsum[i]), "l")) self._set_item(n + 2, n + 2, _sum_item(int(rowsum.sum()))) def send_report(self): """Send report""" if self.results is not None and self.selected_learner: self.report_table( "Confusion matrix for {} (showing {})". format(self.learners[self.selected_learner[0]], self.quantities[self.selected_quantity].lower()), self.tableview)
class DlgSqlLayerWindow(QWidget, Ui_Dialog): nameChanged = pyqtSignal(str) def __init__(self, iface, layer, parent=None): QWidget.__init__(self, parent) self.iface = iface self.layer = layer uri = QgsDataSourceURI(layer.source()) dbplugin = None db = None if layer.dataProvider().name() == 'postgres': dbplugin = createDbPlugin('postgis', 'postgres') elif layer.dataProvider().name() == 'spatialite': dbplugin = createDbPlugin('spatialite', 'spatialite') elif layer.dataProvider().name() == 'oracle': dbplugin = createDbPlugin('oracle', 'oracle') elif layer.dataProvider().name() == 'virtual': dbplugin = createDbPlugin('vlayers', 'virtual') elif layer.dataProvider().name() == 'ogr': dbplugin = createDbPlugin('gpkg', 'gpkg') if dbplugin: dbplugin.connectToUri(uri) db = dbplugin.db self.dbplugin = dbplugin self.db = db self.filter = "" self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostgreSQL allows a primary key to span multiple columns, spatialite doesn't self.aliasSubQuery = isinstance(db, PGDatabase) # only PostgreSQL requires subqueries to be aliases self.setupUi(self) self.setWindowTitle( u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString())) self.defaultLayerName = 'QueryLayer' if self.allowMultiColumnPk: self.uniqueColumnCheck.setText(self.trUtf8("Column(s) with unique values")) else: self.uniqueColumnCheck.setText(self.trUtf8("Column with unique values")) self.editSql.setFocus() self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.editSql.setMarginVisible(True) self.initCompleter() # allow copying results copyAction = QAction("copy", self) self.viewResult.addAction(copyAction) copyAction.setShortcuts(QKeySequence.Copy) copyAction.triggered.connect(self.copySelectedResults) self.btnExecute.clicked.connect(self.executeSql) self.btnSetFilter.clicked.connect(self.setFilter) self.btnClear.clicked.connect(self.clearSql) self.presetStore.clicked.connect(self.storePreset) self.presetDelete.clicked.connect(self.deletePreset) self.presetCombo.activated[str].connect(self.loadPreset) self.presetCombo.activated[str].connect(self.presetName.setText) self.updatePresetsCombobox() self.geomCombo.setEditable(True) self.geomCombo.lineEdit().setReadOnly(True) self.uniqueCombo.setEditable(True) self.uniqueCombo.lineEdit().setReadOnly(True) self.uniqueModel = QStandardItemModel(self.uniqueCombo) self.uniqueCombo.setModel(self.uniqueModel) if self.allowMultiColumnPk: self.uniqueCombo.setItemDelegate(QStyledItemDelegate()) self.uniqueModel.itemChanged.connect(self.uniqueChanged) # react to the (un)checking of an item self.uniqueCombo.lineEdit().textChanged.connect(self.uniqueTextChanged) # there are other events that change the displayed text and some of them can not be caught directly self.layerTypeWidget.hide() # show if load as raster is supported #self.loadLayerBtn.clicked.connect(self.loadSqlLayer) self.updateLayerBtn.clicked.connect(self.updateSqlLayer) self.getColumnsBtn.clicked.connect(self.fillColumnCombos) self.queryBuilderFirst = True self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif")) self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder) self.presetName.textChanged.connect(self.nameChanged) # Update from layer # Fisrtly the SQL from QgsDataSourceURI table sql = uri.table() if uri.keyColumn() == '_uid_': match = re.search('^\(SELECT .+ AS _uid_,\* FROM \((.*)\) AS _subq_.+_\s*\)$', sql, re.S) if match: sql = match.group(1) else: match = re.search('^\((SELECT .+ FROM .+)\)$', sql, re.S) if match: sql = match.group(1) self.editSql.setText(sql) self.executeSql() # Then the columns self.geomCombo.setCurrentIndex(self.geomCombo.findText(uri.geometryColumn(), Qt.MatchExactly)) if uri.keyColumn() != '_uid_': self.uniqueColumnCheck.setCheckState(Qt.Checked) if self.allowMultiColumnPk: itemsData = uri.keyColumn().split(',') for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.data() in itemsData: item.setCheckState(Qt.Checked) else: keyColumn = uri.keyColumn() if self.uniqueModel.findItems(keyColumn): self.uniqueCombo.setEditText(keyColumn) # Finally layer name, filter and selectAtId self.layerNameEdit.setText(layer.name()) self.filter = uri.sql() if uri.selectAtIdDisabled(): self.avoidSelectById.setCheckState(Qt.Checked) def updatePresetsCombobox(self): self.presetCombo.clear() names = [] entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries') for entry in entries: name = QgsProject.instance().readEntry('DBManager', 'savedQueries/' + entry + '/name')[0] names.append(name) for name in sorted(names): self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(-1) def storePreset(self): query = self._getSqlQuery() if query == "": return name = self.presetName.text() QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name', name) QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query', query) index = self.presetCombo.findText(name) if index == -1: self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1) else: self.presetCombo.setCurrentIndex(index) def deletePreset(self): name = self.presetCombo.currentText() QgsProject.instance().removeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__())) self.presetCombo.removeItem(self.presetCombo.findText(name)) self.presetCombo.setCurrentIndex(-1) def loadPreset(self, name): query = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query')[0] name = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name')[0] self.editSql.setText(query) def clearSql(self): self.editSql.clear() self.editSql.setFocus() self.filter = "" def executeSql(self): sql = self._getSqlQuery() if sql == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # delete the old model old_model = self.viewResult.model() self.viewResult.setModel(None) if old_model: old_model.deleteLater() cols = [] quotedCols = [] try: # set the new model model = self.db.sqlResultModel(sql, self) self.viewResult.setModel(model) self.lblResult.setText(self.tr("%d rows, %.1f seconds") % (model.affectedRows(), model.secs())) cols = self.viewResult.model().columnNames() for col in cols: quotedCols.append(self.db.connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return self.setColumnCombos(cols, quotedCols) self.update() QApplication.restoreOverrideCursor() def _getSqlLayer(self, _filter): hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked if hasUniqueField: if self.allowMultiColumnPk: checkedCols = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedCols.append(item.data()) uniqueFieldName = ",".join(checkedCols) elif self.uniqueCombo.currentIndex() >= 0: uniqueFieldName = self.uniqueModel.item(self.uniqueCombo.currentIndex()).data() else: uniqueFieldName = None else: uniqueFieldName = None hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked if hasGeomCol: geomFieldName = self.geomCombo.currentText() else: geomFieldName = None query = self._getSqlQuery() if query == "": return None # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] from qgis.core import QgsMapLayer, QgsMapLayerRegistry layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer # get a new layer name names = [] for layer in QgsMapLayerRegistry.instance().mapLayers().values(): names.append(layer.name()) layerName = self.layerNameEdit.text() if layerName == "": layerName = self.defaultLayerName newLayerName = layerName index = 1 while newLayerName in names: index += 1 newLayerName = u"%s_%d" % (layerName, index) # create the layer layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType, self.avoidSelectById.isChecked(), _filter) if layer.isValid(): return layer else: return None def loadSqlLayer(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: layer = self._getSqlLayer(self.filter) if layer == None: return from qgis.core import QgsMapLayerRegistry QgsMapLayerRegistry.instance().addMapLayers([layer], True) finally: QApplication.restoreOverrideCursor() def updateSqlLayer(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) try: layer = self._getSqlLayer(self.filter) if layer == None: return #self.layer.dataProvider().setDataSourceUri(layer.dataProvider().dataSourceUri()) #self.layer.dataProvider().reloadData() XMLDocument = QDomDocument("style") XMLMapLayers = XMLDocument.createElement("maplayers") XMLMapLayer = XMLDocument.createElement("maplayer") self.layer.writeLayerXML(XMLMapLayer, XMLDocument) XMLMapLayer.firstChildElement("datasource").firstChild().setNodeValue(layer.source()) XMLMapLayers.appendChild(XMLMapLayer) XMLDocument.appendChild(XMLMapLayers) self.layer.readLayerXML(XMLMapLayer) self.layer.reload() self.iface.actionDraw().trigger() self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(layer) finally: QApplication.restoreOverrideCursor() def fillColumnCombos(self): query = self._getSqlQuery() if query == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] # get all the columns cols = [] quotedCols = [] connector = self.db.connector if self.aliasSubQuery: # get a new alias aliasIndex = 0 while True: alias = "_subQuery__%d" % aliasIndex escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b') if not escaped.search(query): break aliasIndex += 1 sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % (unicode(query), connector.quoteId(alias)) else: sql = u"SELECT * FROM (%s\n) WHERE 1=0" % unicode(query) c = None try: c = connector._execute(None, sql) cols = connector._get_cursor_columns(c) for col in cols: quotedCols.append(connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return finally: if c: c.close() del c self.setColumnCombos(cols, quotedCols) QApplication.restoreOverrideCursor() def setColumnCombos(self, cols, quotedCols): # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first) try: defaultGeomCol = next(col for col in cols if col in ['geom', 'geometry', 'the_geom', 'way']) except: defaultGeomCol = None try: defaultUniqueCol = [col for col in cols if 'id' in col][0] except: defaultUniqueCol = None colNames = sorted(zip(cols, quotedCols)) newItems = [] uniqueIsFilled = False for (col, quotedCol) in colNames: item = QStandardItem(col) item.setData(quotedCol) item.setEnabled(True) item.setCheckable(self.allowMultiColumnPk) item.setSelectable(not self.allowMultiColumnPk) if self.allowMultiColumnPk: matchingItems = self.uniqueModel.findItems(col) if matchingItems: item.setCheckState(matchingItems[0].checkState()) uniqueIsFilled = uniqueIsFilled or matchingItems[0].checkState() == Qt.Checked else: item.setCheckState(Qt.Unchecked) newItems.append(item) if self.allowMultiColumnPk: self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) self.uniqueChanged() else: previousUniqueColumn = self.uniqueCombo.currentText() self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) if self.uniqueModel.findItems(previousUniqueColumn): self.uniqueCombo.setEditText(previousUniqueColumn) uniqueIsFilled = True oldGeometryColumn = self.geomCombo.currentText() self.geomCombo.clear() self.geomCombo.addItems(cols) self.geomCombo.setCurrentIndex(self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly)) # set sensible default columns if the columns are not already set try: if self.geomCombo.currentIndex() == -1: self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol)) except: pass items = self.uniqueModel.findItems(defaultUniqueCol) if items and not uniqueIsFilled: if self.allowMultiColumnPk: items[0].setCheckState(Qt.Checked) else: self.uniqueCombo.setEditText(defaultUniqueCol) try: pass except: pass def copySelectedResults(self): if len(self.viewResult.selectedIndexes()) <= 0: return model = self.viewResult.model() # convert to string using tab as separator text = model.headerToString("\t") for idx in self.viewResult.selectionModel().selectedRows(): text += "\n" + model.rowToString(idx.row(), "\t") QApplication.clipboard().setText(text, QClipboard.Selection) QApplication.clipboard().setText(text, QClipboard.Clipboard) def initCompleter(self): dictionary = None if self.db: dictionary = self.db.connector.getSqlDictionary() if not dictionary: # use the generic sql dictionary from .sql_dictionary import getSqlDictionary dictionary = getSqlDictionary() wordlist = [] for name, value in dictionary.iteritems(): wordlist += value # concat lists wordlist = list(set(wordlist)) # remove duplicates api = QsciAPIs(self.editSql.lexer()) for word in wordlist: api.add(word) api.prepare() self.editSql.lexer().setAPIs(api) def displayQueryBuilder(self): dlg = QueryBuilderDlg(self.iface, self.db, self, reset=self.queryBuilderFirst) self.queryBuilderFirst = False r = dlg.exec_() if r == QDialog.Accepted: self.editSql.setText(dlg.query) def _getSqlQuery(self): sql = self.editSql.selectedText() if len(sql) == 0: sql = self.editSql.text() return sql def uniqueChanged(self): # when an item is (un)checked, simply trigger an update of the combobox text self.uniqueTextChanged(None) def uniqueTextChanged(self, text): # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one. checkedItems = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedItems.append(item.text()) label = ", ".join(checkedItems) if text != label: self.uniqueCombo.setEditText(label) def setFilter(self): from qgis.gui import QgsQueryBuilder layer = self._getSqlLayer("") if not layer: return dlg = QgsQueryBuilder(layer) dlg.setSql(self.filter) if dlg.exec_(): self.filter = dlg.sql() layer.deleteLater()
class ConnectionsDialog(QtGui.QDialog, Ui_DlgConnections): on_connect = pyqtSignal(str, str) on_add = pyqtSignal(str, list) on_connection_change = pyqtSignal() on_zoom_change = pyqtSignal() _connections_array = "connections" _table_headers = OrderedDict([("ID", "id"), ("Min. Zoom", "minzoom"), ("Max. Zoom", "maxzoom"), ("Description", "description")]) _OMT = "OpenMapTiles.com" _predefined_connections = { _OMT: "https://free.tilehosting.com/data/v3.json?key={token}" } _tokens = {_OMT: "6irhAXGgsi8TrIDL0211"} def __init__(self, default_browse_directory): QtGui.QDialog.__init__(self) self.setupUi(self) self.options = OptionsGroup(self.grpOptions, self._on_zoom_change) self.settings = QSettings("VtrSettings") self.connections = {} self.selected_connection = None self.selected_layer_id = None self.cbxConnections.currentIndexChanged['QString'].connect( self._handle_connection_change) self.btnCreateConnection.clicked.connect(self._create_connection) self.btnConnect.clicked.connect(self._handle_connect) self.btnEdit.clicked.connect(self._edit_connection) self.btnDelete.clicked.connect(self._delete_connection) self.btnAdd.clicked.connect(self._load_tiles_for_connection) self.btnSave.clicked.connect(self._export_connections) self.btnLoad.clicked.connect(self._import_connections) self.btnHelp.clicked.connect(lambda: webbrowser.open(_HELP_URL)) self.btnBrowse.clicked.connect(self._select_file_path) self.btnBrowseTrexCache.clicked.connect(self._select_trex_cache_folder) self.open_path = None self.browse_path = default_browse_directory self.model = QStandardItemModel() self.model.setHorizontalHeaderLabels(self._table_headers.keys()) self.tblLayers.setModel(self.model) self._load_connections() self._add_loaded_connections() self.edit_connection_dialog = EditConnectionDialog() _update_size(self) def _select_file_path(self): open_file_name = QFileDialog.getOpenFileName( None, "Select Mapbox Tiles", self.browse_path, "Mapbox Tiles (*.mbtiles)") if open_file_name and os.path.isfile(open_file_name): self.txtPath.setText(open_file_name) self._handle_path_or_folder_selection(open_file_name) def _select_trex_cache_folder(self): open_file_name = QFileDialog.getExistingDirectory( None, "Select t-rex Cache directory", self.browse_path) if open_file_name and os.path.isdir(open_file_name): self.txtTrexCachePath.setText(open_file_name) self._handle_path_or_folder_selection(open_file_name) def _handle_path_or_folder_selection(self, path): self.browse_path = path self.open_path = path name = os.path.basename(path) self.on_connect.emit(name, path) def _on_zoom_change(self): self.on_zoom_change.emit() def set_nr_of_tiles(self, nr_tiles): self.options.set_nr_of_tiles(nr_tiles) def _load_tiles_for_connection(self): indexes = self.tblLayers.selectionModel().selectedRows() selected_layers = map(lambda i: self.model.item(i.row()).text(), indexes) name, url = self._get_current_connection() self.on_add.emit(url, selected_layers) def _export_connections(self): file_name = QFileDialog.getSaveFileName( None, "Export Vector Tile Reader Connections", "", "csv (*.csv)") if file_name: with open(file_name, 'w') as csvfile: fieldnames = ['name', 'url'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for name in self.connections: writer.writerow({ 'name': name, 'url': self.connections[name] }) def _import_connections(self): file_name = QFileDialog.getOpenFileName( None, "Export Vector Tile Reader Connections", "", "csv (*.csv)") if file_name: with open(file_name, 'r') as csvfile: reader = csv.DictReader(csvfile) for row in reader: self._set_connection_url(row['name'], row['url']) self._add_loaded_connections() def _load_connections(self): settings = self.settings connections = settings.beginReadArray(self._connections_array) for i in range(connections): settings.setArrayIndex(i) name = settings.value("name") url = settings.value("url") self._set_connection_url(name, url) settings.endArray() def _add_loaded_connections(self): for index, name in enumerate(self._predefined_connections.keys()): url = self._predefined_connections[name] self._set_connection_url(name, url) for name in sorted(self.connections): is_already_added = self.cbxConnections.findText(name) != -1 if not is_already_added: self.cbxConnections.addItem(name) if len(self.connections) > 0: self.cbxConnections.setCurrentIndex(0) def _delete_connection(self): index = self.cbxConnections.currentIndex() connection = self.cbxConnections.currentText() msg = "Are you sure you want to remove the connection '{}' and all associated settings?".format( connection) reply = QMessageBox.question(self.activateWindow(), 'Confirm Delete', msg, QMessageBox.Yes, QMessageBox.No) if reply == QtGui.QMessageBox.Yes: self.cbxConnections.removeItem(index) self.connections.pop(connection) self._save_connections() def _save_connections(self): settings = self.settings settings.beginWriteArray(self._connections_array) for index, key in enumerate(self.connections): settings.setArrayIndex(index) settings.setValue("name", key) settings.setValue("url", self.connections[key]) settings.endArray() def _set_connection_url(self, name, url): self.connections[name] = url def _handle_connect(self): conn = self._get_current_connection() name = conn[0] url = conn[1] self.on_connect.emit(name, url) self.txtPath.setText("") def _get_current_connection(self): if self.tabServer.isEnabled(): name = self.cbxConnections.currentText() url = self.connections[name] elif self.tabFile.isEnabled(): url = self.txtPath.text() name = os.path.basename(url) else: url = self.txtTrexCachePath.text() name = os.path.basename(url) if name in self._predefined_connections: url = url.replace("{token}", self._tokens[name]) return name, url def show(self): self.exec_() def keep_dialog_open(self): return self.chkKeepOpen.isChecked() def set_layers(self, layers): self.model.removeRows(0, self.model.rowCount()) for row_index, layer in enumerate(layers): for header_index, header in enumerate(self._table_headers.keys()): header_value = self._table_headers[header] if header_value in layer: value = str(layer[header_value]) else: value = "-" self.model.setItem(row_index, header_index, QStandardItem(value)) add_enabled = layers is not None and len(layers) > 0 self.btnAdd.setEnabled(add_enabled) def _edit_connection(self): conn = self._get_current_connection() self._create_or_update_connection(name=conn[0], url=conn[1]) def _create_connection(self): self._create_or_update_connection("", "") def _create_or_update_connection(self, name=None, url=None): self.edit_connection_dialog.set_name_and_path(name, url) result = self.edit_connection_dialog.exec_() if result == QtGui.QDialog.Accepted: newname, newurl = self.edit_connection_dialog.get_connection() self._set_connection_url(newname, newurl) if newname != name: self.cbxConnections.addItem(newname) self.cbxConnections.setCurrentIndex(len(self.connections) - 1) self._save_connections() def _handle_connection_change(self, name): self.set_layers([]) enable_connect = False enable_edit = False if name in self.connections: enable_connect = True enable_edit = name not in self._predefined_connections self.btnConnect.setEnabled(enable_connect) self.btnEdit.setEnabled(enable_edit) self.btnDelete.setEnabled(enable_edit) self.on_connection_change.emit()
class OrderSelectorModel(QObject): """""" #---------------------------------------------------------------------- def __init__(self, full_string_list, init_selected_string_list=None, permanently_selected_string_list=None): """Constructor""" QObject.__init__(self) self.output = [] if not self.hasNoDuplicateStrings(full_string_list): raise ValueError('Duplicate strings detected in full string list.') else: self.full_string_list = full_string_list[:] if init_selected_string_list is not None: if not self.allStringsInList1FoundInList2( init_selected_string_list, self.full_string_list): raise ValueError('Some of the strings in initially selected string list are not in full string list.') else: init_selected_string_list = [] if permanently_selected_string_list is not None: if not self.allStringsInList1FoundInList2( permanently_selected_string_list, init_selected_string_list): raise ValueError('Some of the strings in permanently selected string list are not in initially selected string list.') else: permanently_selected_string_list = [] self.permanently_selected_string_list = permanently_selected_string_list[:] self.model_Selected = QStandardItemModel() self.model_NotSelected = QStandardItemModel() Selected_item_list = [None for s in init_selected_string_list] NotSelected_item_list = [] for s in self.full_string_list: item = QStandardItem(s) try: Selected_item_list[init_selected_string_list.index(s)] = item except: NotSelected_item_list.append(item) for item in NotSelected_item_list: self.model_NotSelected.appendRow(item) for item in Selected_item_list: self.model_Selected.appendRow(item) #---------------------------------------------------------------------- def getSelectedList(self): """""" selectedList = [] for i in range(self.model_Selected.rowCount()): selectedList.append(self.model_Selected.item(i,0).text()) return selectedList #---------------------------------------------------------------------- def hasNoDuplicateStrings(self, full_string_list): """""" str_list = full_string_list str_set = set(full_string_list) if len(str_list) == len(str_set): return True else: return False #---------------------------------------------------------------------- def allStringsInList1FoundInList2(self, str_list_1, str_list_2): """""" stringsNotFound = [ s for s in str_list_1 if s not in str_list_2 ] if stringsNotFound != []: return False else: return True
class GroupPhotoWindow(QMainWindow, Ui_main_win): def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self.image_model = QStandardItemModel() self.image_list.setModel(self.image_model) QObject.connect(self.add_btn, QtCore.SIGNAL('clicked()'), self.on_add_image) QObject.connect(self.delete_btn, QtCore.SIGNAL('clicked()'), self.on_remove_image) QObject.connect( self.image_list.selectionModel(), QtCore.SIGNAL( 'currentChanged (const QModelIndex &, const QModelIndex &)'), self.on_row_changed) QObject.connect(self.harris_btn, QtCore.SIGNAL('clicked()'), self.on_harris_detect) QObject.connect(self.stitch_btn, QtCore.SIGNAL('clicked()'), self.on_stitch) def on_add_image(self): image_path = QFileDialog.getOpenFileName( self, 'Select image', filter='Images (*.png *.jpg *.bmp)') ignored, name = os.path.split(unicode(image_path)) self.image_model.appendRow( [QStandardItem(name), QStandardItem(image_path)]) def on_remove_image(self): row = self.image_list.selectionModel().currentIndex().row() if row == -1: return self.image_model.removeRows(row, 1) def on_row_changed(self, current, previous): row = current.row() if row == -1: file_path = PLACE_HOLDER else: file_path = self.image_model.item(row, 1).text() self.set_pixmap(QPixmap(file_path)) def on_harris_detect(self): row = self.image_list.selectionModel().currentIndex().row() if row == -1: return file_path = self.image_model.item(row, 1).text() image_pfm = convert_to_pfm(imread(unicode(file_path))) image = image_to_gray(image_pfm) kernel = self.ksize_slider.value() cornerness = harris_corner(image, ksize=kernel) is_corner = cornerness > 0.000001 suppress = non_max_suppression(cornerness, ksize=kernel) result = np.array(is_corner * suppress) zero = np.zeros_like(result) gray_img = np.dstack((zero, zero, draw_cross(result))) self.set_pixmap( QPixmap.fromImage( image_from_ndarray(np.array(gray_img + image_pfm)))) def on_stitch(self): i = 0 images = [] while self.image_model.item(i): file_path = self.image_model.item(i, 1).text() image = image_to_gray(convert_to_pfm(imread(unicode(file_path)))) images.append(image) i += 1 stitch(self.ksize_slider.value(), images) def set_pixmap(self, pixmap): self.image_label.setPixmap( pixmap.scaled(self.image_label.size(), QtCore.Qt.KeepAspectRatio))
class InputDialog(GenericDialog): TBL_HEADER_LABEL=["Input Mesh", "Output group name"] def __init__(self, parent=None, name="InputDialog", modal=0): """ This initializes a dialog windows to define the input data of the plugin function. The input data consist in a list of meshes characterizes each by a name, a pointer to the smesh servant object, a type and a group name (see data model in the inputdata.py). """ GenericDialog.__init__(self, parent, name, modal) # Set up the user interface from Designer. self.__ui = Ui_InputFrame() # BE CAREFULL HERE, the ui form is NOT drawn in the global # dialog (already containing some generic widgets) but in the # center panel created in the GenericDialog as a void # container for the form. The InputFrame form is supposed # here to create only the widgets to be placed in the center # panel. Then, the setupUi function of this form draws itself # in the specified panel, i.e. the panel returned by # self.getPanel(). self.__ui.setupUi(self.getPanel()) self.setWindowTitle("Specification of input files") # The icon are supposed to be located in the plugin folder, # i.e. in the same folder than this python module file iconfolder=os.path.dirname(os.path.abspath(__file__)) icon = QIcon() icon.addFile(os.path.join(iconfolder,"select.png")) self.__ui.btnSmeshObject.setIcon(icon) icon = QIcon() icon.addFile(os.path.join(iconfolder,"addinput.png")) self.__ui.btnAddInput.setIcon(icon) icon = QIcon() icon.addFile(os.path.join(iconfolder,"deleteinput.png")) self.__ui.btnDeleteInput.setIcon(icon) # We specify here the items in the combo box (even if already # defined in the designer) so that we can be sure of the item # indexation. self.MESHTYPE_ICONS = {} meshTypeIndex = InputData.MESHTYPES.CONCRETE self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Béton") icon = QIcon() icon.addFile(os.path.join(iconfolder,"concrete.png")) self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon) self.MESHTYPE_ICONS[meshTypeIndex] = icon meshTypeIndex = InputData.MESHTYPES.STEELBAR self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Acier") icon = QIcon() icon.addFile(os.path.join(iconfolder,"steelbar.png")) self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon) self.MESHTYPE_ICONS[meshTypeIndex] = icon # The click on btnSmeshObject (signal clicked() emitted by the # button btnSmeshObject) is connected to the slot # onSelectSmeshObject, etc ... self.connect(self.__ui.btnSmeshObject, SIGNAL('clicked()'), self.onSelectSmeshObject ) self.connect(self.__ui.btnAddInput, SIGNAL('clicked()'), self.onAddInput ) self.connect(self.__ui.btnDeleteInput, SIGNAL('clicked()'), self.onDeleteInput ) # Set up the model of the Qt table list self.__inputModel = QStandardItemModel(0,2) self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL) self.__ui.tblListInput.setModel(self.__inputModel) self.__ui.tblListInput.verticalHeader().hide() self.__ui.tblListInput.horizontalHeader().setStretchLastSection(True) # Note that the type is not display explicitly in the Qt table # because it is specified using an icon on the text of the # name item. # Note that PADDER does not support group name longer than 8 # characters. We apply then this limit in the gui field. self.__ui.txtGroupName.setMaxLength(GROUPNAME_MAXLENGTH) self.clear() self.smeshStudyTool = SMeshStudyTools() def clear(self): """ This function clears the data gui area and associated values. """ self.__ui.txtSmeshObject.setText("") self.__ui.txtGroupName.setText("") self.__inputModel.clear() self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL) if not DEBUG_MODE: self.__ui.txtSmeshObject.setEnabled(False) self.__ui.btnAddInput.setEnabled(False) self.__selectedMesh = None self.__dictInputData = {} self.__nbConcreteMesh = 0 self.__nbSteelbarMesh = 0 def accept(self): """ This function is the slot connected to the button OK """ # The dialog is raised in a non modal mode to get # interactivity with the parents windows. Then we have to emit # a signal to warn the parent observer that the dialog has # been validated so that it can process the event GenericDialog.accept(self) if self.wasOk(): self.emit(SIGNAL('inputValidated()')) def onSelectSmeshObject(self): ''' This function is the slot connected on the mesh selection button. It memorizes the selected mesh and put its name in the text field of the dialog box. ''' mySObject, myEntry = guihelper.getSObjectSelected() if CORBA.is_nil(mySObject): self.__ui.txtSmeshObject.setText("You must choose a mesh") self.__ui.txtGroupName.setText("") self.__ui.txtSmeshObject.setEnabled(False) self.__ui.btnAddInput.setEnabled(False) self.__selectedMesh = None return self.smeshStudyTool.updateStudy(studyedit.getActiveStudyId()) self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject) if CORBA.is_nil(self.__selectedMesh): self.__ui.txtSmeshObject.setText("The selected object is not a mesh") self.__ui.txtGroupName.setText("") self.__ui.txtSmeshObject.setEnabled(False) self.__ui.btnAddInput.setEnabled(False) self.__selectedMesh = None return myName = mySObject.GetName() self.__ui.txtSmeshObject.setText(myName) self.__ui.txtSmeshObject.setEnabled(True) self.__ui.btnAddInput.setEnabled(True) # We can suggest a default group name from the mesh name self.__ui.txtGroupName.setText(myName) def onAddInput(self): """ This function is the slot connected to the Add button. It creates a new entry in the list of input data, or updates this entry if it already exists. """ meshName = str(self.__ui.txtSmeshObject.text().trimmed()) meshObject = self.__selectedMesh meshType = self.__ui.cmbMeshType.currentIndex() groupName = str(self.__ui.txtGroupName.text().trimmed()) self.__addInputInGui(meshName, meshObject, meshType, groupName) self.__addInputInMap(meshName, meshObject, meshType, groupName) def __addInputInGui(self, meshName, meshObject, meshType, groupName): """ This function adds an entry with the specified data int the GUI table (for data visualization purpose). """ # The mesh name is used as the key index in the model. We have # to check first if this item already exists in the list. tblItems = self.__inputModel.findItems(meshName) row = self.__inputModel.rowCount() if not tblItems: tblItems = [] tblItems.append(QStandardItem()) # input mesh name tblItems.append(QStandardItem()) # output group name else: row = tblItems[0].index().row() tblItems.append(self.__inputModel.item(row,1)) tblItems[0].setText(meshName) tblItems[0].setIcon(self.MESHTYPE_ICONS[meshType]) tblItems[1].setText(groupName) self.__inputModel.setItem(row,0,tblItems[0]) self.__inputModel.setItem(row,1,tblItems[1]) self.__ui.tblListInput.setCurrentIndex(tblItems[0].index()) def __addInputInMap(self, meshName, meshObject, meshType, groupName): """ This function adds an entry with the specified data in the internal map (for data management purpose). """ # if the entry already exists, we remove it to replace by a # new one if self.__dictInputData.has_key(meshName): self.__delInputFromMap(meshName) inputData = InputData() inputData.meshName = meshName inputData.meshObject = meshObject inputData.meshType = meshType inputData.groupName = groupName # The key of the map is the mesh name self.__dictInputData[meshName] = inputData if inputData.meshType == InputData.MESHTYPES.CONCRETE: self.__nbConcreteMesh += 1 else: self.__nbSteelbarMesh += 1 print inputData print "meshType = ",inputData.meshType print "nb concrete mesh ",self.__nbConcreteMesh print "nb steelbar mesh ",self.__nbSteelbarMesh def onDeleteInput(self): """ This function is the slot connected to the Delete button. It remove from the data list the entry selected in the Qt table. """ selectedIdx = self.__ui.tblListInput.selectedIndexes() if selectedIdx: row = selectedIdx[0].row() tblItem = self.__inputModel.item(row,0) meshName = str(tblItem.text()) self.__inputModel.takeRow(row) # Don't forget to remove this entry from the mesh object # internal dictionnary self.__delInputFromMap(meshName) def __delInputFromMap(self, meshName): """ This function removes the specified entry from the internal map (for data management purpose) """ inputData = self.__dictInputData.pop(meshName) if inputData.meshType == InputData.MESHTYPES.CONCRETE: self.__nbConcreteMesh -= 1 else: self.__nbSteelbarMesh -= 1 print inputData print "nb concrete mesh ",self.__nbConcreteMesh print "nb steelbar mesh ",self.__nbSteelbarMesh def setData(self, listInputData=[]): """ This function fills the dialog widgets with values provided by the specified data list. """ self.clear() for inputData in listInputData: meshName = inputData.meshName meshObject = inputData.meshObject meshType = inputData.meshType groupName = inputData.groupName self.__addInputInGui(meshName, meshObject, meshType, groupName) self.__addInputInMap(meshName, meshObject, meshType, groupName) if not DEBUG_MODE: self.onSelectSmeshObject() def getData(self): """ This function returns a list of InputData that corresponds to the data in the dialog widgets of the current dialog. """ # Note that the values() function returns a copy of the list # of values. return self.__dictInputData.values() def checkData(self): """ This function checks if the data are valid, from the dialog window point of view. """ if self.__nbConcreteMesh == 0 and self.__nbSteelbarMesh == 0: self.checkDataMessage = "You must define at least one mesh (CONCRETE or STEELBAR)" return False if self.__nbConcreteMesh > 1: self.checkDataMessage = "You define multiple CONCRETE meshes." self.checkDataMessage += "You should verify first that your version of PADDER support this configuration." # just warn the user, but don't block QMessageBox.information(self, "Info", self.checkDataMessage) return True return True
class AbstractSTREnityListView(QListView): """ A widget for listing and selecting one or more STR entities. .. versionadded:: 1.7 """ def __init__(self, parent=None, **kwargs): super(AbstractSTREnityListView, self).__init__(parent) self._model = QStandardItemModel(self) self._model.setColumnCount(1) self.setModel(self._model) self.setEditTriggers(QAbstractItemView.NoEditTriggers) self._model.itemChanged.connect(self._on_item_changed) self._profile = kwargs.get('profile', None) self._social_tenure = kwargs.get('social_tenure', None) # Load appropriate entities to the view if not self._profile is None: self._load_profile_entities() # Load entities in the STR definition if not self._social_tenure is None: self._select_str_entities() def _on_item_changed(self, item): # Emit signals when an item has been (de)selected. To be # implemented by subclasses. pass @property def profile(self): """ :return: Returns the current profile object in the configuration. :rtype: Profile """ return self._profile @profile.setter def profile(self, profile): """ Sets the current profile object in the configuration. :param profile: Profile object. :type profile: Profile """ self._profile = profile self._load_profile_entities() @property def social_tenure(self): """ :return: Returns the profile's social tenure entity. :rtype: SocialTenure """ return self._social_tenure @social_tenure.setter def social_tenure(self, social_tenure): """ Set the social_tenure entity. :param social_tenure: A profile's social tenure entity. :type social_tenure: SocialTenure """ self._social_tenure = social_tenure self._select_str_entities() def _select_str_entities(self): """ Select the entities defined in the STR. E.g. parties for party entity and spatial units for spatial unit entity. Default implementation does nothing, to be implemented by subclasses. """ pass def _load_profile_entities(self): # Reset view self.clear() # Populate entity items in the view for e in self._profile.user_entities(): self._add_entity(e) def _add_entity(self, entity): # Add entity item to view item = QStandardItem( QIcon(':/plugins/stdm/images/icons/table.png'), entity.short_name ) item.setCheckable(True) item.setCheckState(Qt.Unchecked) self._model.appendRow(item) def select_entities(self, entities): """ Checks STR entities in the view and emit the entity_selected signal for each item selected. :param entities: Collection of STR entities. :type entities: list """ # Clear selection self.clear_selection() for e in entities: name = e.short_name self.select_entity(name) def selected_entities(self): """ :return: Returns a list of selected entity short names. :rtype: list """ selected_items = [] for i in range(self._model.rowCount()): item = self._model.item(i) if item.checkState() == Qt.Checked: selected_items.append(item.text()) return selected_items def clear(self): """ Remove all party items in the view. """ self._model.clear() self._model.setColumnCount(1) def clear_selection(self): """ Uncheck all items in the view. """ for i in range(self._model.rowCount()): item = self._model.item(i) if item.checkState() == Qt.Checked: item.setCheckState(Qt.Unchecked) def select_entity(self, name): """ Selects a party entity with the given short name. :param name: Entity short name :type name: str """ items = self._model.findItems(name) if len(items) > 0: item = items[0] if item.checkState() == Qt.Unchecked: item.setCheckState(Qt.Checked) def deselect_entity(self, name): """ Deselects an entity with the given short name. :param name: Entity short name :type name: str """ items = self._model.findItems(name) if len(items) > 0: item = items[0] if item.checkState() == Qt.Checked: item.setCheckState(Qt.Unchecked)
class Formation(QMainWindow, Ui_Formation): """ Class documentation goes here. """ #signal fermeture_reouverture = pyqtSignal() maj = pyqtSignal() def __init__(self, engine, gui_parent, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super().__init__(parent) self.setupUi(self) self.setWindowTitle("Enregistrement d'une formation") self.engine = engine self.dateEdit.setDate(pendulum.now('Europe/Paris')) self.cmr_bdd = Bdd_Cmr(self.engine) gen_cmr = self.cmr_bdd.recup_cmr_en_activite() self.remplir_tableau_cmr(next(gen_cmr)) # self.threadpool = QThreadPool() self.gui_parent = gui_parent ####Threads self.thread_finish = False # self.affectation_lancement_threads() init_domaine = Insertion_Domaine(self.engine) areas = init_domaine.recuperation_domaine() # print(areas) self.model = QStandardItemModel((len(areas) + 1), 1) # 5 rows, 1 col firstItem = QStandardItem("---- Select domaine(s) ----") firstItem.setBackground(QBrush(QColor(200, 200, 200))) firstItem.setSelectable(False) self.model.setItem(0, 0, firstItem) for i, area in enumerate(areas): item = QStandardItem(area) item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setData(Qt.Unchecked, Qt.CheckStateRole) self.model.setItem(i + 1, 0, item) self.comboBox_domaine.setModel(self.model) self.gui_parent.formation_a_modifier.connect( self.reaffectation_formation) # # def affectation_lancement_threads(self): # """"met en place les threads et les lance""" # bdd_thread = Gestion_BDD_Thread(self.cmr_bdd ) # bdd_thread.signals.signalData_dispo.connect(self.remplir_tableau_cmr) # self.threadpool.start(bdd_thread) ### bdd_thread.run() # # self.thread_combobox = Gestion_Combobox_domaine_Thread(self.engine) # self.thread_combobox.signals.signalmodel_dispo.connect(self.affectation_model_combobox_domaine) ## self.thread_combobox.finished.connect(self.danslemille) # self.threadpool.start(self.thread_combobox) # # print(self.thread_combobox) ## self.thread_combobox.run() # # @pyqtSlot(QStandardItemModel) # def affectation_model_combobox_domaine(self, model): # """permet de recevoir le model créé et affecte au combobox dans le thread specifique""" # print("jy suis") # mutex = QMutex() # mutex.lock() # self.model = model # self.comboBox_domaine.setModel(self.model) # # self.thread_finish = True # mutex.unlock() # print(self.thread_finish) @pyqtSlot(list) def remplir_tableau_cmr(self, gen_list_cmr): self.tableWidget.setRowCount(0) for cmr in reversed(gen_list_cmr): # print(cmr) self.tableWidget.insertRow(0) item_nom = QTableWidgetItem(cmr.NOM) item_prenom = QTableWidgetItem(cmr.PRENOM) self.tableWidget.setItem(0, 0, item_nom) self.tableWidget.setItem(0, 1, item_prenom) self.tableWidget.setCellWidget(0, 2, QComboBox()) self.tableWidget.cellWidget(0, 2).addItems( ["*", "Acquise", "À améliorer", "Non acquise"]) self.tableWidget.setCellWidget(0, 3, QComboBox()) self.tableWidget.cellWidget(0, 3).addItems( [str(x) for x in range(21)]) self.tableWidget.setCellWidget(0, 4, QTextEdit()) self.tableWidget.setCellWidget(0, 5, QCheckBox()) @pyqtSlot() def on_pushButton_enregistrer_clicked(self): """ Slot documentation goes here. """ nom_formation = self.lineEdit_nom_formation.text() if nom_formation: date = self.dateEdit.date().toString("dd-MM-yyyy") type_formation = self.comboBox_type_formation.currentText() # domaine = self.comboBox_domaine.currentText() domaine = [] for ligne in range(self.model.rowCount()): if self.model.item(ligne, 0).checkState() == Qt.Checked: domaine.append(self.model.item(ligne, 0).text()) plan = self.textEdit_plan_formation.toPlainText() nbr_ligne = self.tableWidget.rowCount() sauvegarde_dico = [] for ligne in range(nbr_ligne): if self.tableWidget.cellWidget(ligne, 5).isChecked(): nom = self.tableWidget.item(ligne, 0).text() prenom = self.tableWidget.item(ligne, 1).text() gen_id = self.cmr_bdd.recup_id_cmr(nom, prenom) try: resultat = self.tableWidget.cellWidget( ligne, 2).currentText() except: resultat = None try: note = self.tableWidget.cellWidget(ligne, 3).currentText() except: note = None try: remarque = self.tableWidget.item(ligne, 4).text() except: remarque = None dico = { "nom": nom, "prenom": prenom, "id": gen_id, "resultat": resultat, "note": note, "remarque": remarque } # print(dico) sauvegarde_dico.append(json.dumps(dico)) sauvegarde = { "nom_formation": nom_formation, "date": date, "type_formation": type_formation, "domaine": domaine, "plan": plan, "participants": sauvegarde_dico } # print(sauvegarde) if self.windowTitle() == "Enregistrement d'une formation": self.cmr_bdd.insertion_formation(sauvegarde) self.close() self.fermeture_reouverture.emit() else: #on est dans une modification self.cmr_bdd.modif_formation(self.id_formation_a_modif, sauvegarde) self.close() self.maj.emit() @pyqtSlot(object) def reaffectation_formation(self, formation): """fct qui reaffecte les donnees recues par le signal""" self.setWindowTitle("Modification d'une formation") # print(formation) self.id_formation_a_modif = formation.ID # print(formation.ID) self.lineEdit_nom_formation.setText(formation.NOM_FORMATION) self.dateEdit.setDate(formation.DATE_FORMATION) index = self.comboBox_type_formation.findText(formation.TYPE_FORMATION, Qt.MatchExactly) if index: self.comboBox_type_formation.setCurrentIndex(index) #gestion des domaines : for domaine in formation.DOMAINE: for ligne in range(self.model.rowCount()): # print(f"ligne {ligne}") if self.model.item(ligne, 0).text() == domaine: self.model.item(ligne, 0).setData(Qt.Checked, Qt.CheckStateRole) self.textEdit_plan_formation.setText(formation.PLAN) for participant in formation.LIST_PARTICIPANTS: nom = json.loads(participant)["nom"] prenom = json.loads(participant)["prenom"] # id = json.loads(participant)["id"] resultat = json.loads(participant)["resultat"] note = json.loads(participant)["note"] remarque = json.loads(participant)["remarque"] for ligne in range(self.tableWidget.rowCount()): if self.tableWidget.item( ligne, 0).text() == nom and self.tableWidget.item( ligne, 1).text() == prenom: index = self.tableWidget.cellWidget(ligne, 2).findText( resultat, Qt.MatchExactly) if index != -1: self.tableWidget.cellWidget(ligne, 2).setCurrentIndex(index) index = self.tableWidget.cellWidget(ligne, 3).findText( note, Qt.MatchExactly) if index != -1: self.tableWidget.cellWidget(ligne, 3).setCurrentIndex(index) self.tableWidget.cellWidget(ligne, 4).setText(remarque) self.tableWidget.cellWidget(ligne, 5).setChecked(True)
class QtWidgetRegistry(QObject, WidgetRegistry): """ A QObject wrapper for `WidgetRegistry` A QStandardItemModel instance containing the widgets in a tree (of depth 2). The items in a model can be quaries using standard roles (DisplayRole, BackgroundRole, DecorationRole ToolTipRole). They also have QtWidgetRegistry.CATEGORY_DESC_ROLE, QtWidgetRegistry.WIDGET_DESC_ROLE, which store Category/WidgetDescription respectfully. Furthermore QtWidgetRegistry.WIDGET_ACTION_ROLE stores an default QAction which can be used for widget creation action. """ CATEGORY_DESC_ROLE = Qt.UserRole + 1 """Category Description Role""" WIDGET_DESC_ROLE = Qt.UserRole + 2 """Widget Description Role""" WIDGET_ACTION_ROLE = Qt.UserRole + 3 """Widget Action Role""" BACKGROUND_ROLE = Qt.UserRole + 4 """Background color for widget/category in the canvas (different from Qt.BackgroundRole) """ category_added = Signal(str, CategoryDescription) """signal: category_added(name: str, desc: CategoryDescription) """ widget_added = Signal(str, str, WidgetDescription) """signal widget_added(category_name: str, widget_name: str, desc: WidgetDescription) """ reset = Signal() """signal: reset() """ def __init__(self, other_or_parent=None, parent=None): if isinstance(other_or_parent, QObject) and parent is None: parent, other_or_parent = other_or_parent, None QObject.__init__(self, parent) WidgetRegistry.__init__(self, other_or_parent) # Should the QStandardItemModel be subclassed? self.__item_model = QStandardItemModel(self) for i, desc in enumerate(self.categories()): cat_item = self._cat_desc_to_std_item(desc) self.__item_model.insertRow(i, cat_item) for j, wdesc in enumerate(self.widgets(desc.name)): widget_item = self._widget_desc_to_std_item(wdesc, desc) cat_item.insertRow(j, widget_item) def model(self): """ Return the widget descriptions in a Qt Item Model instance (QStandardItemModel). .. note:: The model should not be modified outside of the registry. """ return self.__item_model def item_for_widget(self, widget): """Return the QStandardItem for the widget. """ if isinstance(widget, basestring): widget = self.widget(widget) cat = self.category(widget.category) cat_ind = self.categories().index(cat) cat_item = self.model().item(cat_ind) widget_ind = self.widgets(cat).index(widget) return cat_item.child(widget_ind) def action_for_widget(self, widget): """ Return the QAction instance for the widget (can be a string or a WidgetDescription instance). """ item = self.item_for_widget(widget) return item.data(self.WIDGET_ACTION_ROLE).toPyObject() def create_action_for_item(self, item): """ Create a QAction instance for the widget description item. """ name = item.text() tooltip = item.toolTip() whatsThis = item.whatsThis() icon = item.icon() if icon: action = QAction(icon, name, self, toolTip=tooltip, whatsThis=whatsThis, statusTip=name) else: action = QAction(name, self, toolTip=tooltip, whatsThis=whatsThis, statusTip=name) widget_desc = item.data(self.WIDGET_DESC_ROLE) action.setData(widget_desc) action.setProperty("item", QVariant(item)) return action def _insert_category(self, desc): """ Override to update the item model and emit the signals. """ priority = desc.priority priorities = [c.priority for c, _ in self.registry] insertion_i = bisect.bisect_right(priorities, priority) WidgetRegistry._insert_category(self, desc) cat_item = self._cat_desc_to_std_item(desc) self.__item_model.insertRow(insertion_i, cat_item) self.category_added.emit(desc.name, desc) def _insert_widget(self, category, desc): """ Override to update the item model and emit the signals. """ assert(isinstance(category, CategoryDescription)) categories = self.categories() cat_i = categories.index(category) _, widgets = self._categories_dict[category.name] priorities = [w.priority for w in widgets] insertion_i = bisect.bisect_right(priorities, desc.priority) WidgetRegistry._insert_widget(self, category, desc) cat_item = self.__item_model.item(cat_i) widget_item = self._widget_desc_to_std_item(desc, category) cat_item.insertRow(insertion_i, widget_item) self.widget_added.emit(category.name, desc.name, desc) def _cat_desc_to_std_item(self, desc): """ Create a QStandardItem for the category description. """ item = QStandardItem() item.setText(desc.name) if desc.icon: icon = desc.icon else: icon = "icons/default-category.svg" icon = icon_loader.from_description(desc).get(icon) item.setIcon(icon) if desc.background: background = desc.background else: background = DEFAULT_COLOR background = NAMED_COLORS.get(background, background) brush = QBrush(QColor(background)) item.setData(brush, self.BACKGROUND_ROLE) tooltip = desc.description if desc.description else desc.name item.setToolTip(tooltip) item.setFlags(Qt.ItemIsEnabled) item.setData(QVariant(desc), self.CATEGORY_DESC_ROLE) return item def _widget_desc_to_std_item(self, desc, category): """ Create a QStandardItem for the widget description. """ item = QStandardItem(desc.name) item.setText(desc.name) if desc.icon: icon = desc.icon else: icon = "icons/default-widget.svg" icon = icon_loader.from_description(desc).get(icon) item.setIcon(icon) # This should be inherited from the category. background = None if desc.background: background = desc.background elif category.background: background = category.background else: background = DEFAULT_COLOR if background is not None: background = NAMED_COLORS.get(background, background) brush = QBrush(QColor(background)) item.setData(brush, self.BACKGROUND_ROLE) tooltip = tooltip_helper(desc) style = "ul { margin-top: 1px; margin-bottom: 1px; }" tooltip = TOOLTIP_TEMPLATE.format(style=style, tooltip=tooltip) item.setToolTip(tooltip) item.setWhatsThis(whats_this_helper(desc)) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) item.setData(QVariant(desc), self.WIDGET_DESC_ROLE) # Create the action for the widget_item action = self.create_action_for_item(item) item.setData(QVariant(action), self.WIDGET_ACTION_ROLE) return item
class DlgSqlWindow(QWidget, Ui_Dialog): nameChanged = pyqtSignal(str) def __init__(self, iface, db, parent=None): QWidget.__init__(self, parent) self.iface = iface self.db = db self.allowMultiColumnPk = isinstance( db, PGDatabase ) # at the moment only PostGIS allows a primary key to span multiple columns, spatialite doesn't self.setupUi(self) self.setWindowTitle( u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString())) self.defaultLayerName = 'QueryLayer' if self.allowMultiColumnPk: self.uniqueColumnCheck.setText( self.trUtf8("Column(s) with unique values")) else: self.uniqueColumnCheck.setText( self.trUtf8("Column with unique values")) self.editSql.setFocus() self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.initCompleter() # allow to copy results copyAction = QAction("copy", self) self.viewResult.addAction(copyAction) copyAction.setShortcuts(QKeySequence.Copy) copyAction.triggered.connect(self.copySelectedResults) self.btnExecute.clicked.connect(self.executeSql) self.btnClear.clicked.connect(self.clearSql) self.presetStore.clicked.connect(self.storePreset) self.presetDelete.clicked.connect(self.deletePreset) self.presetCombo.activated[str].connect(self.loadPreset) self.presetCombo.activated[str].connect(self.presetName.setText) self.updatePresetsCombobox() self.geomCombo.setEditable(True) self.geomCombo.lineEdit().setReadOnly(True) self.uniqueCombo.setEditable(True) self.uniqueCombo.lineEdit().setReadOnly(True) self.uniqueModel = QStandardItemModel(self.uniqueCombo) self.uniqueCombo.setModel(self.uniqueModel) if self.allowMultiColumnPk: self.uniqueCombo.setItemDelegate(QStyledItemDelegate()) self.uniqueModel.itemChanged.connect( self.uniqueChanged) # react to the (un)checking of an item self.uniqueCombo.lineEdit().textChanged.connect( self.uniqueTextChanged ) # there are other events that change the displayed text and some of them can not be caught directly # hide the load query as layer if feature is not supported self._loadAsLayerAvailable = self.db.connector.hasCustomQuerySupport() self.loadAsLayerGroup.setVisible(self._loadAsLayerAvailable) if self._loadAsLayerAvailable: self.layerTypeWidget.hide() # show if load as raster is supported self.loadLayerBtn.clicked.connect(self.loadSqlLayer) self.getColumnsBtn.clicked.connect(self.fillColumnCombos) self.loadAsLayerGroup.toggled.connect(self.loadAsLayerToggled) self.loadAsLayerToggled(False) self._createViewAvailable = self.db.connector.hasCreateSpatialViewSupport( ) self.btnCreateView.setVisible(self._createViewAvailable) if self._createViewAvailable: self.btnCreateView.clicked.connect(self.createView) self.queryBuilderFirst = True self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif")) self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder) self.presetName.textChanged.connect(self.nameChanged) def updatePresetsCombobox(self): self.presetCombo.clear() names = [] entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries') for entry in entries: name = QgsProject.instance().readEntry( 'DBManager', 'savedQueries/' + entry + '/name')[0] names.append(name) for name in sorted(names): self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(-1) def storePreset(self): query = self._getSqlQuery() if query == "": return name = self.presetName.text() QgsProject.instance().writeEntry( 'DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name', name) QgsProject.instance().writeEntry( 'DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query', query) index = self.presetCombo.findText(name) if index == -1: self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1) else: self.presetCombo.setCurrentIndex(index) def deletePreset(self): name = self.presetCombo.currentText() QgsProject.instance().removeEntry( 'DBManager', 'savedQueries/q' + unicode(name.__hash__())) self.presetCombo.removeItem(self.presetCombo.findText(name)) self.presetCombo.setCurrentIndex(-1) def loadPreset(self, name): query = QgsProject.instance().readEntry( 'DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query')[0] name = QgsProject.instance().readEntry( 'DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name')[0] self.editSql.setText(query) def loadAsLayerToggled(self, checked): self.loadAsLayerGroup.setChecked(checked) self.loadAsLayerWidget.setVisible(checked) if checked: self.fillColumnCombos() def clearSql(self): self.editSql.clear() self.editSql.setFocus() def executeSql(self): sql = self._getSqlQuery() if sql == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # delete the old model old_model = self.viewResult.model() self.viewResult.setModel(None) if old_model: old_model.deleteLater() cols = [] quotedCols = [] try: # set the new model model = self.db.sqlResultModel(sql, self) self.viewResult.setModel(model) self.lblResult.setText( self.tr("%d rows, %.1f seconds") % (model.affectedRows(), model.secs())) cols = self.viewResult.model().columnNames() for col in cols: quotedCols.append(self.db.connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return self.setColumnCombos(cols, quotedCols) self.update() QApplication.restoreOverrideCursor() def loadSqlLayer(self): hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked if hasUniqueField: if self.allowMultiColumnPk: checkedCols = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedCols.append(item.data()) uniqueFieldName = ",".join(checkedCols) elif self.uniqueCombo.currentIndex() >= 0: uniqueFieldName = self.uniqueModel.item( self.uniqueCombo.currentIndex()).data() else: uniqueFieldName = None else: uniqueFieldName = None hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked if hasGeomCol: geomFieldName = self.geomCombo.currentText() else: geomFieldName = None query = self._getSqlQuery() if query == "": return # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) from qgis.core import QgsMapLayer, QgsMapLayerRegistry layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked( ) else QgsMapLayer.RasterLayer # get a new layer name names = [] for layer in QgsMapLayerRegistry.instance().mapLayers().values(): names.append(layer.name()) layerName = self.layerNameEdit.text() if layerName == "": layerName = self.defaultLayerName newLayerName = layerName index = 1 while newLayerName in names: index += 1 newLayerName = u"%s_%d" % (layerName, index) # create the layer layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType, self.avoidSelectById.isChecked()) if layer.isValid(): QgsMapLayerRegistry.instance().addMapLayers([layer], True) QApplication.restoreOverrideCursor() def fillColumnCombos(self): query = self._getSqlQuery() if query == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # get a new alias aliasIndex = 0 while True: alias = "_%s__%d" % ("subQuery", aliasIndex) escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b') if not escaped.search(query): break aliasIndex += 1 # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] # get all the columns cols = [] quotedCols = [] connector = self.db.connector sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % ( unicode(query), connector.quoteId(alias)) c = None try: c = connector._execute(None, sql) cols = connector._get_cursor_columns(c) for col in cols: quotedCols.append(connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return finally: if c: c.close() del c self.setColumnCombos(cols, quotedCols) QApplication.restoreOverrideCursor() def setColumnCombos(self, cols, quotedCols): # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first) try: defaultGeomCol = next( col for col in cols if col in ['geom', 'geometry', 'the_geom', 'way']) except: defaultGeomCol = None try: defaultUniqueCol = [col for col in cols if 'id' in col][0] except: defaultUniqueCol = None colNames = sorted(zip(cols, quotedCols)) newItems = [] uniqueIsFilled = False for (col, quotedCol) in colNames: item = QStandardItem(col) item.setData(quotedCol) item.setEnabled(True) item.setCheckable(self.allowMultiColumnPk) item.setSelectable(not self.allowMultiColumnPk) if self.allowMultiColumnPk: matchingItems = self.uniqueModel.findItems(col) if matchingItems: item.setCheckState(matchingItems[0].checkState()) uniqueIsFilled = uniqueIsFilled or matchingItems[ 0].checkState() == Qt.Checked else: item.setCheckState(Qt.Unchecked) newItems.append(item) if self.allowMultiColumnPk: self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) self.uniqueChanged() else: previousUniqueColumn = self.uniqueCombo.currentText() self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) if self.uniqueModel.findItems(previousUniqueColumn): self.uniqueCombo.setEditText(previousUniqueColumn) uniqueIsFilled = True oldGeometryColumn = self.geomCombo.currentText() self.geomCombo.clear() self.geomCombo.addItems(cols) self.geomCombo.setCurrentIndex( self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly)) # set sensible default columns if the columns are not already set try: if self.geomCombo.currentIndex() == -1: self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol)) except: pass items = self.uniqueModel.findItems(defaultUniqueCol) if items and not uniqueIsFilled: if self.allowMultiColumnPk: items[0].setCheckState(Qt.Checked) else: self.uniqueCombo.setEditText(defaultUniqueCol) try: pass except: pass def copySelectedResults(self): if len(self.viewResult.selectedIndexes()) <= 0: return model = self.viewResult.model() # convert to string using tab as separator text = model.headerToString("\t") for idx in self.viewResult.selectionModel().selectedRows(): text += "\n" + model.rowToString(idx.row(), "\t") QApplication.clipboard().setText(text, QClipboard.Selection) QApplication.clipboard().setText(text, QClipboard.Clipboard) def initCompleter(self): dictionary = None if self.db: dictionary = self.db.connector.getSqlDictionary() if not dictionary: # use the generic sql dictionary from .sql_dictionary import getSqlDictionary dictionary = getSqlDictionary() wordlist = [] for name, value in dictionary.iteritems(): wordlist += value # concat lists wordlist = list(set(wordlist)) # remove duplicates api = QsciAPIs(self.editSql.lexer()) for word in wordlist: api.add(word) api.prepare() self.editSql.lexer().setAPIs(api) def displayQueryBuilder(self): dlg = QueryBuilderDlg(self.iface, self.db, self, reset=self.queryBuilderFirst) self.queryBuilderFirst = False r = dlg.exec_() if r == QDialog.Accepted: self.editSql.setText(dlg.query) def createView(self): name, ok = QInputDialog.getText(None, "View name", "View name") if ok: try: self.db.connector.createSpatialView(name, self._getSqlQuery()) except BaseError as e: DlgDbError.showError(e, self) def _getSqlQuery(self): sql = self.editSql.selectedText() if len(sql) == 0: sql = self.editSql.text() return sql def uniqueChanged(self): # when an item is (un)checked, simply trigger an update of the combobox text self.uniqueTextChanged(None) def uniqueTextChanged(self, text): # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one. checkedItems = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedItems.append(item.text()) label = ", ".join(checkedItems) if text != label: self.uniqueCombo.setEditText(label)
class GroupPhotoWindow(QMainWindow, Ui_main_win): def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self.image_model = QStandardItemModel() self.image_list.setModel(self.image_model) QObject.connect(self.add_btn, QtCore.SIGNAL('clicked()'), self.on_add_image) QObject.connect(self.delete_btn, QtCore.SIGNAL('clicked()'), self.on_remove_image) QObject.connect(self.image_list.selectionModel(), QtCore.SIGNAL( 'currentChanged (const QModelIndex &, const QModelIndex &)'), self.on_row_changed) QObject.connect(self.harris_btn, QtCore.SIGNAL('clicked()'), self.on_harris_detect) QObject.connect(self.stitch_btn, QtCore.SIGNAL('clicked()'), self.on_stitch) def on_add_image(self): image_path = QFileDialog.getOpenFileName(self, 'Select image', filter='Images (*.png *.jpg *.bmp)') ignored, name = os.path.split(unicode(image_path)) self.image_model.appendRow([QStandardItem(name), QStandardItem(image_path)]) def on_remove_image(self): row = self.image_list.selectionModel().currentIndex().row() if row == -1: return self.image_model.removeRows(row, 1) def on_row_changed(self, current, previous): row = current.row() if row == -1: file_path = PLACE_HOLDER else: file_path = self.image_model.item(row, 1).text() self.set_pixmap(QPixmap(file_path)) def on_harris_detect(self): row = self.image_list.selectionModel().currentIndex().row() if row == -1: return file_path = self.image_model.item(row, 1).text() image_pfm = convert_to_pfm(imread(unicode(file_path))) image = image_to_gray(image_pfm) kernel = self.ksize_slider.value() cornerness = harris_corner(image, ksize=kernel) is_corner = cornerness > 0.000001 suppress = non_max_suppression(cornerness, ksize=kernel) result = np.array(is_corner * suppress) zero = np.zeros_like(result) gray_img = np.dstack((zero, zero, draw_cross(result))) self.set_pixmap(QPixmap.fromImage(image_from_ndarray(np.array(gray_img + image_pfm)))) def on_stitch(self): i = 0 images = [] while self.image_model.item(i): file_path = self.image_model.item(i, 1).text() image = image_to_gray(convert_to_pfm(imread(unicode(file_path)))) images.append(image) i += 1 stitch(self.ksize_slider.value(), images) def set_pixmap(self, pixmap): self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), QtCore.Qt.KeepAspectRatio))
class ClusterWidget(QSplitter): def __init__(self, peaks, parent=None): QSplitter.__init__(self, Qt.Vertical, parent) self.peaks = peaks self.choosenOne = [pe for pe in self.peaks if pe is not None][0] #self.peakModel = QStandardItemModel() self.identificationModel = QStandardItemModel() self.setupUi() self.setModel() self.connect(self.calcCorr, SIGNAL('pressed()'), self.setRankValue) #self.setRankValue() def setupUi(self): self.widget = MSView( MSQtCanvas(self.peaks, "peaks@%s" % str(self.peaks[0]), labels={ 'bottom': 'RT(s)', 'left': 'INTENSITY' }, flags='peak')) self.tableView = QTableView() self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.setSortingEnabled(True) self.corr = QLabel("Nan") self.calcCorr = QPushButton("r_coef:") #v = QVBoxLayout(self) self.addWidget(self.widget) self.wid = QWidget() vb = QVBoxLayout() vb.addWidget(self.calcCorr) vb.addWidget(self.corr) hb = QHBoxLayout(self.wid) #if self.choosenOne.formulas: hb.addWidget(self.tableView) #else: # hb.addWidget(QLabel("Identification not performed yet...")) hb.addLayout(vb) self.addWidget(self.wid) def setModel(self): from gui.MetBaseGui import MSStandardItem #we assume that the different peaks have the same identifiers #TODO: may have to merge several stuffs later if self.choosenOne.formulas: self.identificationModel.setHorizontalHeaderLabels( ["score", "formula", "diff mass", "names"]) for i, f in enumerate(self.choosenOne.formulas.iterkeys()): self.identificationModel.setItem( i, 0, MSStandardItem(str(self.choosenOne.formulas[f]["score"]))) self.identificationModel.setItem(i, 1, QStandardItem(str(f))) self.identificationModel.setItem( i, 2, MSStandardItem(str( self.choosenOne.formulas[f]["diffmass"]))) self.identificationModel.setItem( i, 3, QStandardItem(self.choosenOne.formulas[f]["names"])) if self.choosenOne.formulas[f]["names"] != 'Not Found': for j in xrange(4): self.identificationModel.item(i, j).setBackground( QBrush(Qt.green)) else: for j in xrange(4): self.identificationModel.item(i, j).setBackground( QBrush(Qt.red)) self.tableView.setModel(self.identificationModel) def setRankValue(self): #m = qApp.instance().model #m.pearsonIntraCalculation() #peaks =[] #for spl in m: # peaks+=[p.r_coef for p in spl.mappedPeaks if p.r_coef] #if not self.choosenOne.r_coef: self.choosenOne.pCalcBasedOnPeakShape() #from _bisect import bisect_left #x = bisect_left(sorted(peaks), self.choosenOne.r_coef) s = '<br><b>%f</b></br>' % np.round(self.choosenOne.r_coef, 4) #s+='<br><b>Rank: </b>%d</br>'%abs(len(peaks)-x) self.corr.setText(s)
class DlgSqlWindow(QWidget, Ui_Dialog): nameChanged = pyqtSignal(str) def __init__(self, iface, db, parent=None): QWidget.__init__(self, parent) self.iface = iface self.db = db self.allowMultiColumnPk = isinstance(db, PGDatabase) # at the moment only PostGIS allows a primary key to span multiple columns, spatialite doesn't self.setupUi(self) self.setWindowTitle( u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString())) self.defaultLayerName = 'QueryLayer' if self.allowMultiColumnPk: self.uniqueColumnCheck.setText(self.trUtf8("Column(s) with unique values")) else: self.uniqueColumnCheck.setText(self.trUtf8("Column with unique values")) self.editSql.setFocus() self.editSql.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.initCompleter() # allow to copy results copyAction = QAction("copy", self) self.viewResult.addAction(copyAction) copyAction.setShortcuts(QKeySequence.Copy) copyAction.triggered.connect(self.copySelectedResults) self.btnExecute.clicked.connect(self.executeSql) self.btnClear.clicked.connect(self.clearSql) self.presetStore.clicked.connect(self.storePreset) self.presetDelete.clicked.connect(self.deletePreset) self.presetCombo.activated[str].connect(self.loadPreset) self.presetCombo.activated[str].connect(self.presetName.setText) self.updatePresetsCombobox() self.geomCombo.setEditable(True) self.geomCombo.lineEdit().setReadOnly(True) self.uniqueCombo.setEditable(True) self.uniqueCombo.lineEdit().setReadOnly(True) self.uniqueModel = QStandardItemModel(self.uniqueCombo) self.uniqueCombo.setModel(self.uniqueModel) if self.allowMultiColumnPk: self.uniqueCombo.setItemDelegate(QStyledItemDelegate()) self.uniqueModel.itemChanged.connect(self.uniqueChanged) # react to the (un)checking of an item self.uniqueCombo.lineEdit().textChanged.connect(self.uniqueTextChanged) # there are other events that change the displayed text and some of them can not be caught directly # hide the load query as layer if feature is not supported self._loadAsLayerAvailable = self.db.connector.hasCustomQuerySupport() self.loadAsLayerGroup.setVisible(self._loadAsLayerAvailable) if self._loadAsLayerAvailable: self.layerTypeWidget.hide() # show if load as raster is supported self.loadLayerBtn.clicked.connect(self.loadSqlLayer) self.getColumnsBtn.clicked.connect(self.fillColumnCombos) self.loadAsLayerGroup.toggled.connect(self.loadAsLayerToggled) self.loadAsLayerToggled(False) self._createViewAvailable = self.db.connector.hasCreateSpatialViewSupport() self.btnCreateView.setVisible(self._createViewAvailable) if self._createViewAvailable: self.btnCreateView.clicked.connect(self.createView) self.queryBuilderFirst = True self.queryBuilderBtn.setIcon(QIcon(":/db_manager/icons/sql.gif")) self.queryBuilderBtn.clicked.connect(self.displayQueryBuilder) self.presetName.textChanged.connect(self.nameChanged) def updatePresetsCombobox(self): self.presetCombo.clear() names = [] entries = QgsProject.instance().subkeyList('DBManager', 'savedQueries') for entry in entries: name = QgsProject.instance().readEntry('DBManager', 'savedQueries/' + entry + '/name')[0] names.append(name) for name in sorted(names): self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(-1) def storePreset(self): query = self._getSqlQuery() if query == "": return name = self.presetName.text() QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name', name) QgsProject.instance().writeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query', query) index = self.presetCombo.findText(name) if index == -1: self.presetCombo.addItem(name) self.presetCombo.setCurrentIndex(self.presetCombo.count() - 1) else: self.presetCombo.setCurrentIndex(index) def deletePreset(self): name = self.presetCombo.currentText() QgsProject.instance().removeEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__())) self.presetCombo.removeItem(self.presetCombo.findText(name)) self.presetCombo.setCurrentIndex(-1) def loadPreset(self, name): query = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/query')[0] name = QgsProject.instance().readEntry('DBManager', 'savedQueries/q' + unicode(name.__hash__()) + '/name')[0] self.editSql.setText(query) def loadAsLayerToggled(self, checked): self.loadAsLayerGroup.setChecked(checked) self.loadAsLayerWidget.setVisible(checked) if checked: self.fillColumnCombos() def clearSql(self): self.editSql.clear() self.editSql.setFocus() def executeSql(self): sql = self._getSqlQuery() if sql == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # delete the old model old_model = self.viewResult.model() self.viewResult.setModel(None) if old_model: old_model.deleteLater() cols = [] quotedCols = [] try: # set the new model model = self.db.sqlResultModel(sql, self) self.viewResult.setModel(model) self.lblResult.setText(self.tr("%d rows, %.1f seconds") % (model.affectedRows(), model.secs())) cols = self.viewResult.model().columnNames() for col in cols: quotedCols.append(self.db.connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return self.setColumnCombos(cols, quotedCols) self.update() QApplication.restoreOverrideCursor() def loadSqlLayer(self): hasUniqueField = self.uniqueColumnCheck.checkState() == Qt.Checked if hasUniqueField: if self.allowMultiColumnPk: checkedCols = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedCols.append(item.data()) uniqueFieldName = ",".join(checkedCols) elif self.uniqueCombo.currentIndex() >= 0: uniqueFieldName = self.uniqueModel.item(self.uniqueCombo.currentIndex()).data() else: uniqueFieldName = None else: uniqueFieldName = None hasGeomCol = self.hasGeometryCol.checkState() == Qt.Checked if hasGeomCol: geomFieldName = self.geomCombo.currentText() else: geomFieldName = None query = self._getSqlQuery() if query == "": return # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) from qgis.core import QgsMapLayer, QgsMapLayerRegistry layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer # get a new layer name names = [] for layer in QgsMapLayerRegistry.instance().mapLayers().values(): names.append(layer.name()) layerName = self.layerNameEdit.text() if layerName == "": layerName = self.defaultLayerName newLayerName = layerName index = 1 while newLayerName in names: index += 1 newLayerName = u"%s_%d" % (layerName, index) # create the layer layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType, self.avoidSelectById.isChecked()) if layer.isValid(): QgsMapLayerRegistry.instance().addMapLayers([layer], True) QApplication.restoreOverrideCursor() def fillColumnCombos(self): query = self._getSqlQuery() if query == "": return QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # get a new alias aliasIndex = 0 while True: alias = "_%s__%d" % ("subQuery", aliasIndex) escaped = re.compile('\\b("?)' + re.escape(alias) + '\\1\\b') if not escaped.search(query): break aliasIndex += 1 # remove a trailing ';' from query if present if query.strip().endswith(';'): query = query.strip()[:-1] # get all the columns cols = [] quotedCols = [] connector = self.db.connector sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % (unicode(query), connector.quoteId(alias)) c = None try: c = connector._execute(None, sql) cols = connector._get_cursor_columns(c) for col in cols: quotedCols.append(connector.quoteId(col)) except BaseError as e: QApplication.restoreOverrideCursor() DlgDbError.showError(e, self) self.uniqueModel.clear() self.geomCombo.clear() return finally: if c: c.close() del c self.setColumnCombos(cols, quotedCols) QApplication.restoreOverrideCursor() def setColumnCombos(self, cols, quotedCols): # get sensible default columns. do this before sorting in case there's hints in the column order (eg, id is more likely to be first) try: defaultGeomCol = next(col for col in cols if col in ['geom', 'geometry', 'the_geom', 'way']) except: defaultGeomCol = None try: defaultUniqueCol = [col for col in cols if 'id' in col][0] except: defaultUniqueCol = None colNames = sorted(zip(cols, quotedCols)) newItems = [] uniqueIsFilled = False for (col, quotedCol) in colNames: item = QStandardItem(col) item.setData(quotedCol) item.setEnabled(True) item.setCheckable(self.allowMultiColumnPk) item.setSelectable(not self.allowMultiColumnPk) if self.allowMultiColumnPk: matchingItems = self.uniqueModel.findItems(col) if matchingItems: item.setCheckState(matchingItems[0].checkState()) uniqueIsFilled = uniqueIsFilled or matchingItems[0].checkState() == Qt.Checked else: item.setCheckState(Qt.Unchecked) newItems.append(item) if self.allowMultiColumnPk: self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) self.uniqueChanged() else: previousUniqueColumn = self.uniqueCombo.currentText() self.uniqueModel.clear() self.uniqueModel.appendColumn(newItems) if self.uniqueModel.findItems(previousUniqueColumn): self.uniqueCombo.setEditText(previousUniqueColumn) uniqueIsFilled = True oldGeometryColumn = self.geomCombo.currentText() self.geomCombo.clear() self.geomCombo.addItems(cols) self.geomCombo.setCurrentIndex(self.geomCombo.findText(oldGeometryColumn, Qt.MatchExactly)) # set sensible default columns if the columns are not already set try: if self.geomCombo.currentIndex() == -1: self.geomCombo.setCurrentIndex(cols.index(defaultGeomCol)) except: pass items = self.uniqueModel.findItems(defaultUniqueCol) if items and not uniqueIsFilled: if self.allowMultiColumnPk: items[0].setCheckState(Qt.Checked) else: self.uniqueCombo.setEditText(defaultUniqueCol) try: pass except: pass def copySelectedResults(self): if len(self.viewResult.selectedIndexes()) <= 0: return model = self.viewResult.model() # convert to string using tab as separator text = model.headerToString("\t") for idx in self.viewResult.selectionModel().selectedRows(): text += "\n" + model.rowToString(idx.row(), "\t") QApplication.clipboard().setText(text, QClipboard.Selection) QApplication.clipboard().setText(text, QClipboard.Clipboard) def initCompleter(self): dictionary = None if self.db: dictionary = self.db.connector.getSqlDictionary() if not dictionary: # use the generic sql dictionary from .sql_dictionary import getSqlDictionary dictionary = getSqlDictionary() wordlist = [] for name, value in dictionary.iteritems(): wordlist += value # concat lists wordlist = list(set(wordlist)) # remove duplicates api = QsciAPIs(self.editSql.lexer()) for word in wordlist: api.add(word) api.prepare() self.editSql.lexer().setAPIs(api) def displayQueryBuilder(self): dlg = QueryBuilderDlg(self.iface, self.db, self, reset=self.queryBuilderFirst) self.queryBuilderFirst = False r = dlg.exec_() if r == QDialog.Accepted: self.editSql.setText(dlg.query) def createView(self): name, ok = QInputDialog.getText(None, "View name", "View name") if ok: try: self.db.connector.createSpatialView(name, self._getSqlQuery()) except BaseError as e: DlgDbError.showError(e, self) def _getSqlQuery(self): sql = self.editSql.selectedText() if len(sql) == 0: sql = self.editSql.text() return sql def uniqueChanged(self): # when an item is (un)checked, simply trigger an update of the combobox text self.uniqueTextChanged(None) def uniqueTextChanged(self, text): # Whenever there is new text displayed in the combobox, check if it is the correct one and if not, display the correct one. checkedItems = [] for item in self.uniqueModel.findItems("*", Qt.MatchWildcard): if item.checkState() == Qt.Checked: checkedItems.append(item.text()) label = ", ".join(checkedItems) if text != label: self.uniqueCombo.setEditText(label)
class ClusterWidget(QSplitter): def __init__(self, peaks, parent=None): QSplitter.__init__(self, Qt.Vertical, parent) self.peaks = peaks self.choosenOne = [pe for pe in self.peaks if pe is not None][0] #self.peakModel = QStandardItemModel() self.identificationModel = QStandardItemModel() self.setupUi() self.setModel() self.connect(self.calcCorr, SIGNAL('pressed()'), self.setRankValue) #self.setRankValue() def setupUi(self): self.widget = MSView(MSQtCanvas(self.peaks, "peaks@%s"%str(self.peaks[0]), labels={'bottom':'RT(s)', 'left':'INTENSITY'}, flags='peak')) self.tableView = QTableView() self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.setSortingEnabled(True) self.corr = QLabel("Nan") self.calcCorr = QPushButton("r_coef:") #v = QVBoxLayout(self) self.addWidget(self.widget) self.wid = QWidget() vb = QVBoxLayout() vb.addWidget(self.calcCorr) vb.addWidget(self.corr) hb = QHBoxLayout(self.wid) #if self.choosenOne.formulas: hb.addWidget(self.tableView) #else: # hb.addWidget(QLabel("Identification not performed yet...")) hb.addLayout(vb) self.addWidget(self.wid) def setModel(self): from gui.MetBaseGui import MSStandardItem #we assume that the different peaks have the same identifiers #TODO: may have to merge several stuffs later if self.choosenOne.formulas: self.identificationModel.setHorizontalHeaderLabels(["score", "formula", "diff mass", "names"]) for i, f in enumerate(self.choosenOne.formulas.iterkeys()): self.identificationModel.setItem(i, 0, MSStandardItem(str(self.choosenOne.formulas[f]["score"]))) self.identificationModel.setItem(i, 1, QStandardItem(str(f))) self.identificationModel.setItem(i, 2, MSStandardItem(str(self.choosenOne.formulas[f]["diffmass"]))) self.identificationModel.setItem(i, 3, QStandardItem(self.choosenOne.formulas[f]["names"])) if self.choosenOne.formulas[f]["names"] != 'Not Found': for j in xrange(4): self.identificationModel.item(i, j).setBackground(QBrush(Qt.green)) else: for j in xrange(4): self.identificationModel.item(i, j).setBackground(QBrush(Qt.red)) self.tableView.setModel(self.identificationModel) def setRankValue(self): #m = qApp.instance().model #m.pearsonIntraCalculation() #peaks =[] #for spl in m: # peaks+=[p.r_coef for p in spl.mappedPeaks if p.r_coef] #if not self.choosenOne.r_coef: self.choosenOne.pCalcBasedOnPeakShape() #from _bisect import bisect_left #x = bisect_left(sorted(peaks), self.choosenOne.r_coef) s = '<br><b>%f</b></br>'%np.round(self.choosenOne.r_coef, 4) #s+='<br><b>Rank: </b>%d</br>'%abs(len(peaks)-x) self.corr.setText(s)