def showParaAndRdnr(self, listItem): paraAndRdnr = self.listToParaAndRdnr.get(listItem.row()) model = QStandardItemModel(self) c = 0 for para, rdnrs in paraAndRdnr.iteritems(): l = self._createListItem(para, rdnrs) model.insertRow(c, l) c += 1 model.setHeaderData(0, Qt.Horizontal, "Paragraph") model.setHeaderData(1, Qt.Horizontal, "Randnummern") self._paraAndRdnr.setModel(model)
def setContent(self, content, blackList = False): model = QStandardItemModel(self) c = 0 for value in self.adjustContent(content): model.insertRow(c, self._createListItem(value)) c += 1 # self._currentCont[blackList] = content model.setHeaderData(0, Qt.Horizontal, "Wort") model.setHeaderData(1, Qt.Horizontal, "Vorkommen") self.setModel(model, blackList)
class UniteTableView(QTableView): def __init__(self,parent=None): QTableView.__init__(self,parent=parent) self.source_model = QStandardItemModel() self.setModel(self.source_model) self.proxy_model = QSortFilterProxyModel() def set_source_data(self, source_data): for row,row_data in enumerate(source_data): row_item = deque() for column in row_data: item = QStandardItem(str(column)) row_item.append(item) self.source_model.insertRow(row, list(row_item)) def set_column_name(self, column_names): pass
class VizRank(OWWidget): name = "Rank projections (Scatter Plot)" want_control_area = False def __init__(self, parent_widget): super().__init__() self.parent_widget = parent_widget self.running = False self.progress = None self.k = 10 self.projectionTable = QTableView() self.mainArea.layout().addWidget(self.projectionTable) self.projectionTable.setSelectionBehavior(QTableView.SelectRows) self.projectionTable.setSelectionMode(QTableView.SingleSelection) self.projectionTable.setSortingEnabled(True) self.projectionTableModel = QStandardItemModel(self) self.projectionTable.setModel(self.projectionTableModel) self.projectionTable.selectionModel().selectionChanged.connect( self.on_selection_changed) self.button = gui.button(self.mainArea, self, "Start evaluation", callback=self.toggle, default=True) self.resize(380, 512) self._initialize() def _initialize(self): self.running = False self.projectionTableModel.clear() self.projectionTableModel.setHorizontalHeaderLabels( ["Score", "Feature 1", "Feature 2"]) self.projectionTable.setColumnWidth(0, 60) self.projectionTable.setColumnWidth(1, 120) self.projectionTable.setColumnWidth(2, 120) self.button.setText("Start evaluation") self.button.setEnabled(False) self.pause = False self.data = None self.attrs = [] self.scores = [] self.i, self.j = 0, 0 if self.progress: self.progress.finish() self.progress = None self.information(0) if self.parent_widget.data: if not self.parent_widget.data.domain.class_var: self.information( 0, "Data with a class variable is required.") return if len(self.parent_widget.data.domain.attributes) < 2: self.information(0, 'At least 2 unique features are needed.') return if len(self.parent_widget.data) < 2: self.information(0, 'At least 2 instances are needed.') return self.button.setEnabled(True) def on_selection_changed(self, selected, deselected): """Called when the ranks view selection changes.""" a1 = selected.indexes()[1].data() a2 = selected.indexes()[2].data() self.parent_widget.update_attr(attributes=(a1, a2)) def toggle(self): self.running ^= 1 if self.running: self.button.setText("Pause") self.run() else: self.button.setText("Continue") self.button.setEnabled(False) def run(self): graph = self.parent_widget.graph y_full = self.parent_widget.data.Y if not self.attrs: self.attrs = self.score_heuristic() if not self.progress: self.progress = gui.ProgressBar( self, len(self.attrs) * (len(self.attrs) - 1) / 2) for i in range(self.i, len(self.attrs)): ind1 = graph.attribute_name_index[self.attrs[i]] for j in range(self.j, i): if not self.running: self.i, self.j = i, j if not self.projectionTable.selectedIndexes(): self.projectionTable.selectRow(0) self.button.setEnabled(True) return ind2 = graph.attribute_name_index[self.attrs[j]] X = graph.scaled_data[[ind1, ind2], :] valid = graph.get_valid_list([ind1, ind2]) X = X[:, valid].T if X.shape[0] < self.k: self.progress.advance() continue y = y_full[valid] n_neighbors = min(self.k, len(X) - 1) knn = NearestNeighbors(n_neighbors=n_neighbors).fit(X) ind = knn.kneighbors(return_distance=False) if self.parent_widget.data.domain.has_discrete_class: score = np.sum(y[ind] == y.reshape(-1, 1)) / ( len(y_full) * n_neighbors) else: score = r2_score(y, np.mean( y[ind], axis=1)) * (len(y) / len(y_full)) pos = bisect_left(self.scores, score) self.projectionTableModel.insertRow( len(self.scores) - pos, [ QStandardItem("{:.4f}".format(score)), QStandardItem(self.attrs[j]), QStandardItem(self.attrs[i]) ]) self.scores.insert(pos, score) self.progress.advance() self.j = 0 self.progress.finish() if not self.projectionTable.selectedIndexes(): self.projectionTable.selectRow(0) self.button.setText("Finished") self.button.setEnabled(False) def score_heuristic(self): X = self.parent_widget.graph.scaled_data.T Y = self.parent_widget.data.Y dom = Domain( [ContinuousVariable(str(i)) for i in range(X.shape[1])], self.parent_widget.data.domain.class_vars) data = Table(dom, X, Y) relief = ReliefF if isinstance(dom.class_var, DiscreteVariable) else RReliefF weights = relief(n_iterations=100, k_nearest=self.k)(data) attrs = sorted(zip( weights, (x.name for x in self.parent_widget.data.domain.attributes)), reverse=True) return [a for _, a in attrs]
class ResultView(QWidget): """This class represent a search result view. """ def __init__(self, filter='', attributes=[], resultlist=[], parent=None): """Initialize a result view for the `SearchPlugin`. :param filter: the filter applied on the search :type filter: string :param attributes: a list containing the attributes used in the search operation. Usually extracted from the `filter`. :type attributes: list :param resultlist: a list of `SmartDataObject` from the search operation. :type resultlist: list :param parent: the parent for this widget. :type parent: QWidget """ super(ResultView, self).__init__(parent) self.setObjectName('ResultView') self.layout = QtGui.QVBoxLayout(self) # Only display the no-result message if resultlist is empty if len(resultlist) == 0: self.retranslate(all=False) self.onNoResult() return # The proxy model is used for sort and filter support self.proxymodel = QSortFilterProxyModel(self) self.proxymodel.setDynamicSortFilter(True) self.headerdata = ['dn'] self.headerdata.extend(attributes) self.resultdata = resultlist # FIXME: should we create a custom item model ? self.model = QStandardItemModel(0, len(self.headerdata), parent=self) #self.model = ResultItemModel(self) #self.model = ResultItemModel(self.headerdata, self.resultdata, self) self.proxymodel.setSourceModel(self.model) self.resultview = QTreeView(self) self.resultview.setUniformRowHeights(True) self.resultview.setRootIsDecorated(False) self.resultview.setAlternatingRowColors(True) self.resultview.setSortingEnabled(True) self.resultview.setModel(self.proxymodel) # For right-click context menu self.resultview.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.resultview.setSelectionMode(QAbstractItemView.ExtendedSelection) self.layout.addWidget(self.resultview) # The filter box enables the user to filter the returned search # results. It becomes accessible with Ctrl-F (QKeySequence.Find) self.filterBox = ResultFilterWidget(self.headerdata, parent=self) self.filterBox.setVisible(False) self.layout.addWidget(self.filterBox) # We need to call the retranslate method before populating # the result data self.retranslate() #self.model.populateHeader(self.headerdata) #self.model.populateModel(self.resultdata) self.setHeaderData(self.headerdata) self.setResultData(self.resultdata) self.resultview.resizeColumnToContents(0) self.__createContextMenu() self.__connectSlots() def __connectSlots(self): """Connect signal and slots. """ self.resultview.customContextMenuRequested.connect( self.onContextMenuRequested) self.filterBox.inputEdit.textChanged['QString'].connect( self.onFilterInputChanged) self.filterBox.columnBox.currentIndexChanged[int].connect( self.onFilterColumnChanged) def __getVSpacer(self): return QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) def __createContextMenu(self): """Display the context menu. """ self.contextMenu = QtGui.QMenu() self.contextMenuView = QtGui.QAction(self) self.contextMenuDelete = QtGui.QAction(self) self.contextMenuExport = QtGui.QAction(self) self.contextMenu.addAction(self.contextMenuView) self.contextMenu.addAction(self.contextMenuDelete) self.contextMenu.addAction(self.contextMenuExport) # Connect the context menu actions to the correct slots self.contextMenuView.triggered.connect(self.onViewItemsSelected) self.contextMenuDelete.triggered.connect(self.onDeleteItemsSelected) self.contextMenuExport.triggered.connect(self.onExportItemsSelected) def onNoResult(self): """Adds a styled *no result* message to the main layout. """ font = QtGui.QFont() font.setBold(True) sadface = QtGui.QLabel(self) sadface.setPixmap(pixmapFromTheme('face-sad', ':/icons/48/face-sad')) noresult = QtGui.QLabel(self) noresult.setText(self.str_NO_RESULT) noresult.setFont(font) hlayout = QtGui.QHBoxLayout() hlayout.addItem(self.__getVSpacer()) hlayout.addWidget(sadface) hlayout.addWidget(noresult) hlayout.addItem(self.__getVSpacer()) self.layout.addLayout(hlayout) def setHeaderData(self, data=[]): """Populates the ``resultview`` model with header data. Parameters: - `data`: a list with header items. Usually this is the attributelist from the LDAP search. """ i = 0 for header in data: self.model.setHeaderData(i, QtCore.Qt.Horizontal, header) i += 1 def setResultData(self, data=[]): """Populates the ``resultview`` model with result data. Parameters: - `data`: a list containing the SmartDataObjects representing items in the LDAP search result. """ row = 0 for obj in data: self.model.insertRow(row) col = 0 for attr in self.headerdata: if self.isDistinguishedName(attr): modelData = obj.getPrettyDN() elif self.isObjectClass(attr): modelData = ','.join(obj.getObjectClasses()) elif obj.hasAttribute(attr): if obj.isAttributeBinary(attr): modelData = self.str_BINARY_DATA else: modelData = ','.join(obj.getAttributeValueList(attr)) self.model.setData(self.model.index(row, col), modelData) col += 1 row += 1 def isDistinguishedName(self, attr): """Returns ``True`` if `attr` is a distinguished name, ``False`` otherwise. Parameters: - `attr`: the LDAP string attribute value to check. """ return attr.lower() == 'dn' def isObjectClass(self, attr): """Returns ``True`` if `attr` is an object class, ``False`` otherwise. Parameters: - `attr`: the LDAP string attribute value to check. """ return attr.lower() == 'objectclass' def onContextMenuRequested(self, point): """Display the context menu """ # FIXME: In order to be able to export, delete and view search # result entries. We should make use of the various dialogs in # the Browser plugin. Unitl we have refactored the design in a # way that allow us to use these without accessing the browser # modules, we simple don't provide these options yet. return self.selection = self.resultview.selectedIndexes() deleteSupport = True exportSupport = True rowsselected = len(self.selection) / len(self.headerdata) if not rowsselected > 0: self.contextMenu.setEnabled(False) self.contextMenu.exec_(self.resultview.mapToGlobal(point)) return self.contextMenu.setEnabled(True) # Look over at Browser plugin for implementation of # multiselect and operation support validation print rowsselected self.contextMenuView.setEnabled(True) if rowsselected == 1: self.contextMenuView.setText(self.str_VIEW_ITEM) else: self.contextMenuView.setText(self.str_VIEW_ITEMS) if deleteSupport: self.contextMenuDelete.setEnabled(True) if rowsselected == 1: self.contextMenuDelete.setText(self.str_DELETE_ITEM) else: self.contextMenuDelete.setText(self.str_DELETE_ITEMS) if exportSupport: self.contextMenuExport.setEnabled(True) if rowsselected == 1: self.contextMenuExport.setText(self.str_EXPORT_ITEM) else: self.contextMenuExport.setText(self.str_EXPORT_ITEMS) # Finally we execute the context menu self.contextMenu.exec_(self.resultview.mapToGlobal(point)) def onViewItemsSelected(self): """Slot for the *view* context menu action. """ raise NotImplementedError( 'Need to implement a proper model for this to be supported') def onDeleteItemsSelected(self): """Slot for the *delete* context menu action. """ msg = 'Delete from the Search Plugin is not implemented jet.' dialog = DeleteDialog(self, msg) dialog.setDeleteItems([]) dialog.exec_() def onExportItemsSelected(self): """Slot for the 'export' context menu action. """ msg = 'Export from the Search Plugin is not implemented jet.' dialog = ExportDialog(self, msg) # Only for proof of concept dialog.setExportData([]) dialog.exec_() def onFilterBoxVisibilityChanged(self, visible): """Slot for the QKeySequence.Find. - `visible`: a boolean value indicating wether or not to toggle the filter box widget visibility on or off. """ if visible: self.filterBox.setVisible(True) self.filterBox.inputEdit.setFocus() else: # I belive it's common practise to clear the filter when # the filter box is closed. This is at least the way the # filter boxes works for most webbrowsers. self.filterBox.inputEdit.clear() self.filterBox.setVisible(False) self.resultview.setFocus() def onFilterInputChanged(self, filter=''): """Slot for the filter input in the result filter widget. We get the selected syntax from the syntax combobox """ # The PyQt4 QVariant is causing some problems here, when we try # to use the <combobox>.itemData directly, even though the data # holds valid QRexExp.PatternSyntax values. # We therefore need to explicitly make the QVariant and integer. i = self.filterBox.syntaxBox.currentIndex() syntaxIndex = self.filterBox.syntaxBox.itemData(i).toInt()[0] syntax = QtCore.QRegExp.PatternSyntax(syntaxIndex) # As of now we do filtering in a case insensitive way, until we # come up with a way to introduce case sensitivity selection in a # UI inexpensive way. We want to keep the filter widget as clean # and simple as possible. regex = QtCore.QRegExp(filter, QtCore.Qt.CaseInsensitive, syntax) self.proxymodel.setFilterRegExp(regex) def onFilterColumnChanged(self, index): """Slot for the column combobox in the filter box widget. """ self.proxymodel.setFilterKeyColumn(index) def retranslate(self, all=True): """For dynamic translation support. """ self.str_VIEW_ITEM = QtGui.QApplication.translate( 'ResultView', 'View Item') self.str_VIEW_ITEMS = QtGui.QApplication.translate( 'ResultView', 'View Items') self.str_DELETE_ITEM = QtGui.QApplication.translate( 'ResultView', 'Delete Item') self.str_DELETE_ITEMS = QtGui.QApplication.translate( 'ResultView', 'Delete Items') self.str_EXPORT_ITEM = QtGui.QApplication.translate( 'ResultView', 'Export Item') self.str_EXPORT_ITEMS = QtGui.QApplication.translate( 'ResultView', 'Export Items') self.str_NO_RESULT = QtGui.QApplication.translate( 'ResultView', 'Sorry, no result to display!') self.str_BINARY_DATA = QtGui.QApplication.translate( 'ResultView', 'Binary Data') if all: self.filterBox.retranslate()
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 VizRankDialog(QDialog, ProgressBarMixin, WidgetMessagesMixin): """ Base class for VizRank dialogs, providing a GUI with a table and a button, and the skeleton for managing the evaluation of visualizations. Derived classes must provide methods - `iterate_states` for generating combinations (e.g. pairs of attritutes), - `compute_score(state)` for computing the score of a combination, - `row_for_state(state)` that returns a list of items inserted into the table for the given state. and, optionally, - `state_count` that returns the number of combinations (used for progress bar) - `on_selection_changed` that handles event triggered when the user selects a table row. The method should emit signal `VizRankDialog.selectionChanged(object)`. The class provides a table and a button. A widget constructs a single instance of this dialog in its `__init__`, like (in Sieve) by using a convenience method :obj:`add_vizrank`:: self.vizrank, self.vizrank_button = SieveRank.add_vizrank( box, self, "Score Combinations", self.set_attr) When the widget receives new data, it must call the VizRankDialog's method :obj:`VizRankDialog.initialize()` to clear the GUI and reset the state. Clicking the Start button calls method `run` (and renames the button to Pause). Run sets up a progress bar by getting the number of combinations from :obj:`VizRankDialog.state_count()`. It restores the paused state (if any) and calls generator :obj:`VizRankDialog.iterate_states()`. For each generated state, it calls :obj:`VizRankDialog.score(state)`, which must return the score (lower is better) for this state. If the returned state is not `None`, the data returned by `row_for_state` is inserted at the appropriate place in the table. Args: master (Orange.widget.OWWidget): widget to which the dialog belongs Attributes: master (Orange.widget.OWWidget): widget to which the dialog belongs captionTitle (str): the caption for the dialog. This can be a class attribute. `captionTitle` is used by the `ProgressBarMixin`. """ captionTitle = "" processingStateChanged = Signal(int) progressBarValueChanged = Signal(float) messageActivated = Signal(Msg) messageDeactivated = Signal(Msg) selectionChanged = Signal(object) def __init__(self, master): """Initialize the attributes and set up the interface""" QDialog.__init__(self, windowTitle=self.captionTitle) WidgetMessagesMixin.__init__(self) self.setLayout(QVBoxLayout()) self.insert_message_bar() self.layout().insertWidget(0, self.message_bar) self.master = master self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.rank_model = QStandardItemModel(self) self.rank_table = view = QTableView( selectionBehavior=QTableView.SelectRows, selectionMode=QTableView.SingleSelection, showGrid=False ) view.setItemDelegate(HorizontalGridDelegate()) view.setModel(self.rank_model) view.selectionModel().selectionChanged.connect(self.on_selection_changed) view.horizontalHeader().setStretchLastSection(True) view.horizontalHeader().hide() self.layout().addWidget(view) self.button = gui.button(self, self, "Start", callback=self.toggle, default=True) @classmethod def add_vizrank(cls, widget, master, button_label, set_attr_callback): """ Equip the widget with VizRank button and dialog, and monkey patch the widget's `closeEvent` and `hideEvent` to close/hide the vizrank, too. Args: widget (QWidget): the widget into whose layout to insert the button master (Orange.widgets.widget.OWWidget): the master widget button_label: the label for the button set_attr_callback: the callback for setting the projection chosen in the vizrank Returns: tuple with Vizrank dialog instance and push button """ # Monkey patching could be avoided by mixing-in the class (not # necessarily a good idea since we can make a mess of multiple # defined/derived closeEvent and hideEvent methods). Furthermore, # per-class patching would be better than per-instance, but we don't # want to mess with meta-classes either. vizrank = cls(master) button = gui.button(widget, master, button_label, callback=vizrank.reshow, enabled=False) vizrank.selectionChanged.connect(lambda args: set_attr_callback(*args)) master_close_event = master.closeEvent master_hide_event = master.hideEvent def closeEvent(event): vizrank.close() master_close_event(event) def hideEvent(event): vizrank.hide() master_hide_event(event) master.closeEvent = closeEvent master.hideEvent = hideEvent return vizrank, button def reshow(self): """Put the widget on top of all windows """ self.show() self.raise_() self.activateWindow() def initialize(self): """ Clear and initialize the dialog. This method must be called by the widget when the data is reset, e.g. from `set_data` handler. """ self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.rank_model.clear() self.button.setText("Start") self.button.setEnabled(self.check_preconditions()) def check_preconditions(self): """Check whether there is sufficient data for ranking.""" return True def on_selection_changed(self, selected, deselected): """ Set the new visualization in the widget when the user select a row in the table. If derived class does not reimplement this, the table gives the information but the user can't click it to select the visualization. Args: selected: the index of the selected item deselected: the index of the previously selected item """ pass def iterate_states(self, initial_state): """ Generate all possible states (e.g. attribute combinations) for the given data. The content of the generated states is specific to the visualization. This method must be defined in the derived classes. Args: initial_state: initial state; None if this is the first call """ raise NotImplementedError def state_count(self): """ Return the number of states for the progress bar. Derived classes should implement this to ensure the proper behaviour of the progress bar""" return 0 def compute_score(self, state): """ Abstract method for computing the score for the given state. Smaller scores are better. Args: state: the state, e.g. the combination of attributes as generated by :obj:`state_count`. """ raise NotImplementedError def row_for_state(self, state, score): """ Abstract method that return the items that are inserted into the table. Args: state: the state, e.g. combination of attributes score: score, computed by :obj:`compute_score` """ raise NotImplementedError def _select_first_if_none(self): if not self.rank_table.selectedIndexes(): self.rank_table.selectRow(0) def run(self): """Compute and show scores""" with self.progressBar(self.state_count()) as progress: progress.advance(self.saved_progress) for state in self.iterate_states(self.saved_state): if not self.keep_running: self.saved_state = state self.saved_progress = progress.count self._select_first_if_none() return score = self.compute_score(state) if score is not None: pos = bisect_left(self.scores, score) self.rank_model.insertRow(pos, self.row_for_state(score, state)) self.scores.insert(pos, score) progress.advance() self._select_first_if_none() self.button.setText("Finished") self.button.setEnabled(False) def toggle(self): """Start or pause the computation.""" self.keep_running = not self.keep_running if self.keep_running: self.button.setText("Pause") self.run() else: self._select_first_if_none() self.button.setText("Continue")
class route: def __init__(self, name='', desc='', survey_date=None, run_no=''): self.name = name self.desc = desc self.survey_date = survey_date self.run_no = run_no self.model = QStandardItemModel() #self.model=route_model.route_model() self.model.setColumnCount(len(cols)) [self.model.setHeaderData(cols[c], Qt.Horizontal, c) for c in cols] #def add_section(self,label,snode,rev,length,rbt,ch,desc,wkt,row=0): # #self.model.insertRow(row,[make_cell(label),make_cell(rev,True),make_cell(desc,True),make_cell(ch),make_cell(snode),make_cell(length),make_cell(rbt),make_cell(wkt)]) def add_section(self, label, rev, desc, ch, snode, length, rbt, wkt, row=0): self.model.insertRow(row, [ make_cell(label), make_cell(rev, True), make_cell(desc, True), make_cell(ch), make_cell(snode), make_cell(length), make_cell(rbt), make_cell(wkt) ]) #converts to qgis features def to_features(self, layer): return [ self.to_feat(i, layer) for i in range(0, self.model.rowCount()) ] def remove_rows(self, rows): # removing changes following row numbers.Start with highest row number. for r in reversed(sorted(rows)): self.model.takeRow(r) #key like [route_att:feature_att] def add_feat(self, f, transform, row, rev, key): geom = f.geometry() geom.transform(transform) snode = f[key['snode']] if rev: geom = reversed_geom(geom) snode = f[key['enode']] #chainage will be recalculated so irrelevant self.add_section(f[key['section_label']], rev, f[key['section_description']], 0, snode, f[key['section_length']], f[key['roundabout']], geom.exportToWkt(), row) # g.geometry().asWkt()))) for qgis 3 #make qgis feature from row of model def to_feat(self, row, layer): feat = QgsFeature(layer.fields()) for c in cols: if c != 'wkt': feat.setAttribute(c, self.get_val(row, cols[c])) feat.setAttribute('route', self.name) feat.setAttribute('route_description', self.desc) feat.setAttribute('survey_date', self.desc) feat.setAttribute('run_no', self.run_no) if self.get_val(row, cols['reversed']): geom = reversed_geom( QgsGeometry.fromWkt(self.get_val(row, cols['wkt']))) else: geom = QgsGeometry.fromWkt(self.get_val(row, cols['wkt'])) feat.setGeometry(geom) return feat def get_val(self, row, col): return self.model.item(row, col).data(Qt.EditRole) def __eq__(self, other): return self.name == other.name and self.desc == other.desc and self.run_no == other.run_no #and self.survey_date=other.survey_date #def __add__(self,other): # if self==other: # r=route(self.name,self.desc,self.survey_date,self.run_no) # else: # raise ValueError('conflicting route data') def consume_other(self, other): if self == other: for i in other.model.rowCount(): self.model.appendRow(other.model.takeRow(i)) else: raise ValueError('conflicting route data')
class VizRankDialog(QDialog, ProgressBarMixin, WidgetMessagesMixin): """ Base class for VizRank dialogs, providing a GUI with a table and a button, and the skeleton for managing the evaluation of visualizations. Derived classes need to provide generators of combinations (e.g. pairs of attribtutes) and the scoring function. The widget stores the current upon pause, and restores it upon continuation. The class provides a table and a button. A widget constructs a single instance of this dialog in its `__init__`, like (in Sieve): self.vizrank = SieveRank(self) self.vizrank_button = gui.button( box, self, "Score Combinations", callback=self.vizrank.reshow) The widget (the argument `self`) above is stored in `VizRankDialog`'s attribute `master` since derived classes will need to interact with is. When the widget receives new data, it must call the VizRankDialog's method :obj:`VizRankDialog.initialize()` to clear the GUI and reset the state. Clicking the Start button calls method `run` (and renames the button to Pause). Run sets up a progress bar by getting the number of combinations from :obj:`VizRankDialog.state_count()`. It restores the paused state (if any) and calls generator :obj:`VizRankDialog.iterate_states()`. For each generated state, it calls :obj:`VizRankDialog.score(state)`, which must return the score (lower is better) for this state. If the returned state is not `None`, the data returned by `row_for_state` is inserted at the appropriate place in the table. Args: master (Orange.widget.OWWidget): widget to which the dialog belongs Attributes: master (Orange.widget.OWWidget): widget to which the dialog belongs captionTitle (str): the caption for the dialog. This can be a class attribute. `captionTitle` is used by the `ProgressBarMixin`. """ captionTitle = "" processingStateChanged = Signal(int) progressBarValueChanged = Signal(float) messageActivated = Signal(Msg) messageDeactivated = Signal(Msg) def __init__(self, master): """Initialize the attributes and set up the interface""" QDialog.__init__(self, windowTitle=self.captionTitle) WidgetMessagesMixin.__init__(self) self.setLayout(QVBoxLayout()) self.insert_message_bar() self.layout().insertWidget(0, self.message_bar) self.master = master self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.rank_model = QStandardItemModel(self) self.rank_table = view = QTableView( selectionBehavior=QTableView.SelectRows, selectionMode=QTableView.SingleSelection, showGrid=False) view.setItemDelegate(HorizontalGridDelegate()) view.setModel(self.rank_model) view.selectionModel().selectionChanged.connect( self.on_selection_changed) view.horizontalHeader().setStretchLastSection(True) view.horizontalHeader().hide() self.layout().addWidget(view) self.button = gui.button(self, self, "Start", callback=self.toggle, default=True) def reshow(self): """Put the widget on top of all windows """ self.show() self.raise_() self.activateWindow() def initialize(self): """ Clear and initialize the dialog. This method must be called by the widget when the data is reset, e.g. from `set_data` handler. """ self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.rank_model.clear() self.button.setText("Start") self.button.setEnabled(self.check_preconditions()) def check_preconditions(self): """Check whether there is sufficient data for ranking.""" return True def on_selection_changed(self, selected, deselected): """ Set the new visualization in the widget when the user select a row in the table. If derived class does not reimplement this, the table gives the information but the user can't click it to select the visualization. Args: selected: the index of the selected item deselected: the index of the previously selected item """ pass def iterate_states(self, initial_state): """ Generate all possible states (e.g. attribute combinations) for the given data. The content of the generated states is specific to the visualization. This method must be defined in the derived classes. Args: initial_state: initial state; None if this is the first call """ raise NotImplementedError def state_count(self): """ Return the number of states for the progress bar. Derived classes should implement this to ensure the proper behaviour of the progress bar""" return 0 def compute_score(self, state): """ Abstract method for computing the score for the given state. Smaller scores are better. Args: state: the state, e.g. the combination of attributes as generated by :obj:`state_count`. """ raise NotImplementedError def row_for_state(self, state, score): """ Abstract method that return the items that are inserted into the table. Args: state: the state, e.g. combination of attributes score: score, computed by :obj:`compute_score` """ raise NotImplementedError def _select_first_if_none(self): if not self.rank_table.selectedIndexes(): self.rank_table.selectRow(0) def run(self): """Compute and show scores""" with self.progressBar(self.state_count()) as progress: progress.advance(self.saved_progress) for state in self.iterate_states(self.saved_state): if not self.keep_running: self.saved_state = state self.saved_progress = progress.count self._select_first_if_none() return score = self.compute_score(state) if score is not None: pos = bisect_left(self.scores, score) self.rank_model.insertRow(pos, self.row_for_state(score, state)) self.scores.insert(pos, score) progress.advance() self._select_first_if_none() self.button.setText("Finished") self.button.setEnabled(False) def toggle(self): """Start or pause the computation.""" self.keep_running = not self.keep_running if self.keep_running: self.button.setText("Pause") self.run() else: self._select_first_if_none() self.button.setText("Continue")
def init_baud(self): model = QStandardItemModel() model.insertRow(0,QStandardItem('38400')) model.insertRow(1,QStandardItem('500000')) self.ui.baud.setModel(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 VizRankDialog(QDialog, ProgressBarMixin, WidgetMessagesMixin): """ Base class for VizRank dialogs, providing a GUI with a table and a button, and the skeleton for managing the evaluation of visualizations. Derived classes must provide methods - `iterate_states` for generating combinations (e.g. pairs of attritutes), - `compute_score(state)` for computing the score of a combination, - `row_for_state(state)` that returns a list of items inserted into the table for the given state. and, optionally, - `state_count` that returns the number of combinations (used for progress bar) - `on_selection_changed` that handles event triggered when the user selects a table row. The method should emit signal `VizRankDialog.selectionChanged(object)`. The class provides a table and a button. A widget constructs a single instance of this dialog in its `__init__`, like (in Sieve) by using a convenience method :obj:`add_vizrank`:: self.vizrank, self.vizrank_button = SieveRank.add_vizrank( box, self, "Score Combinations", self.set_attr) When the widget receives new data, it must call the VizRankDialog's method :obj:`VizRankDialog.initialize()` to clear the GUI and reset the state. Clicking the Start button calls method `run` (and renames the button to Pause). Run sets up a progress bar by getting the number of combinations from :obj:`VizRankDialog.state_count()`. It restores the paused state (if any) and calls generator :obj:`VizRankDialog.iterate_states()`. For each generated state, it calls :obj:`VizRankDialog.score(state)`, which must return the score (lower is better) for this state. If the returned state is not `None`, the data returned by `row_for_state` is inserted at the appropriate place in the table. Args: master (Orange.widget.OWWidget): widget to which the dialog belongs Attributes: master (Orange.widget.OWWidget): widget to which the dialog belongs captionTitle (str): the caption for the dialog. This can be a class attribute. `captionTitle` is used by the `ProgressBarMixin`. """ captionTitle = "" processingStateChanged = Signal(int) progressBarValueChanged = Signal(float) messageActivated = Signal(Msg) messageDeactivated = Signal(Msg) selectionChanged = Signal(object) def __init__(self, master): """Initialize the attributes and set up the interface""" QDialog.__init__(self, windowTitle=self.captionTitle) WidgetMessagesMixin.__init__(self) self.setLayout(QVBoxLayout()) self.insert_message_bar() self.layout().insertWidget(0, self.message_bar) self.master = master self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.rank_model = QStandardItemModel(self) self.rank_table = view = QTableView( selectionBehavior=QTableView.SelectRows, selectionMode=QTableView.SingleSelection, showGrid=False) view.setItemDelegate(HorizontalGridDelegate()) view.setModel(self.rank_model) view.selectionModel().selectionChanged.connect( self.on_selection_changed) view.horizontalHeader().setStretchLastSection(True) view.horizontalHeader().hide() self.layout().addWidget(view) self.button = gui.button( self, self, "Start", callback=self.toggle, default=True) @classmethod def add_vizrank(cls, widget, master, button_label, set_attr_callback): """ Equip the widget with VizRank button and dialog, and monkey patch the widget's `closeEvent` and `hideEvent` to close/hide the vizrank, too. Args: widget (QWidget): the widget into whose layout to insert the button master (Orange.widgets.widget.OWWidget): the master widget button_label: the label for the button set_attr_callback: the callback for setting the projection chosen in the vizrank Returns: tuple with Vizrank dialog instance and push button """ # Monkey patching could be avoided by mixing-in the class (not # necessarily a good idea since we can make a mess of multiple # defined/derived closeEvent and hideEvent methods). Furthermore, # per-class patching would be better than per-instance, but we don't # want to mess with meta-classes either. vizrank = cls(master) button = gui.button( widget, master, button_label, callback=vizrank.reshow, enabled=False) vizrank.selectionChanged.connect(lambda args: set_attr_callback(*args)) master_close_event = master.closeEvent master_hide_event = master.hideEvent def closeEvent(event): vizrank.close() master_close_event(event) def hideEvent(event): vizrank.hide() master_hide_event(event) master.closeEvent = closeEvent master.hideEvent = hideEvent return vizrank, button def reshow(self): """Put the widget on top of all windows """ self.show() self.raise_() self.activateWindow() def initialize(self): """ Clear and initialize the dialog. This method must be called by the widget when the data is reset, e.g. from `set_data` handler. """ self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.rank_model.clear() self.button.setText("Start") self.button.setEnabled(self.check_preconditions()) def check_preconditions(self): """Check whether there is sufficient data for ranking.""" return True def on_selection_changed(self, selected, deselected): """ Set the new visualization in the widget when the user select a row in the table. If derived class does not reimplement this, the table gives the information but the user can't click it to select the visualization. Args: selected: the index of the selected item deselected: the index of the previously selected item """ pass def iterate_states(self, initial_state): """ Generate all possible states (e.g. attribute combinations) for the given data. The content of the generated states is specific to the visualization. This method must be defined in the derived classes. Args: initial_state: initial state; None if this is the first call """ raise NotImplementedError def state_count(self): """ Return the number of states for the progress bar. Derived classes should implement this to ensure the proper behaviour of the progress bar""" return 0 def compute_score(self, state): """ Abstract method for computing the score for the given state. Smaller scores are better. Args: state: the state, e.g. the combination of attributes as generated by :obj:`state_count`. """ raise NotImplementedError def row_for_state(self, state, score): """ Abstract method that return the items that are inserted into the table. Args: state: the state, e.g. combination of attributes score: score, computed by :obj:`compute_score` """ raise NotImplementedError def _select_first_if_none(self): if not self.rank_table.selectedIndexes(): self.rank_table.selectRow(0) def run(self): """Compute and show scores""" with self.progressBar(self.state_count()) as progress: progress.advance(self.saved_progress) for state in self.iterate_states(self.saved_state): if not self.keep_running: self.saved_state = state self.saved_progress = progress.count self._select_first_if_none() return score = self.compute_score(state) if score is not None: pos = bisect_left(self.scores, score) self.rank_model.insertRow( pos, self.row_for_state(score, state)) self.scores.insert(pos, score) progress.advance() self._select_first_if_none() self.button.setText("Finished") self.button.setEnabled(False) def toggle(self): """Start or pause the computation.""" self.keep_running = not self.keep_running if self.keep_running: self.button.setText("Pause") self.run() else: self._select_first_if_none() self.button.setText("Continue")
class SettingsWidget(QMainWindow): def __init__(self, main_ui_handler, config_helper, logger): QMainWindow.__init__(self, main_ui_handler.main_widget, Qt.Window) self.setAttribute(Qt.WA_Maemo5StackedWindow) self.setWindowTitle("DropN900 - Settings") self.setCentralWidget(QWidget()) self.ui = Ui_SettingsWidget() self.ui.setupUi(self.centralWidget()) self.main_ui_handler = main_ui_handler self.tree_controller = main_ui_handler.tree_controller self.config_helper = config_helper self.datahandler = config_helper.datahandler self.logger = logger self.store_settings = False self.backup_settings = None self.connection_manager = None self.sync_manager = None # Icons for titles self.ui.downloading_icon.setPixmap(QPixmap(self.datahandler.datapath("ui/icons/download.png"))) self.ui.authentication_icon.setPixmap(QPixmap(self.datahandler.datapath("ui/icons/authentication.png"))) self.ui.sync_icon.setPixmap(QPixmap(self.datahandler.datapath("ui/icons/folder-sync.png"))) # Connects self.ui.button_save.clicked.connect(self.save_setting_clicked) self.ui.button_cancel.clicked.connect(self.hide) self.ui.button_browse_folder.clicked.connect(self.set_default_dl_folder) self.ui.button_reset_auth.clicked.connect(self.reset_authentication_clicked) self.ui.button_sync_now.clicked.connect(self.sync_now_clicked) self.ui.checkbox_enable_sync.toggled.connect(self.set_sync_widgets_enabled) self.ui.checkbox_only_wlan_sync.toggled.connect(self.set_wlan_sync_only_enabled) # Create maemo value button for selecting sync location self.sync_path_model = QStandardItemModel(0,1) self.sync_path_pick_selector = QMaemo5ListPickSelector() self.sync_path_pick_selector.setModel(self.sync_path_model) self.sync_path_pick_selector.selected.connect(self.sync_path_selected) self.sync_path_button = QMaemo5ValueButton("Sync Path") self.sync_path_button.setValueLayout(QMaemo5ValueButton.ValueUnderTextCentered) self.sync_path_button.setPickSelector(self.sync_path_pick_selector) self.ui.sync_buttons_layout.insertWidget(0, self.sync_path_button) self.sync_path_button.setStyleSheet("color:white; QPushbutton { color:white; }") # Get initial settings and set to ui init_settings = self.config_helper.get_current_settings() if init_settings == None: self.logger.config("Settings data from file invalid, writing defaults") self.config_helper.write_default_settings() init_settings = self.config_helper.get_current_settings() self.set_settings_to_ui(init_settings["download"], init_settings["authentication"], init_settings["automated-sync"]) action_restore_defaults = self.menuBar().addAction("Restore Defaults") action_restore_defaults.triggered.connect(self.restore_defaults) def setup(self, connection_manager, sync_manager): self.connection_manager = connection_manager self.sync_manager = sync_manager def restore_defaults(self): confirmation = QMessageBox.question(None, " ", "Sure you want to restore default settings?", QMessageBox.Yes, QMessageBox.Cancel) if confirmation == QMessageBox.Cancel: return self.logger.config("Restoring default settings to config") self.config_helper.write_default_settings(True) default_data = self.config_helper.get_current_settings() self.set_settings_to_ui(default_data["download"], default_data["authentication"], default_data["automated-sync"]) self.select_config_sync_path(default_data["automated-sync"]["sync-path"]) def handle_root_folder(self, root_folder): items = [] if root_folder == None: enabled = False items.append("Connect to DropBox first") else: enabled = True items.append("None") self.populate_folder_list(items, root_folder) self.populate_sync_path_model(items) self.select_config_sync_path(self.config_helper.get_current_settings()["automated-sync"]["sync-path"]) self.ui.button_sync_now.setEnabled(enabled) self.sync_path_button.setEnabled(enabled) def populate_folder_list(self, folder_list, search_folder): for folder in search_folder.get_folders(): folder_list.append(folder.path) self.populate_folder_list(folder_list, folder) def populate_sync_path_model(self, folder_paths): self.sync_path_model.clear() for folder_path in folder_paths: item = QStandardItem(folder_path) item.setEditable(False) if folder_path == "Connect to DropBox first": item.setTextAlignment(Qt.AlignCenter) self.sync_path_model.appendRow(item) def select_config_sync_path(self, config_sync_path): found_items = self.sync_path_model.findItems(config_sync_path) if len(found_items) > 0: index = found_items[0].index().row() else: config_item = QStandardItem(config_sync_path) config_item.setEditable(False) self.sync_path_model.insertRow(1, config_item) index = 1 self.sync_path_pick_selector.setCurrentIndex(index) def check_settings(self): self.sync_path_selected(str(self.sync_path_button.valueText())) download_default_folder = self.ui.lineedit_default_download_folder.text() dir_check = QDir(download_default_folder) if not dir_check.exists(): confirmation = QMessageBox.question(None, "Default Download Folder", "The folder " + str(download_default_folder) + " does not exist anymore. Define new folder now or reset to default?", QMessageBox.Yes, QMessageBox.Reset) if confirmation == QMessageBox.Yes: self.set_default_dl_folder(False, self.datahandler.default_data_root) if confirmation == QMessageBox.Reset: self.ui.lineedit_default_download_folder.setText(self.datahandler.default_data_root) self.parse_settings_from_ui() def sync_path_selected(self, new_path): if new_path == "None": enabled = False else: enabled = True if not self.sync_path_button.isEnabled(): enabled = False self.set_sync_controls_enabled(enabled) def save_setting_clicked(self): self.store_settings = True self.hide() def reset_authentication_clicked(self): self.config_helper.datahandler.reset_auth() def set_default_dl_folder(self, magic, open_in_path = None): if open_in_path == None: open_in_path = self.ui.lineedit_default_download_folder.text() local_folder_path = QFileDialog.getExistingDirectory(None, QString("Select Default Download Folder"), QString(open_in_path), (QFileDialog.ShowDirsOnly|QFileDialog.HideNameFilterDetails|QFileDialog.ReadOnly)) if local_folder_path.isEmpty(): self.ui.lineedit_default_download_folder.setText(open_in_path) return dir_check = QDir(local_folder_path) if dir_check.exists(): self.ui.lineedit_default_download_folder.setText(local_folder_path) else: self.logger.warning("Could not validate " + str(local_folder_path) + " folder, resetting to default.") self.ui.lineedit_default_download_folder.setText(open_in_path) def set_sync_controls_enabled(self, enabled): self.ui.button_sync_now.setEnabled(enabled) self.ui.checkbox_enable_sync.setEnabled(enabled) self.ui.checkbox_only_wlan_sync.setEnabled(enabled) #self.set_sync_widgets_enabled(enabled) def set_sync_widgets_enabled(self, enabled): if not self.ui.checkbox_enable_sync.isChecked(): enabled = False self.ui.sync_frame.setEnabled(enabled) #self.ui.checkbox_only_wlan_sync.setEnabled(enabled) self.ui.label_update_every.setEnabled(enabled) self.ui.spinbox_sync_interval.setEnabled(enabled) self.ui.label_min.setEnabled(enabled) def set_wlan_sync_only_enabled(self, enabled): # NOTIFY TO SYNC MANAGER THAT USE ONLY WLAN IMMIDIATELY? # - no affected only after save pass def sync_now_clicked(self): if not self.isVisible(): sync_path = self.config_helper.get_current_settings()["automated-sync"]["sync-path"] else: sync_path = str(self.sync_path_button.valueText()) if sync_path != self.config_helper.get_current_settings()["automated-sync"]["sync-path"]: self.parse_settings_from_ui() self.sync_manager.sync_now(sync_path) def showEvent(self, show_event): self.backup_settings = self.config_helper.get_current_settings() self.handle_root_folder(self.tree_controller.root_folder) self.hide_unused() QWidget.showEvent(self, show_event) def hide_unused(self): self.ui.checkbox_enable_sync.hide() self.ui.sync_frame.hide() def hideEvent(self, hide_event): if self.store_settings: self.logger.config("Storing new settings to config") self.parse_settings_from_ui() else: if self.backup_settings != None: self.set_settings_to_ui(self.backup_settings["download"], self.backup_settings["authentication"], self.backup_settings["automated-sync"]) else: self.logger.error("Settings data from file invalid, cannot restore state.") self.store_settings = False QWidget.hideEvent(self, hide_event) def parse_settings_from_ui(self): # Download settings download_data = {} download_default_folder = self.ui.lineedit_default_download_folder.text() dir_check = QDir(download_default_folder) if dir_check.exists(): download_data["default-folder"] = str(download_default_folder) else: download_data["default-folder"] = self.config_helper.datahandler.get_data_dir_path() self.ui.lineedit_default_download_folder.setText(download_data["default-folder"]) self.main_ui_handler.show_banner("Could not validate default download folder " + str(download_default_folder) + ", reseted to default") self.logger.warning("Default download folder invalid, reseted to default") download_data["no-dialog"] = self.ui.checkbox_no_dl_dialog.isChecked() # Authentication settings authentication_data = {} authentication_data["store-auth"] = self.ui.checkbox_enable_store_auth.isChecked() # Automated sync automate_sync_data = {} automate_sync_data["enabled"] = self.ui.checkbox_enable_sync.isChecked() automate_sync_data["only-sync-on-wlan"] = self.ui.checkbox_only_wlan_sync.isChecked() automate_sync_data["update-interval"] = self.ui.spinbox_sync_interval.value() automate_sync_data["sync-path"] = str(self.sync_path_button.valueText()) self.config_helper.write_settings(download_data, authentication_data, automate_sync_data) def set_settings_to_ui(self, download_data, authentication_data, automate_sync_data): # Download settings dir_check = QDir(download_data["default-folder"]) if dir_check.exists(): self.ui.lineedit_default_download_folder.setText(download_data["default-folder"]) else: self.ui.lineedit_default_download_folder.setText(str(QDir.home().absolutePath()) + "/MyDocs/DropN900/") self.ui.checkbox_no_dl_dialog.setChecked(download_data["no-dialog"]) # Authentication settings self.ui.checkbox_enable_store_auth.setChecked(authentication_data["store-auth"]) # Automated sync self.ui.checkbox_enable_sync.setChecked(automate_sync_data["enabled"]) self.set_sync_widgets_enabled(automate_sync_data["enabled"]) self.ui.checkbox_only_wlan_sync.setChecked(automate_sync_data["only-sync-on-wlan"]) self.ui.spinbox_sync_interval.setValue(automate_sync_data["update-interval"])
class TreeView(QTreeView): def __init__(self, parent): QTreeView.__init__(self, parent) while not isinstance(parent, QDialog) and not isinstance(parent, QMainWindow): parent = parent.parent() self.setObjectName("TreeView" + str(len(parent.findChildren(TreeView)))) # self.setObjectName("TreeViewWidget") # 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 = QTreeView(self) # self.hLayout.addWidget(self) self.stdModel = QStandardItemModel() self.setModel(self.stdModel) self.hasObject = False self.treeNodeList = [] self.checkBoxList = [] self.setHeaderHidden(True) # self.stdModel.appendRow(TreeNode("P")) # rootIndex = self.rootIndex() # rootItem = self.stdModel.itemFromIndex(rootIndex) # rootItem.setText("Root") def mouseMoveEvent(self, mouseEvent): pt = mouseEvent.pos() pass def Clear(self): self.stdModel.clear() self.hasObject = False self.treeNodeList = [] def Add(self, caption): item = TreeNode(caption) if len(self.treeNodeList) > 0: item.PrevNode = self.treeNodeList[len(self.treeNodeList) - 1] item.PrevNode.NextNode = item item.Index = len(self.treeNodeList) # item.nodeIndex = len(self.treeNodeList) self.treeNodeList.append(item) self.stdModel.appendRow(item) return item def RemoveNode(self, i): self.stdModel.removeRow(i) self.treeNodeList.pop(i) for j in range(i, len(self.treeNodeList)): self.treeNodeList[j].nodeIndex -= 1 def Remove(self, item): removedIndex = self.treeNodeList.index(item) if removedIndex == 0: self.treeNodeList[1].PrevNode = None elif removedIndex == len(self.treeNodeList) - 1: self.treeNodeList[len(self.treeNodeList) - 2].NextNode = None else: self.treeNodeList[removedIndex + 1].PrevNode = self.treeNodeList[removedIndex - 1] self.treeNodeList[removedIndex - 1].NextNode = self.treeNodeList[removedIndex + 1] self.treeNodeList.pop(removedIndex) self.stdModel.removeRow(removedIndex) i = 0 for node in self.treeNodeList: node.Index = i node.LastNode = self.treeNodeList[len(self.treeNodeList) - 1] i += 1 def Insert(self, index, text): if index == 0 and len(self.treeNodeList) == 0: self.Add(text) return node = TreeNode(text) node.Parent = self self.treeNodeList.insert(index, node) i = 0 for node0 in self.treeNodeList: node0.Index = i i += 1 if index == 0: self.treeNodeList[index].PrevNode = None if len(self.treeNodeList) == 1: self.treeNodeList[index].NextNode = None self.treeNodeList[index].LastNode = self.treeNodeList[index] else: self.treeNodeList[index].NextNode = self.treeNodeList[index + 1] self.treeNodeList[index].LastNode = self.treeNodeList[len(self.treeNodeList) - 1] self.treeNodeList[index + 1].PrevNode = self.treeNodeList[index] else: self.treeNodeList[index].PrevNode = self.treeNodeList[index - 1] self.treeNodeList[index].NextNode = self.treeNodeList[index + 1] self.treeNodeList[index].LastNode = self.treeNodeList[len(self.treeNodeList) - 1] self.treeNodeList[index + 1].PrevNode = self.treeNodeList[index] self.treeNodeList[index - 1].NextNode = self.treeNodeList[index] self.stdModel.insertRow(index, node) return node def get_Items(self): return self.treeNodeList Nodes = property(get_Items, None, None, None) def Node(self, index): if not self.stdModel.rowCount() > 0: return None return self.treeNodeList[index] def getSelectedNode(self): if not self.stdModel.rowCount() > 0: return None index = self.currentIndex() return self.stdModel.itemFromIndex(index) def setSelectedNode(self, node): if not self.stdModel.rowCount() > 0: return # self.s index = self.stdModel.indexFromItem(node) self.setCurrentIndex(index) # self.treeNodeList.pop(index) # self.treeNodeList.insert(index, node) # self.stdModel.setItem(index, node) SelectedNode = property(getSelectedNode, setSelectedNode, 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 VizRank(OWWidget): name = "Rank projections (Scatter Plot)" def __init__(self, parent_widget): super().__init__() self.parent_widget = parent_widget self.want_control_area = False self.running = False self.progress = None self.k = 10 self.projectionTable = QTableView() self.mainArea.layout().addWidget(self.projectionTable) self.projectionTable.setSelectionBehavior(QTableView.SelectRows) self.projectionTable.setSelectionMode(QTableView.SingleSelection) self.projectionTable.setSortingEnabled(True) self.projectionTableModel = QStandardItemModel(self) self.projectionTable.setModel(self.projectionTableModel) self.projectionTable.selectionModel().selectionChanged.connect( self.on_selection_changed) self.button = gui.button(self.mainArea, self, "Start evaluation", callback=self.toggle, default=True) self.resize(380, 512) self._initialize() def _initialize(self): self.running = False self.projectionTableModel.clear() self.projectionTableModel.setHorizontalHeaderLabels( ["Score", "Feature 1", "Feature 2"]) self.projectionTable.setColumnWidth(0, 60) self.projectionTable.setColumnWidth(1, 120) self.projectionTable.setColumnWidth(2, 120) self.button.setText("Start evaluation") self.button.setEnabled(False) self.pause = False self.data = None self.attrs = [] self.scores = [] self.i, self.j = 0, 0 if self.progress: self.progress.finish() self.progress = None self.information(0) if self.parent_widget.data: if not self.parent_widget.data.domain.class_var: self.information( 0, "Data with a class variable is required.") return if len(self.parent_widget.data.domain.attributes) < 2: self.information( 0, 'At least 2 unique features are needed.') return self.button.setEnabled(True) def on_selection_changed(self, selected, deselected): """Called when the ranks view selection changes.""" a1 = selected.indexes()[1].data() a2 = selected.indexes()[2].data() self.parent_widget.update_attr(attributes=(a1, a2)) def toggle(self): self.running ^= 1 if self.running: self.button.setText("Pause") self.run() else: self.button.setText("Continue") self.button.setEnabled(False) def run(self): graph = self.parent_widget.graph y_full = self.parent_widget.data.Y norm = 1 / (len(y_full) * self.k) if not self.attrs: self.attrs = self.score_heuristic() if not self.progress: self.progress = gui.ProgressBar( self, len(self.attrs) * (len(self.attrs) - 1) / 2) for i in range(self.i, len(self.attrs)): ind1 = graph.attribute_name_index[self.attrs[i]] for j in range(self.j, i): if not self.running: self.i, self.j = i, j if not self.projectionTable.selectedIndexes(): self.projectionTable.selectRow(0) self.button.setEnabled(True) return ind2 = graph.attribute_name_index[self.attrs[j]] X = graph.scaled_data[[ind1, ind2], :] valid = graph.get_valid_list([ind1, ind2]) X = X[:, valid].T y = y_full[valid] knn = NearestNeighbors(n_neighbors=self.k).fit(X) ind = knn.kneighbors(return_distance=False) score = norm * np.sum(y[ind] == y.reshape(-1, 1)) pos = bisect_left(self.scores, score) self.projectionTableModel.insertRow( len(self.scores) - pos, [QStandardItem("{:.4f}".format(score)), QStandardItem(self.attrs[j]), QStandardItem(self.attrs[i])]) self.scores.insert(pos, score) self.progress.advance() self.j = 0 self.progress.finish() if not self.projectionTable.selectedIndexes(): self.projectionTable.selectRow(0) self.button.setText("Finished") self.button.setEnabled(False) def score_heuristic(self): X = self.parent_widget.graph.scaled_data.T Y = self.parent_widget.data.Y dom = Orange.data.Domain([ContinuousVariable(str(i)) for i in range(X.shape[1])], self.parent_widget.data.domain.class_vars) data = Orange.data.Table(dom, X, Y) weights = ReliefF(n_iterations=100, k_nearest=self.k)(data) attrs = sorted( zip(weights, (x.name for x in self.parent_widget.data.domain.attributes) ), reverse=True) return [a for _, a in attrs]
class VizRankDialog(QDialog, ProgressBarMixin): """ Base class for VizRank dialogs, providing a GUI with a table and a button, and the skeleton for managing the evaluation of visualizations. Derived classes need to provide generators of combinations (e.g. pairs of attribtutes) and the scoring function. The widget stores the current upon pause, and restores it upon continuation. The class provides a table and a button. A widget constructs a single instance of this dialog in its `__init__`, like (in Sieve): self.vizrank = SieveRank(self) self.vizrank_button = gui.button( box, self, "Score Combinations", callback=self.vizrank.reshow) The widget (the argument `self`) above is stored in `VizRankDialog`'s attribute `master` since derived classes will need to interact with is. When the widget receives new data, it must call the VizRankDialog's method :obj:`VizRankDialog.initialize()` to clear the GUI and reset the state. Clicking the Start button calls method `run` (and renames the button to Pause). Run sets up a progress bar by getting the number of combinations from :obj:`VizRankDialog.state_count()`. It restores the paused state (if any) and calls generator :obj:`VizRankDialog.iterate_states()`. For each generated state, it calls :obj:`VizRankDialog.score(state)`, which must return the score (lower is better) for this state. If the returned state is not `None`, the data returned by `row_for_state` is inserted at the appropriate place in the table. Args: master (Orange.widget.OWWidget): widget to which the dialog belongs Attributes: master (Orange.widget.OWWidget): widget to which the dialog belongs captionTitle (str): the caption for the dialog. This can be a class attribute. `captionTitle` is used by the `ProgressBarMixin`. """ captionTitle = "" processingStateChanged = Signal(int) progressBarValueChanged = Signal(float) def __init__(self, master): """Initialize the attributes and set up the interface""" super().__init__(windowTitle=self.captionTitle) self.master = master self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.setLayout(QVBoxLayout()) self.rank_model = QStandardItemModel(self) self.rank_table = view = QTableView( selectionBehavior=QTableView.SelectRows, selectionMode=QTableView.SingleSelection, showGrid=False) view.setItemDelegate(HorizontalGridDelegate()) view.setModel(self.rank_model) view.selectionModel().selectionChanged.connect( self.on_selection_changed) view.horizontalHeader().setStretchLastSection(True) view.horizontalHeader().hide() self.layout().addWidget(view) self.button = gui.button( self, self, "Start", callback=self.toggle, default=True) def reshow(self): """Put the widget on top of all windows """ self.show() self.raise_() self.activateWindow() def initialize(self): """ Clear and initialize the dialog. This method must be called by the widget when the data is reset, e.g. from `set_data` handler. """ self.keep_running = False self.saved_state = None self.saved_progress = 0 self.scores = [] self.rank_model.clear() self.button.setText("Start") self.button.setEnabled(self.check_preconditions()) def check_preconditions(self): """Check whether there is sufficient data for ranking.""" return True def on_selection_changed(self, selected, deselected): """ Set the new visualization in the widget when the user select a row in the table. If derived class does not reimplement this, the table gives the information but the user can't click it to select the visualization. Args: selected: the index of the selected item deselected: the index of the previously selected item """ pass def iterate_states(self, initial_state): """ Generate all possible states (e.g. attribute combinations) for the given data. The content of the generated states is specific to the visualization. This method must be defined in the derived classes. Args: initial_state: initial state; None if this is the first call """ raise NotImplementedError def state_count(self): """ Return the number of states for the progress bar. Derived classes should implement this to ensure the proper behaviour of the progress bar""" return 0 def compute_score(self, state): """ Abstract method for computing the score for the given state. Smaller scores are better. Args: state: the state, e.g. the combination of attributes as generated by :obj:`state_count`. """ raise NotImplementedError def row_for_state(self, state, score): """ Abstract method that return the items that are inserted into the table. Args: state: the state, e.g. combination of attributes score: score, computed by :obj:`compute_score` """ raise NotImplementedError def _select_first_if_none(self): if not self.rank_table.selectedIndexes(): self.rank_table.selectRow(0) def run(self): """Compute and show scores""" with self.progressBar(self.state_count()) as progress: progress.advance(self.saved_progress) for state in self.iterate_states(self.saved_state): if not self.keep_running: self.saved_state = state self.saved_progress = progress.count self._select_first_if_none() return score = self.compute_score(state) if score is not None: pos = bisect_left(self.scores, score) self.rank_model.insertRow( pos, self.row_for_state(score, state)) self.scores.insert(pos, score) progress.advance() self._select_first_if_none() self.button.setText("Finished") self.button.setEnabled(False) def toggle(self): """Start or pause the computation.""" self.keep_running = not self.keep_running if self.keep_running: self.button.setText("Pause") self.run() else: self._select_first_if_none() self.button.setText("Continue")
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 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