def _loadFile(self, filename=None): ''' Loads a SBML file. It invokes the creation of a data model and a networkx graph based on the SBML data. @param filename: Name of the SBML file @type filename: str ''' if filename is None: return self.filename = filename self.sbmlModel = SBMLMainModel(filename) self.treeModel = self.sbmlModel.MainTreeModel # self.connect(self.sbmlModel, SIGNAL("DirtyChanged(bool)"), self.on_dirtyChanged) self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged) # self.proxyModel = self.treeModel # DEBUGGING: "disabling" the proxy approach self.proxyModel = QSortFilterProxyModel() self.proxyModel.setSortRole(Qt.UserRole) try: self.proxyModel.setSourceModel(self.treeModel) except Exception, e: # try again logging.debug( "ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s" % e) self._loadFile(filename)
class OverviewDock(QDockWidget, Ui_Dock): """ Main interface with recent actions """ def __init__(self, parent=None): super(OverviewDock, self).__init__(parent) self.setupUi(self) self.tableView.setSortingEnabled(True) self._model = OverviewTableModel() self._proxy = QSortFilterProxyModel() self._proxy.setSourceModel(self._model) self.tableView.setModel(self._proxy) self.initialLoad() def initialLoad(self): self._model.modelReset.connect(self.setup_view) self.dateEdit.setDate(QtCore.QDate.currentDate()) def setup_view(self): self.tableView.setColumnHidden(self._model.ID, True) self.tableView.setColumnHidden(self._model.TYPE, True) self.tableView.setColumnHidden(self._model.ID_REF, True) self.resize_columns() #self.tableView.setFocus() self.tableView.selectRow(self._model.rowCount() - 1) def resize_columns(self): self.tableView.resizeColumnsToContents() self.tableView.horizontalHeader().setResizeMode(self._model.DESCRIPTION, QHeaderView.Stretch) @QtCore.Slot(QtCore.QDate) def on_dateEdit_dateChanged(self, date): self._model.load_date(date) @QtCore.Slot() def on_btnRefresh_clicked(self): self.refresh() def refresh(self): self._model.load_date(self.dateEdit.date()) @QtCore.Slot(QtCore.QModelIndex) def on_tableView_doubleClicked(self, index): source_index = self._proxy.mapToSource(index) record = self._model.get_record(source_index.row()) record_type = record.value(self._model.TYPE) record_id = record.value(self._model.ID) record_time = record.value(self._model.DATE).toString("dd/MMM - HH:mm") record_user = record.value(self._model.USERNAME) record_desc = record.value(self._model.DESCRIPTION) print ("%s /// %s /// %s /// %s /// %s") % (record_type, record_id, record_time, record_user, record_desc)
class UserListWidget(QListView): """ This actual widget that shows the list of users. It contains a proxy that, in turn, contains a UserListModel. """ def __init__(self, users, parent): super(UserListWidget, self).__init__(parent) self.model = UserListModel(users) self.proxy = QSortFilterProxyModel(self) self.proxy.setSourceModel(self.model) self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.setModel(self.proxy) self.clicked.connect(parent.user_selected) self.adjustSize() def setUsers(self, users): self.model.setUsers(users) def getUser(self, index): return self.model.data(index, UserListModel.UserRole) def filter(self, text): self.proxy.setFilterRegExp(text) self.proxy.filterRegExp()
class NodeTree(QTreeView): def __init__(self): super(NodeTree, self).__init__() self._model = NodeModel(self) self._proxy = QSortFilterProxyModel() self._proxy.setSortRole(Qt.UserRole) # sort order is stored in item in Qt.UserRole self._proxy.setSourceModel(self._model) self.setModel(self._proxy) self.setItemDelegate(NodeDelegate()) self.header().setResizeMode(self.header().ResizeToContents) self.header().setStretchLastSection(False) self.setSortingEnabled(True) self.sortByColumn(self.model().sourceModel().HEADER.index('Node'), Qt.AscendingOrder)
def _loadFile(self, filename=None): """ Loads a SBML file. It invokes the creation of a data model and a networkx graph based on the SBML data. @param filename: Name of the SBML file @type filename: str """ if filename is None: return self.filename = filename self.sbmlModel = SBMLMainModel(filename) self.treeModel = self.sbmlModel.MainTreeModel self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged) # self.proxyModel = self.treeModel # DEBUGGING: "disabling" the proxy approach self.proxyModel = QSortFilterProxyModel() self.proxyModel.setSortRole(Qt.UserRole) try: self.proxyModel.setSourceModel(self.treeModel) except Exception, e: # try again logging.debug("ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s" % e) self._loadFile(filename)
def __init__(self, parent=None): super(ComboBoxWithTypingSearch, self).__init__(parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self.completer = QCompleter(self) # always show all completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.completer.setPopup(self.view()) self.setCompleter(self.completer) self.lineEdit().textEdited.connect( self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.setTextIfCompleterIsClicked)
def __init__(self, parent=None): super(OverviewDock, self).__init__(parent) self.setupUi(self) self.tableView.setSortingEnabled(True) self._model = OverviewTableModel() self._proxy = QSortFilterProxyModel() self._proxy.setSourceModel(self._model) self.tableView.setModel(self._proxy) self.initialLoad()
def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi() # setup a sample model self.model = QStandardItemModel(self) self.model.setHorizontalHeaderLabels(self.COLUMNS) for row, item in enumerate(self.ITEMS): for column, cell in enumerate(item): self.model.setItem(row, column, QStandardItem(cell)) self.proxy = QSortFilterProxyModel(self) self.proxy.setSourceModel(self.model) # filter all columns (use 0, 1, etc. to only filter by a specific column) self.proxy.setFilterKeyColumn(-1) # filter text case insensitively self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.view.setModel(self.proxy) for column, _ in enumerate(self.COLUMNS): self.view.resizeColumnToContents(column) self.searchBox.textChanged.connect(self.updateFilter)
def __init__(self): QWidget.__init__(self) self.resize(640, 480) vbox = QVBoxLayout() self.setWindowTitle('TableDemo') self.setLayout(vbox) self.table = QTableView() self.table.setAlternatingRowColors(True) self.table.setSortingEnabled(True) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) cards = [Card(u'巫医', u'战吼:恢复2点生命值。', 1, 2, 1), Card(u'狼骑兵', u'冲锋', 3, 3, 1), Card(u'石牙野猪', u'冲锋', 1, 1, 1), Card(u'森金持盾卫士', u'嘲讽', 4, 3, 5), ] cardModel = CardModel(cards) sortModel = QSortFilterProxyModel() sortModel.setSourceModel(cardModel) self.table.setModel(sortModel) vbox.addWidget(self.table)
def __init__(self, users, parent): super(UserListWidget, self).__init__(parent) self.model = UserListModel(users) self.proxy = QSortFilterProxyModel(self) self.proxy.setSourceModel(self.model) self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.setModel(self.proxy) self.clicked.connect(parent.user_selected) self.adjustSize()
def __init__(self, strategy): QListView.__init__(self) self.item_strat = strategy self.itemmodel = QStandardItemModel() self.proxymodel = QSortFilterProxyModel() self.proxymodel.setSourceModel(self.itemmodel) self.proxymodel.setDynamicSortFilter(True) self.setModel(self.proxymodel) self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
def init(self, parent): super(_FilterTabularEditor, self).init(parent) self.control.text.textChanged.connect(self.on_text_change) self.control.button.clicked.connect(self.on_action) self.proxyModel = proxyModel = QSortFilterProxyModel() proxyModel.setSourceModel(self.model) self.control.setModel(proxyModel) if self.factory.multi_select: slot = self._on_rows_selection else: slot = self._on_row_selection signal = 'selectionChanged(QItemSelection,QItemSelection)' QtCore.QObject.connect(self.control.selectionModel(), QtCore.SIGNAL(signal), slot)
class MainWindow(QMainWindow): COLUMNS = ['Name', 'Comment'] ITEMS = [ ('Ford', "Don't panic"), ('Marvin', "I'm feeling so depressed") ] def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi() # setup a sample model self.model = QStandardItemModel(self) self.model.setHorizontalHeaderLabels(self.COLUMNS) for row, item in enumerate(self.ITEMS): for column, cell in enumerate(item): self.model.setItem(row, column, QStandardItem(cell)) self.proxy = QSortFilterProxyModel(self) self.proxy.setSourceModel(self.model) # filter all columns (use 0, 1, etc. to only filter by a specific column) self.proxy.setFilterKeyColumn(-1) # filter text case insensitively self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.view.setModel(self.proxy) for column, _ in enumerate(self.COLUMNS): self.view.resizeColumnToContents(column) self.searchBox.textChanged.connect(self.updateFilter) def updateFilter(self, text): self.proxy.setFilterFixedString(text) def setupUi(self): centralWidget = QWidget(self) centralWidget.setLayout(QVBoxLayout(centralWidget)) self.view = QTableView(centralWidget) self.view.setSortingEnabled(True) centralWidget.layout().addWidget(self.view) self.searchBox = QLineEdit(centralWidget) centralWidget.layout().addWidget(self.searchBox) self.setCentralWidget(centralWidget) self.searchBox.setFocus()
class LibraryListView(QListView): def __init__(self, strategy): QListView.__init__(self) self.item_strat = strategy self.itemmodel = QStandardItemModel() self.proxymodel = QSortFilterProxyModel() self.proxymodel.setSourceModel(self.itemmodel) self.proxymodel.setDynamicSortFilter(True) self.setModel(self.proxymodel) self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) def add(self, obj): item = self.item_strat.get_item(obj) self.itemmodel.appendRow(item) return item def filter(self, field, value): self.proxymodel.setFilterRole(field) self.proxymodel.setFilterFixedString(value)
def __init__(self, parent=None): """Initialize the window, setup connections, populate initial data.""" super(MainWindow, self).__init__(parent) self.setupUi(self) self.statusCombo.addItems(bug.status_values) self.severityCombo.addItems(bug.severity_values) self.statusCombo.insertSeparator(len(bug.active_status_def)) status_def = bug.active_status_def + bug.inactive_status_def tooltip = '\n'.join([': '.join(s) for s in status_def]) self.statusCombo.setToolTip(tooltip) tooltip = '\n'.join([': '.join(s) for s in bug.severity_def]) self.severityCombo.setToolTip(tooltip) self.action_New.triggered.connect(self.newProject) self.action_Open.triggered.connect(self.openProject) self.action_Close.triggered.connect(self.closeProject) self.bugFilterCombo.currentIndexChanged.connect(self.filter_bugs) self.propertyCombo.currentIndexChanged.connect(self.filter_property) self.saveBugButton.clicked.connect(self.create_bug) self.saveCommentButton.clicked.connect(self.add_comment) self.saveDetailsButton.clicked.connect(self.save_detail) self.discardDetailsButton.clicked.connect(self.display_bug) self.removeBugButton.clicked.connect(self.remove_bug) self.updateAllButton.clicked.connect(self.bulk_update) self.addFilterButton.clicked.connect(self.add_filter) self.cancelFilterButton.clicked.connect(self.clear_filter) self.filterBugsButton.clicked.connect(self.filter_bugs) self.project = None self.model = BugTableModel() self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(self.model) self.bugTable.setModel(self.proxy_model) self.bugTable.horizontalHeader().setResizeMode(1, QHeaderView.ResizeToContents) self.bugTable.horizontalHeader().setResizeMode(2, QHeaderView.ResizeToContents) self.bugTable.horizontalHeader().setResizeMode(0, QHeaderView.Stretch) self.bugTable.horizontalHeader().setMinimumSectionSize(60) self.bugTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.bugTable.selectionModel().selectionChanged.connect(self.select_bug) self.customFilterBox.setVisible(False)
class MainWindow(QMainWindow): COLUMNS = ['Name', 'Comment'] ITEMS = [('Ford', "Don't panic"), ('Marvin', "I'm feeling so depressed")] def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi() # setup a sample model self.model = QStandardItemModel(self) self.model.setHorizontalHeaderLabels(self.COLUMNS) for row, item in enumerate(self.ITEMS): for column, cell in enumerate(item): self.model.setItem(row, column, QStandardItem(cell)) self.proxy = QSortFilterProxyModel(self) self.proxy.setSourceModel(self.model) # filter all columns (use 0, 1, etc. to only filter by a specific column) self.proxy.setFilterKeyColumn(-1) # filter text case insensitively self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.view.setModel(self.proxy) for column, _ in enumerate(self.COLUMNS): self.view.resizeColumnToContents(column) self.searchBox.textChanged.connect(self.updateFilter) def updateFilter(self, text): self.proxy.setFilterFixedString(text) def setupUi(self): centralWidget = QWidget(self) centralWidget.setLayout(QVBoxLayout(centralWidget)) self.view = QTableView(centralWidget) self.view.setSortingEnabled(True) centralWidget.layout().addWidget(self.view) self.searchBox = QLineEdit(centralWidget) centralWidget.layout().addWidget(self.searchBox) self.setCentralWidget(centralWidget) self.searchBox.setFocus()
def setup_ui(self): main_layout = QHBoxLayout(self) edt = QLineEdit(self) edt.setPlaceholderText("Wildcard filter") btn = QToolButton(self) btn.clicked.connect(self.set_icon) layout = QHBoxLayout(self) layout.addWidget(edt) layout.addWidget(btn) layout2 = QVBoxLayout() layout2.addLayout(layout) model = TListModel(self) proxy = QSortFilterProxyModel(self) proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) proxy.setSourceModel(model) edt.textChanged.connect(proxy.setFilterWildcard) list = QListView() list.setModel(proxy) selection_model = list.selectionModel() selection_model.currentChanged.connect(self.currentChanged) layout2.addWidget(list) main_layout.addLayout(layout2) image = QLabel("Select icon", self) image.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) image.setMinimumWidth(256) main_layout.addWidget(image) self.btn = btn self.edt = edt self.image = image self.list = list self.proxy = proxy self.model = model self.selection_model = selection_model
class ComboBoxWithTypingSearch(QComboBox): def __init__(self, parent=None): super(ComboBoxWithTypingSearch, self).__init__(parent) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self.completer = QCompleter(self) # always show all completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.completer.setPopup(self.view()) self.setCompleter(self.completer) self.lineEdit().textEdited.connect( self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.setTextIfCompleterIsClicked) def setModel(self, model): super(ComboBoxWithTypingSearch, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) super(ComboBoxWithTypingSearch, self).setModelColumn(column) def view(self): return self.completer.popup() def index(self): return self.currentIndex() def setTextIfCompleterIsClicked(self, text): if text: index = self.findText(text) self.setCurrentIndex(index)
def setupTabs(self): """ Setup the various tabs in the AddressWidget. """ groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"] for group in groups: proxyModel = QSortFilterProxyModel(self) proxyModel.setSourceModel(self.tableModel) proxyModel.setDynamicSortFilter(True) tableView = QTableView() tableView.setModel(proxyModel) tableView.setSortingEnabled(True) tableView.setSelectionBehavior(QAbstractItemView.SelectRows) tableView.horizontalHeader().setStretchLastSection(True) tableView.verticalHeader().hide() tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) tableView.setSelectionMode(QAbstractItemView.SingleSelection) # This here be the magic: we use the group name (e.g. "ABC") to # build the regex for the QSortFilterProxyModel for the group's # tab. The regex will end up looking like "^[ABC].*", only # allowing this tab to display items where the name starts with # "A", "B", or "C". Notice that we set it to be case-insensitive. reFilter = "^[%s].*" % group proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive)) proxyModel.setFilterKeyColumn(0) # Filter on the "name" column proxyModel.sort(0, Qt.AscendingOrder) #tableView.selectionModel().selectionChanged.connect(self.selectionChanged) self.addTab(tableView, group)
class MainWindow(QMainWindow, Ui_MainWindow): """ The primary GUI class for the Tracker programme. """ def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.settings = QSettings() openRecent = self.settings.value('AppSettings/OpenRecent', '0') if int(openRecent) == int(Qt.Checked): self.filename = self.settings.value('AppSettings/LastOpenFile', None) print self.filename self.currentFilename.setText(self.filename) else: self.filename = None if self.filename == None: self.filename = self.fileBrowser() self.db = TrackerDB(self.filename) # User tab ============================================================= self.browseFiles.clicked.connect(self.fileBrowser) self.userName.editingFinished.connect(self.userNameUpdate) self.currentAge.valueChanged.connect(self.calculateBMR) self.currentHeight.valueChanged.connect(self.calculateBMR) self.currentWeight.valueChanged.connect(self.calculateBMR) self.sex.currentIndexChanged.connect(self.calculateBMR) self.activity.currentIndexChanged.connect(self.calculateMCN) self.goal.currentIndexChanged.connect(self.calculateTCN) self.dietMacro.currentIndexChanged.connect(self.calculateSplit) self.loadUserData() # Foods tab ============================================================ self.foodModel = Foodmodel(self.db, self) self.foodView.setModel(self.foodModel) self.foodView.doubleClicked.connect(self.foodViewEdit) self.addFoodButton.clicked.connect(self.editFood) self.deleteFoodButton.clicked.connect(self.foodViewDelete) # Food log tab ========================================================= self.foodProxyModel = QSortFilterProxyModel(self) self.foodProxyModel.setSourceModel(self.foodModel) self.foodProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.foodProxyModel.setDynamicSortFilter(True) self.foodLogList.setModel(self.foodProxyModel) self.filterText.textChanged.connect(self.filterFoodProxyModel) self.setFoodLogDate() self.todayButton.clicked.connect(self.setFoodLogDate) self.yesterdayButton.clicked.connect(self.setFoodLogYesterday) self.nextDayButton.clicked.connect(self.setFoodLogNextDay) self.previousDayButton.clicked.connect(self.setFoodLogPreviousDay) self.dateEdit.dateChanged.connect(self.changeDate) self.removeFoodButton.clicked.connect(self.deleteFoodLogItem) self.addFoodtoLog.clicked.connect(self.quantityEditButton) self.foodLogList.doubleClicked.connect(self.quantityEdit) self.foodLogToday.doubleClicked.connect(self.existingQuantityEdit) self.clearFilterButton.clicked.connect(self.clearFilter) # Load today's data: self.changeDate() # Weight log tab ======================================================= self.setWeightLogDate() self.todayButton_2.clicked.connect(self.setWeightLogDate) self.yesterdayButton_2.clicked.connect(self.setWeightLogYesterday) self.nextDayButton_2.clicked.connect(self.setWeightLogNextDay) self.previousDayButton_2.clicked.connect(self.setWeightLogPreviousDay) self.dateEdit_2.dateChanged.connect(self.changeWeightDate) self.weight.valueChanged.connect(self.weightChanged) self.changeWeightDate() # set to today's weight # Exercise log tab ===================================================== self.setExerciseLogDate() self.exerciseTodayButton.clicked.connect(self.setExerciseLogDate) self.exerciseYesterdayButton.clicked.connect(self.setExerciseLogYesterday) self.exerciseNextDayButton.clicked.connect(self.setExerciseLogNextDay) self.exercisePreviousDayButton.clicked.connect(self.setExerciseLogPreviousDay) self.exerciseDateEdit.dateChanged.connect(self.changeExerciseDate) self.exerciseModel = Exercisemodel(self.db, self) self.exerciseList.setModel(self.exerciseModel) self.exerciseList.doubleClicked.connect(self.logExercise) self.logExerciseButton.clicked.connect(self.logExerciseClick) #self.unlogExerciseButton.clicked.connect() self.addExercise.clicked.connect(self.createExercise) self.editExercise.clicked.connect(self.modifyExercise) self.deleteExercise.clicked.connect(self.removeExercise) self.changeExerciseDate() # Saved settings ======================================================= self.loadState() def fileBrowser(self): """ Opens a file browser dialog box, and sets the resulting values into the file name text box """ fileName = QFileDialog.getOpenFileName(self, "Open database", "~", "Database files (*.db)") if fileName[0] != '': #print fileName[0] self.currentFilename.setText(fileName[0]) return fileName[0] def foodViewEdit(self, QModelIndex): row = QModelIndex.row() data = [] for column in range(9): data.append(QModelIndex.sibling(row, column).data()) self.editFood(data[1], data[2], data[3:9], data[0], row) def foodViewDelete(self): if len(self.foodView.selectedIndexes()) != 0: QModelIndex = self.foodView.selectedIndexes()[0] #row = QModelIndex.row() self.foodModel.deleteitem(QModelIndex) def loadState(self): '''Loads saved state of the application''' # WINDOW SIZE windowSize = self.settings.value('MainWindow/Size', QSize(500, 500)) self.resize(windowSize) #FOOD: COLUMN WIDTHS foodColumnWidths = self.settings.value('Food/ColumnWidths', [0, 100, 100, 100, 100, 100, 100, 100, 100]) for i in range(9): self.foodView.setColumnWidth(i, int(foodColumnWidths[i])) self.foodView.sortByColumn(1, Qt.AscendingOrder) for i in [0]: self.foodView.hideColumn(i) #FOOD LOG: COLUMN WIDTHS foodLogFoodwidths = self.settings.value('FoodLog/ColumnWidths1', [0, 100, 100, 0, 0, 0, 0, 0, 0]) for i in range(9): self.foodLogList.setColumnWidth(i, int(foodLogFoodwidths[i])) self.foodLogList.sortByColumn(1, Qt.AscendingOrder) for i in [0, 3, 4, 5, 6, 7, 8]: self.foodLogList.hideColumn(i) foodLogFoodwidths2 = self.settings.value('FoodLog/ColumnWidths2', [0, 100, 100, 100]) for i in range(4): self.foodLogToday.setColumnWidth(i, int(foodLogFoodwidths2[i])) self.foodLogToday.sortByColumn(1, Qt.AscendingOrder) for i in [0]: self.foodLogToday.hideColumn(i) #EXERCISE exerciseListWidths = self.settings.value('Exercise/ListWidths',[0, 150, 0, 150]) for i in range(4): self.exerciseList.setColumnWidth(i, int(exerciseListWidths[i])) self.exerciseList.sortByColumn(1, Qt.AscendingOrder) for i in [0, 2]: self.exerciseList.hideColumn(i) exerciseLogWidths = self.settings.value('Exercise/LogWidths',[100, 100, 30, 30, 30]) for i in range(5): self.dailyExerciseLog.setColumnWidth(i, int(exerciseLogWidths[i])) self.dailyExerciseLog.sortByColumn(0, Qt.AscendingOrder) def closeEvent(self, event): '''Method to save state of the application''' # LAST OPEN FILE self.settings.setValue('AppSettings/LastOpenFile', self.filename) self.settings.setValue('AppSettings/OpenRecent', self.openRecent.checkState()) # WINDOW SIZE self.settings.setValue('MainWindow/Size', self.size()) #FOOD: COLUMN WIDTHS columnWidths = [] for i in range(9): columnWidths.append(self.foodView.columnWidth(i)) self.settings.setValue('Food/ColumnWidths',columnWidths) # FOOD LOG: COLUMN WIDTHS columnWidths = [] for i in range(9): columnWidths.append(self.foodLogList.columnWidth(i)) self.settings.setValue('FoodLog/ColumnWidths1',columnWidths) columnWidths = [] for i in range(4): columnWidths.append(self.foodLogToday.columnWidth(i)) self.settings.setValue('FoodLog/ColumnWidths2',columnWidths) #EXERCISE: COLUMN WIDTHS columnWidths = [] for i in range(4): columnWidths.append(self.exerciseList.columnWidth(i)) self.settings.setValue('Exercise/ListWidths',columnWidths) columnWidths = [] for i in range(5): columnWidths.append(self.dailyExerciseLog.columnWidth(i)) self.settings.setValue('Exercise/LogWidths',columnWidths) def editFood(self, name='', portion='', data=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], foodID=0, row=0): dialog = EditFood(name, portion, data, foodID) dialog.setModal(True) newData = dialog.exec_() if newData == False: # cancelled add/edit pass else: # create or edit the item if newData[0] == 0: # brand new item self.foodModel.additem(newData[1]) else: # edit existing item self.foodModel.edititem(newData[0], row, newData[1]) def currentDate(self): '''Returns a QDate object with the date/time set to now''' return QDate.currentDate() def setFoodLogDate(self): '''Sets the date on the food Log tab to the current date''' self.dateEdit.setDate(self.currentDate()) def setWeightLogDate(self): '''Sets the date on the weight log tab to the current date''' self.dateEdit_2.setDate(self.currentDate()) def setExerciseLogDate(self, date=QDate.currentDate()): '''Sets the date on the weight log tab to the current date''' self.exerciseDateEdit.setDate(date) def setFoodLogYesterday(self): '''Sets the date on the food Log tab to yesterday''' self.dateEdit.setDate(self.currentDate().addDays(-1)) def setWeightLogYesterday(self): '''Sets the date on the weight Log tab to yesterday''' self.dateEdit_2.setDate(self.currentDate().addDays(-1)) def setExerciseLogYesterday(self): '''Sets the date on the exercise Log tab to yesterday''' self.exerciseDateEdit.setDate(self.currentDate().addDays(-1)) def setFoodLogNextDay(self): '''Increments current date by 1 day''' self.dateEdit.setDate(self.dateEdit.date().addDays(1)) def setWeightLogNextDay(self): '''Increments current date by 1 day''' self.dateEdit_2.setDate(self.dateEdit_2.date().addDays(1)) def setExerciseLogNextDay(self): '''Increments current date by 1 day''' self.exerciseDateEdit.setDate(self.exerciseDateEdit.date().addDays(1)) def setFoodLogPreviousDay(self): '''Decrements current date by 1 day''' self.dateEdit.setDate(self.dateEdit.date().addDays(-1)) def setWeightLogPreviousDay(self): '''Decrements current date by 1 day''' self.dateEdit_2.setDate(self.dateEdit_2.date().addDays(-1)) def setExerciseLogPreviousDay(self): '''Decrements current date by 1 day''' self.exerciseDateEdit.setDate(self.exerciseDateEdit.date().addDays(-1)) def changeDate(self, date=QDate.currentDate()): '''Actions to conduct when date is changed, e.g. check if date exists in database, load existing food log''' self.foodLogModel = FoodLogModel(self.db, date, self) self.foodLogToday.setModel(self.foodLogModel) def changeWeightDate(self, date=QDate.currentDate()): """ Actions to conduct when the weight date is changed. """ weight = self.db.getWeight(date.toString('yyyy-MM-dd')) if weight != None: self.weight.setValue(weight['weight']) else: self.weight.setValue(0.0) def weightChanged(self): """ Actions to take when the weight value is changed """ # Check that the date exists dateString = self.dateEdit_2.date().toString('yyyy-MM-dd') weight = self.weight.value() d = self.db.getDate(dateString) if len(d) == 0: # The date does not yet exist in the database # has the value been changed to a default zero? if weight != 0: self.db.addDate(dateString) self.db.setWeight(dateString, weight) else: # The date exists in the database # change existing value self.db.setWeight(dateString, weight) def clearFilter(self): """ Clears the filter box string """ self.filterText.setText('') def filterFoodProxyModel(self): """ Applies filter from the text box """ self.foodProxyModel.setFilterFixedString(self.filterText.text()) self.foodProxyModel.setFilterKeyColumn(1) def quantityEdit(self, QModelIndex): """ Adds a food to from the food list to the daily consumption list """ row = QModelIndex.row() data = [] for column in range(9): data.append(QModelIndex.sibling(row,column).data()) dialog = SetQuantity(data[0], data[1], data[2]) dialog.setModal(True) newData = dialog.exec_() if newData == False: # User cancelled the operation pass else: # newData = [id, name, portion, quantity] self.foodLogModel.addFood(newData[0], newData[1], newData[2], newData[3]) def quantityEditButton(self): """ Adds a food to from the food list to the daily consumption list - as quantityEdit, but using the pushbutton """ if len(self.foodLogList.selectedIndexes()) != 0: QModelIndex = self.foodLogList.selectedIndexes()[0] self.quantityEdit(QModelIndex) def existingQuantityEdit(self, QModelIndex): row = QModelIndex.row() data = [] for column in range(4): data.append(QModelIndex.sibling(row,column).data()) dialog = SetQuantity(data[0], data[1], data[2], data[3]) dialog.setModal(True) newData = dialog.exec_() if newData == False: # User cancelled the operation pass else: # newData = [id, name, portion, quantity] self.foodLogModel.editFood(newData[0], newData[3], row) def deleteFoodLogItem(self): if len(self.foodLogToday.selectedIndexes()) != 0: QModelIndex = self.foodLogToday.selectedIndexes()[0] self.foodLogModel.deleteFood(QModelIndex) def userNameUpdate(self): """ Updates the user's name in the database file """ self.db.setName(self.userName.text()) def calculateBMR(self): """ Calculates Basal metabolic rate and updates the information tab http://en.wikipedia.org/wiki/Basal_animal_metabolic_rate Mifflin et al. (1990) """ if self.sex.currentIndex() == 0: # male BMR = 10.0*self.currentWeight.value() + 625*self.currentHeight.value() -5*self.currentAge.value() + 5 if self.sex.currentIndex() == 1: # female BMR = 10.0*self.currentWeight.value() + 625*self.currentHeight.value() -5*self.currentAge.value() - 161 self.currentBMR.setText(str(BMR)) self.calculateMCN() def calculateMCN(self): """ Calculates maintenance calorific needs, and updates ther information tab http://en.wikipedia.org/wiki/Harris-Benedict_equation Harris Benedict principle """ multiplier = [1.2, 1.375, 1.55, 1.725, 1.9] MCN = float(self.currentBMR.text())*multiplier[self.activity.currentIndex()] self.currentMCN.setText(str(MCN)) self.calculateTCN() def calculateTCN(self): """ Calculates total calorific need based on desired weight change goal """ calorieIncrease = [1000, 500, 0, +500, +1000] TCN = float(self.currentMCN.text()) + calorieIncrease[self.goal.currentIndex()] self.currentTCN.setText(str(TCN)) self.calculateSplit() def calculateSplit(self): """ Determines the macronutrient split (by mass) and displays it in the UI This function should always be triggered if any of the upstream data changes (i.e. sex, age, weight, height, activity and goal) so this function also updates the database with latest values of those """ if self.dietMacro.currentIndex() == 0: c, p, f = 40.0, 40.0, 20.0 # carb, protein, fat if self.dietMacro.currentIndex() == 1: c, p, f = 40.0, 30.0, 30.0 # carb, protein, fat if self.dietMacro.currentIndex() == 2: c, p, f = 50.0, 25.0, 25.0 # carb, protein, fat if self.dietMacro.currentIndex() == 3: c, p, f = 50.0, 30.0, 20.0 # carb, protein, fat cg, pg, fg = self.db.macroSplit(c, p, f, float(self.currentTCN.text())) # set the values in the GUI self.targetCarbg.setText('%3i g/ day' % cg) self.targetProteing.setText('%3i g/ day' % pg) self.targetFatg.setText('%3i g/ day' % fg) # save values to DB self.db.updateUserData(self.userName.text(), self.sex.currentIndex(), self.currentAge.value(), self.currentHeight.value(), self.currentWeight.value(), self.activity.currentIndex(), self.goal.currentIndex(), self.dietMacro.currentIndex()) def loadUserData(self): """ Loads the user data from the SQL file into the GUI """ userdata = self.db.getUserData() self.userName.setText(userdata['name']) self.sex.setCurrentIndex(userdata['sex']) self.currentAge.setValue(userdata['age']) self.currentHeight.setValue(userdata['height']) self.currentWeight.setValue(userdata['weight']) self.activity.setCurrentIndex(userdata['activity']) self.goal.setCurrentIndex(userdata['goal']) self.dietMacro.setCurrentIndex(userdata['macrosplit']) def createExercise(self, name='', typeID=1, row=False, existingID=-1): """ Brings up the 'create exercise' dialog """ dialog = CreateExercise(self.db, name, typeID) dialog.setModal(True) exData = dialog.exec_() # [description, typeID] if exData != False: if row == False: # Add a new item self.exerciseModel.addItem(exData[0], exData[1]) else: # edit existing item in row row self.exerciseModel.editItem(exData[0], exData[1], row, existingID) def modifyExercise(self): if len(self.exerciseList.selectedIndexes()) != 0: QModelIndex = self.exerciseList.selectedIndexes()[0] row = QModelIndex.row() data = [] for column in range(4): data.append(QModelIndex.sibling(row, column).data()) self.createExercise(data[1], data[2], row, data[0]) def removeExercise(self): """ Deletes exercise from the exercises list (not the log) """ if len(self.exerciseList.selectedIndexes()) != 0: QModelIndex = self.exerciseList.selectedIndexes()[0] row = QModelIndex.row() exID = QModelIndex.sibling(row, 0).data() self.exerciseModel.deleteItem(exID, row) def logExercise(self, QModelIndex): """ Logs the exercise to the currently selected day """ row = QModelIndex.row() exID = QModelIndex.sibling(row, 0).data() dialog = LogExercise(self.db, exID) dialog.setModal(True) exData = dialog.exec_() dateString = self.exerciseDateEdit.date().toString('yyyy-MM-dd') self.db.logExercise(dateString, exData[0], exData[1], exData[2], exData[3], exData[4]) # reload model self.changeExerciseDate(self.exerciseDateEdit.date()) def logExerciseClick(self): """ Use the button to log the currently selected exercise to the currently selected day """ if len(self.exerciseList.selectedIndexes()) != 0: QModelIndex = self.exerciseList.selectedIndexes()[0] self.logExercise(QModelIndex) def changeExerciseDate(self, date=QDate.currentDate()): """ Actions to conduct when date is changed, e.g. check if date exists in database, load existing exercise log """ self.exerciseLogModel = ExerciseLogModel(self.db, date, self) self.dailyExerciseLog.setModel(self.exerciseLogModel)
class ModelController(QObject): """ The network controller which basically manages all aspects revolving around a single SBML model (i.e. SBML file). It has references to outside Views (e.g. TreeView). Internally, it has a reference to the custom NetworkView. A Dirty state is used to handle the need for saving/rejecting changes, etc. It inherits from QObject for the use of Signals/Slots. @param filename: Filename of the SBML model that should be opened. If None, an empty model is created. @type filename: str @param views: The views of the main window that are to be associated with the model. @type views: L{QAbstractItemView} @since: 2010-04-12 """ __author__ = "Moritz Wade" __contact__ = "*****@*****.**" __copyright__ = "Zuse Institute Berlin 2010" dirtyChanged = Signal(bool) def GetDirty(self): return self.__Dirty def SetDirty(self, value): self.__Dirty = value # self.emit(SIGNAL("DirtyChanged(bool)"), value) self.dirtyChanged.emit(value) def DelDirty(self): del self.__Dirty Dirty = property( GetDirty, SetDirty, DelDirty, "Defines whether this model has any unsaved changes. This is passed through to SbmlMainModel's Dirty." ) def __init__(self, filename=None, views=[], networkViewController=None): """ Sets up some instance variables. Most importantly, it executes the loading of a SBML file, if a filename is given. """ super(ModelController, self).__init__() self.filename = None # will be set by self._loadFile self.sbmlModel = None self.treeModel = None self.selectionModel = None self.proxyModel = None # we have the proxy model here, so that all Views can use it and the same SelectionModel still works (!) self.views = views self.networkViewController = networkViewController # a special place for the NetworkViewController # self.connect(self, SIGNAL("DirtyChanged(bool)"), self.updateUI) # self.dirtyChanged.connect(self.updateUI) if filename is not None: self._loadFile(filename) def setViews(self, views=None, networkViewController=None): """ Can be used to re-reference the ModelController with Views (either if they haven't been given to the Constructor or if they have changed somehow). This internally calls self._connectViews to set the correct models and a single QSelectionModel on the views. """ if views: self.views = views if networkViewController: self.networkViewController = networkViewController self._connectViews() if self.networkViewController: self.networkViewController._createGraph() def _loadFile(self, filename=None): ''' Loads a SBML file. It invokes the creation of a data model and a networkx graph based on the SBML data. @param filename: Name of the SBML file @type filename: str ''' if filename is None: return self.filename = filename self.sbmlModel = SBMLMainModel(filename) self.treeModel = self.sbmlModel.MainTreeModel # self.connect(self.sbmlModel, SIGNAL("DirtyChanged(bool)"), self.on_dirtyChanged) self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged) # self.proxyModel = self.treeModel # DEBUGGING: "disabling" the proxy approach self.proxyModel = QSortFilterProxyModel() self.proxyModel.setSortRole(Qt.UserRole) try: self.proxyModel.setSourceModel(self.treeModel) except Exception, e: # try again logging.debug( "ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s" % e) self._loadFile(filename) self.selectionModel = QItemSelectionModel(self.proxyModel) # self.selectionModel = self.proxyModel.selectionModel() self._connectViews( ) # probably not needed here, there is no View after __init__ if self.networkViewController: self.networkViewController._createGraph() self.Dirty = False
def setupTabs(self): """ Setup the various tabs in the AddressWidget. """ groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"] for group in groups: proxyModel = QSortFilterProxyModel(self) proxyModel.setSourceModel(self.tableModel) proxyModel.setDynamicSortFilter(True) tableView = QTableView() tableView.setModel(proxyModel) tableView.setSortingEnabled(True) tableView.setSelectionBehavior(QAbstractItemView.SelectRows) tableView.horizontalHeader().setStretchLastSection(True) tableView.verticalHeader().hide() tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) tableView.setSelectionMode(QAbstractItemView.SingleSelection) # This here be the magic: we use the group name (e.g. "ABC") to # build the regex for the QSortFilterProxyModel for the group's # tab. The regex will end up looking like "^[ABC].*", only # allowing this tab to display items where the name starts with # "A", "B", or "C". Notice that we set it to be case-insensitive. reFilter = "^[%s].*" % group proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive)) proxyModel.setFilterKeyColumn(0) # Filter on the "name" column proxyModel.sort(0, Qt.AscendingOrder) tableView.selectionModel().selectionChanged.connect(self.selectionChanged) self.addTab(tableView, group)
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.settings = QSettings() openRecent = self.settings.value('AppSettings/OpenRecent', '0') if int(openRecent) == int(Qt.Checked): self.filename = self.settings.value('AppSettings/LastOpenFile', None) print self.filename self.currentFilename.setText(self.filename) else: self.filename = None if self.filename == None: self.filename = self.fileBrowser() self.db = TrackerDB(self.filename) # User tab ============================================================= self.browseFiles.clicked.connect(self.fileBrowser) self.userName.editingFinished.connect(self.userNameUpdate) self.currentAge.valueChanged.connect(self.calculateBMR) self.currentHeight.valueChanged.connect(self.calculateBMR) self.currentWeight.valueChanged.connect(self.calculateBMR) self.sex.currentIndexChanged.connect(self.calculateBMR) self.activity.currentIndexChanged.connect(self.calculateMCN) self.goal.currentIndexChanged.connect(self.calculateTCN) self.dietMacro.currentIndexChanged.connect(self.calculateSplit) self.loadUserData() # Foods tab ============================================================ self.foodModel = Foodmodel(self.db, self) self.foodView.setModel(self.foodModel) self.foodView.doubleClicked.connect(self.foodViewEdit) self.addFoodButton.clicked.connect(self.editFood) self.deleteFoodButton.clicked.connect(self.foodViewDelete) # Food log tab ========================================================= self.foodProxyModel = QSortFilterProxyModel(self) self.foodProxyModel.setSourceModel(self.foodModel) self.foodProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.foodProxyModel.setDynamicSortFilter(True) self.foodLogList.setModel(self.foodProxyModel) self.filterText.textChanged.connect(self.filterFoodProxyModel) self.setFoodLogDate() self.todayButton.clicked.connect(self.setFoodLogDate) self.yesterdayButton.clicked.connect(self.setFoodLogYesterday) self.nextDayButton.clicked.connect(self.setFoodLogNextDay) self.previousDayButton.clicked.connect(self.setFoodLogPreviousDay) self.dateEdit.dateChanged.connect(self.changeDate) self.removeFoodButton.clicked.connect(self.deleteFoodLogItem) self.addFoodtoLog.clicked.connect(self.quantityEditButton) self.foodLogList.doubleClicked.connect(self.quantityEdit) self.foodLogToday.doubleClicked.connect(self.existingQuantityEdit) self.clearFilterButton.clicked.connect(self.clearFilter) # Load today's data: self.changeDate() # Weight log tab ======================================================= self.setWeightLogDate() self.todayButton_2.clicked.connect(self.setWeightLogDate) self.yesterdayButton_2.clicked.connect(self.setWeightLogYesterday) self.nextDayButton_2.clicked.connect(self.setWeightLogNextDay) self.previousDayButton_2.clicked.connect(self.setWeightLogPreviousDay) self.dateEdit_2.dateChanged.connect(self.changeWeightDate) self.weight.valueChanged.connect(self.weightChanged) self.changeWeightDate() # set to today's weight # Exercise log tab ===================================================== self.setExerciseLogDate() self.exerciseTodayButton.clicked.connect(self.setExerciseLogDate) self.exerciseYesterdayButton.clicked.connect(self.setExerciseLogYesterday) self.exerciseNextDayButton.clicked.connect(self.setExerciseLogNextDay) self.exercisePreviousDayButton.clicked.connect(self.setExerciseLogPreviousDay) self.exerciseDateEdit.dateChanged.connect(self.changeExerciseDate) self.exerciseModel = Exercisemodel(self.db, self) self.exerciseList.setModel(self.exerciseModel) self.exerciseList.doubleClicked.connect(self.logExercise) self.logExerciseButton.clicked.connect(self.logExerciseClick) #self.unlogExerciseButton.clicked.connect() self.addExercise.clicked.connect(self.createExercise) self.editExercise.clicked.connect(self.modifyExercise) self.deleteExercise.clicked.connect(self.removeExercise) self.changeExerciseDate() # Saved settings ======================================================= self.loadState()
class MainWindow(QMainWindow, Ui_MainWindow): """Main window of the app.""" def __init__(self, parent=None): """Initialize the window, setup connections, populate initial data.""" super(MainWindow, self).__init__(parent) self.setupUi(self) self.statusCombo.addItems(bug.status_values) self.severityCombo.addItems(bug.severity_values) self.statusCombo.insertSeparator(len(bug.active_status_def)) status_def = bug.active_status_def + bug.inactive_status_def tooltip = '\n'.join([': '.join(s) for s in status_def]) self.statusCombo.setToolTip(tooltip) tooltip = '\n'.join([': '.join(s) for s in bug.severity_def]) self.severityCombo.setToolTip(tooltip) self.action_New.triggered.connect(self.newProject) self.action_Open.triggered.connect(self.openProject) self.action_Close.triggered.connect(self.closeProject) self.bugFilterCombo.currentIndexChanged.connect(self.filter_bugs) self.propertyCombo.currentIndexChanged.connect(self.filter_property) self.saveBugButton.clicked.connect(self.create_bug) self.saveCommentButton.clicked.connect(self.add_comment) self.saveDetailsButton.clicked.connect(self.save_detail) self.discardDetailsButton.clicked.connect(self.display_bug) self.removeBugButton.clicked.connect(self.remove_bug) self.updateAllButton.clicked.connect(self.bulk_update) self.addFilterButton.clicked.connect(self.add_filter) self.cancelFilterButton.clicked.connect(self.clear_filter) self.filterBugsButton.clicked.connect(self.filter_bugs) self.project = None self.model = BugTableModel() self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(self.model) self.bugTable.setModel(self.proxy_model) self.bugTable.horizontalHeader().setResizeMode(1, QHeaderView.ResizeToContents) self.bugTable.horizontalHeader().setResizeMode(2, QHeaderView.ResizeToContents) self.bugTable.horizontalHeader().setResizeMode(0, QHeaderView.Stretch) self.bugTable.horizontalHeader().setMinimumSectionSize(60) self.bugTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.bugTable.selectionModel().selectionChanged.connect(self.select_bug) self.customFilterBox.setVisible(False) def _get_project(self): """Getter for project property""" return self._project def _set_project(self, path): """Setter for project property""" self._project = path if not path: self.projectTitle.setText('') self.newCommentBox.setVisible(False) self.newBugBox.setVisible(False) self._enable_controls(False) else: self.projectTitle.setText(path.split(os.path.sep)[-1]) self._enable_controls() self.enable_bug_view(False) self.clear_filter() project = property(_get_project, _set_project, doc="the absolute path of the project") def _enable_controls(self, enable=True): """Enable/disable UI for opened/closed project""" self.mainBox.setEnabled(enable) self.label.setVisible(not enable) def newProject(self): """Open a new project""" self.openProject(is_new=True) def openProject(self, is_new=False): """Open an existing project""" title = is_new and 'Create new project' or 'Open project' path = QFileDialog.getExistingDirectory(self, title) if path and self.project != path: self._open_store(path, is_new) def closeProject(self): """Close a project""" self.project = None self.model.bugs = [] self.enable_bug_view(False) self.newBugButton.setChecked(False) self.assignedCombo.clear() self.targetCombo.clear() self.bugFilterCombo.setCurrentIndex(0) def _open_store(self, path, is_new=False): """Open the store of the project, initialize the bugdir and load bugs""" store = storage.get_storage(path) try: if is_new: store.init() else: store.connect() if self.project: self.closeProject() self.user = get_user_id(store) version = store.version() self.vcsLabel.setText('None' if version == '0' else version) try: self.bd = bugdir.BugDir(store, from_storage=True) except: self.bd = bugdir.BugDir(store, from_storage=False) self.project = path self.reload_bugs() self.load_assignees() self.load_targets() except storage.ConnectionError as e: print e message = 'No project found. Would you like to initialize a new project?' except OSError as e: print e message = 'Project already exists. Would you like to open instead?' else: message = None if message: if self.confirm_action(message): self._open_store(path, not is_new) def reload_bugs(self, active=True): """Load all the bugs filtering on active status""" # FIXME: lazy loading of bugs should be considered self.bd.load_all_bugs() if active: filter_list = bug.status_values[:len(bug.active_status_def)] else: filter_list = bug.status_values[len(bug.active_status_def):] bugs = [b for b in self.bd if b.status in filter_list] self.model.bugs = bugs self.current_bug = None self.bugsLabel.setText(str(len(bugs))) def load_assignees(self): """Find and save all assignees for this project including the current user""" self.assignees = list(set([unicode(bug.assigned) for bug in self.bd if bug.assigned and bug.assigned != EMPTY])) if len(self.assignees) > 0: if self.user not in self.assignees: self.assignees.append(self.user) self.assignees.sort(key=unicode.lower) else: self.assignees = [self.user] self.assignedCombo.clear() self.assignedCombo.addItems([''] + self.assignees) def load_targets(self): """Load targets""" self.targets = [b for b in self.bd if b.severity == "target"] targets = [unicode(b.summary) for b in self.targets] targets.sort(key=unicode.lower) self.targetCombo.clear() self.targetCombo.addItems([''] + targets) def select_bug(self, new, old): """Slot for the bugTable selection changes. ``old`` is unused for now but required by Qt4 slot signature requirement. """ n_select = len(self.bugTable.selectedIndexes()) n_column = len(self.model.header) try: index = self.proxy_model.mapToSource(new.indexes()[0]) bug = self.model.bugs[index.row()] if n_select > n_column: self.enable_bug_view(False) self.current_bug = None self.updateAllButton.setEnabled(True) else: self.display_bug(bug) self.updateAllButton.setEnabled(False) self.removeBugButton.setEnabled(True) except IndexError: self.enable_bug_view(False) self.removeBugButton.setEnabled(False) def select_current_bug(self, bug=None): """A convenience method to select a bug in the table""" if bug: self.current_bug = bug row = self.model.bugs.index(self.current_bug) index = self.model.index(row, 0) index = self.proxy_model.mapFromSource(index) self.bugTable.selectRow(index.row()) def enable_bug_view(self, enable=True): """Enable/disable bug view""" self.addCommentButton.setEnabled(enable) self.saveDetailsButton.setEnabled(enable) self.discardDetailsButton.setEnabled(enable) self.bugTitle.setText('') self.shortLabel.setText('') self.idLabel.setText('') self.creatorLabel.setText('') self.createdLabel.setText('') self.reporterLabel.setText('') self.bugCommentBrowser.setHtml('') self.assignedCombo.setCurrentIndex(0) self.targetCombo.setCurrentIndex(0) self.addCommentButton.setChecked(False) self.updateAllButton.setEnabled(False) if not enable: self.current_bug = None def display_bug(self, bug=None): """Display currently selected bug or the bug passed via argument""" if bug: self.current_bug = bug else: bug = self.current_bug self.enable_bug_view() self.bugTitle.setText(bug.summary) self.shortLabel.setText(bug.id.user()) self.idLabel.setText(bug.uuid) self.creatorLabel.setText(bug.creator) self.createdLabel.setText(handy_time(bug.time)) self.reporterLabel.setText(bug.reporter) self.load_combos() self.load_comments() def load_comments(self): """Load all the comments for current bug""" comments = '<hr />'.join([comment_html(c) for c in self.current_bug.comments()]) if not comments: comments = '<i>No comment yet!</i>' self.bugCommentBrowser.setHtml(comments) def load_combos(self): """Update the combo boxes for bug properties""" if not self.current_bug: return target = '' bug = self.current_bug blocks = get_blocks(self.bd, bug) for b in blocks: blocker = self.bd.bug_from_uuid(b.uuid) if blocker.severity == 'target': target = blocker.summary combos = [ (self.statusCombo, bug.status), (self.severityCombo, bug.severity), (self.assignedCombo, bug.assigned), (self.targetCombo, target), ] self.assignedCombo.setCurrentIndex(0) self.targetCombo.setCurrentIndex(0) for combo, field in combos: for i in range(combo.count()): if combo.itemText(i) == field: combo.setCurrentIndex(i) def create_bug(self): """Create a new bug""" summary = self.newBugEdit.text().strip() if summary: bug = self.bd.new_bug(summary=summary) bug.creator = self.user bug.reporter = self.user bug.save() self.reload_bugs() self.select_current_bug(bug) self.newBugEdit.setText('') self.statusbar.showMessage('A new bug {0} has been ' 'added'.format(self.current_bug.id.user())) def add_comment(self): """Add a comment to the current bug. Comments are now flat, not threaded.""" body = self.newCommentEdit.toPlainText().strip() if body: comment = self.current_bug.comment_root.new_reply(body=body) comment.author = self.user self.current_bug.save() self.display_bug() self.newCommentEdit.setPlainText('') self.statusbar.showMessage('New comment added to ' '{0}'.format(self.current_bug.id.user())) def save_detail(self): """Save updated properties to the current bug""" status = self.statusCombo.currentText() severity = self.severityCombo.currentText() assigned = self.assignedCombo.currentText() target = self.targetCombo.currentText() is_changed = self.current_bug.status != status or \ self.current_bug.severity != severity or \ self.current_bug.assigned != assigned if is_changed: self.current_bug.severity = severity self.current_bug.status = status self.current_bug.assigned = assigned self.current_bug.save() self.model.reset() self.load_targets() def remove_all_targets(): """remove all targets for a bug, b""" for b in blocks: if b.severity == 'target': remove_block(b, self.current_bug) blocks = get_blocks(self.bd, self.current_bug) if not target: is_changed = True remove_all_targets() else: for t in self.targets: if t.summary == target: if t not in blocks: is_changed = True remove_all_targets() add_block(t, self.current_bug) break if is_changed: self.load_combos() self.select_current_bug() self.statusbar.showMessage('Changes to details for the bug {0} ' 'has been saved'.format(self.current_bug.id.user())) def bulk_update(self): """Bulk update properties of selected bugs""" if not self.confirm_action('Are you sure to update all selected bugs?'): return indexes = set([self.proxy_model.mapToSource(index).row() for index in self.bugTable.selectedIndexes()]) bugs = [self.model.bugs[index] for index in indexes] status = self.statusCombo.currentText() severity = self.severityCombo.currentText() assigned = self.assignedCombo.currentText() target = self.targetCombo.currentText() def remove_all_targets(): for b in blocks: if b.severity == 'target': remove_block(b, bug) for bug in bugs: bug.severity = severity bug.status = status bug.assigned = assigned bug.save() blocks = get_blocks(self.bd, bug) if not target: remove_all_targets() else: for t in self.targets: if t.summary == target: if t not in blocks: remove_all_targets() add_block(t, bug) break self.model.reset() self.load_targets() self.load_combos() self.statusbar.showMessage('Updated all selected bugs') def remove_bug(self): """Remove selected bugs from the project""" indexes = set([self.proxy_model.mapToSource(index).row() for index in self.bugTable.selectedIndexes()]) bugs = [self.model.bugs[index] for index in indexes] if len(bugs) > 0 and not self.confirm_action('Are you sure to remove selected bugs?'): return ids = [] for bug in bugs: ids.append(bug.id.user()) self.bd.remove_bug(bug) self.reload_bugs() self.enable_bug_view(False) self.removeBugButton.setEnabled(False) self.statusbar.showMessage('Removed %s bug(s)' % ', '.join(ids)) def filter_bugs(self, value=None): """Filter bugs on active status""" if not value: bugs = self.bd if self.filter_set: status = self.filter_set.get('status') severity = self.filter_set.get('severity') target = self.filter_set.get('target') assigned = self.filter_set.get('assigned') if target: for t in self.targets: if t.summary == target: target = t break bugs = get_blocked_by(self.bd, target) if assigned: bugs = [b for b in bugs if b.assigned == assigned] if severity: bugs = [b for b in bugs if b.severity == severity] if status: bugs = [b for b in bugs if b.status == status] self.model.bugs = bugs self.current_bug = None self.bugsLabel.setText(str(len(bugs))) self.enable_bug_view(False) elif value == 'custom': self.customFilterBox.setVisible(True) self.propertyCombo.setCurrentIndex(0) self.valueCombo.clear() self.valueCombo.addItems(bug.status_values) else: self.clear_filter() self.customFilterBox.setVisible(False) self.reload_bugs(value == 'active') self.enable_bug_view(False) def filter_property(self, value): items = { 'status': bug.status_values, 'severity': bug.severity_values, 'target': [t.summary for t in self.targets], 'assigned': self.assignees, }[value] self.valueCombo.clear() self.valueCombo.addItems(items) def add_filter(self): try: key, value = self.propertyCombo.currentText(), self.valueCombo.currentText() self.filter_set[key] = value except: self.filter_set = {key: value} text = '' for key in self.filter_set: text += '<b>{0}</b>: {1}<br/>'.format(key, self.filter_set[key]) self.customFilterLabel.setText(text) def clear_filter(self): self.customFilterLabel.setText('Select filters') self.filter_set = None def confirm_action(self, message): """Convenient method for user confirmation on action""" result = QMessageBox.warning(self, self.windowTitle(), message, QMessageBox.Ok | QMessageBox.Cancel) return result == QMessageBox.Ok
def __init__(self, parent=None): QSortFilterProxyModel.__init__(self, parent)
def __init__(self): QSortFilterProxyModel.__init__(self) self.library_sort = LibrarySort()
def __init__(self, mw, parent=None): """ Default class constructor. :param `mw`: The application's MainWindow instance. :type `mw`: `QMainWindow`_ :param `parent`: Pointer to a parent widget instance. :type `parent`: `QWidget`_ """ super(LayerManager, self).__init__(parent) tr = self.tr self.layerModel = layerModel = QStandardItemModel(0, 8, self) self.layerModelSorted = layerModelSorted = QSortFilterProxyModel() layerModelSorted.setDynamicSortFilter(True) layerModelSorted.setSourceModel(layerModel) self.treeView = treeView = QTreeView() treeView.setRootIsDecorated(False) treeView.setAlternatingRowColors(True) treeView.setModel(layerModelSorted) treeView.setSortingEnabled(True) treeView.sortByColumn(0, Qt.AscendingOrder) mainLayout = QVBoxLayout() mainLayout.addWidget(treeView) self.setLayout(mainLayout) self.setWindowTitle(tr("Layer Manager")) self.setMinimumSize(750, 550) ## layerModel.setHeaderData(0, Qt.Horizontal, self.tr("Name")) ## layerModel.setHeaderData(1, Qt.Horizontal, self.tr("Visible")) ## layerModel.setHeaderData(2, Qt.Horizontal, self.tr("Frozen")) ## layerModel.setHeaderData(3, Qt.Horizontal, self.tr("Z Value")) ## layerModel.setHeaderData(4, Qt.Horizontal, self.tr("Color")) ## layerModel.setHeaderData(5, Qt.Horizontal, self.tr("Linetype")) ## layerModel.setHeaderData(6, Qt.Horizontal, self.tr("Lineweight")) ## layerModel.setHeaderData(7, Qt.Horizontal, self.tr("Print")) localMeth = layerModel.setHeaderData localQtHorizontal = Qt.Horizontal [ localMeth(i, localQtHorizontal, tr(strng)) for i, strng in ((0, "Name"), (1, "Visible"), (2, "Frozen"), (3, "Z Value"), (4, "Color"), (5, "Linetype"), (6, "Lineweight"), (7, "Print")) ] ## addLayer = self.addLayer # local optimization ## addLayer("0", True, False, 0.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("1", True, False, 1.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("2", True, False, 2.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("3", True, False, 3.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("4", True, False, 4.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("5", True, False, 5.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("6", True, False, 6.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("7", True, False, 7.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("8", True, False, 8.0, qRgb(0, 0, 0), "Continuous", "Default", True) ## addLayer("9", True, False, 9.0, qRgb(0, 0, 0), "Continuous", "Default", True) addLayer = self.addLayer [ addLayer("%s" % i, True, False, float(i), qRgb(0, 0, 0), "Continuous", "Default", True) for i in range(0, 10) ] ## for i in range(0, layerModel.columnCount()): ## treeView.resizeColumnToContents(i) localtreeViewMeth = treeView.resizeColumnToContents [localtreeViewMeth(i) for i in range(0, layerModel.columnCount())] QApplication.setOverrideCursor(Qt.ArrowCursor)
class ModelController(QObject): """ The network controller which basically manages all aspects revolving around a single SBML model (i.e. SBML file). It has references to outside Views (e.g. TreeView). Internally, it has a reference to the custom NetworkView. A Dirty state is used to handle the need for saving/rejecting changes, etc. It inherits from QObject for the use of Signals/Slots. @param filename: Filename of the SBML model that should be opened. If None, an empty model is created. @type filename: str @param views: The views of the main window that are to be associated with the model. @type views: L{QAbstractItemView} @since: 2010-04-12 """ __author__ = "Moritz Wade" __contact__ = "*****@*****.**" __copyright__ = "Zuse Institute Berlin 2010" dirtyChanged = Signal(bool) def GetDirty(self): return self.__Dirty def SetDirty(self, value): self.__Dirty = value self.dirtyChanged.emit(value) def DelDirty(self): del self.__Dirty Dirty = property(GetDirty, SetDirty, DelDirty, "Defines whether this model has any unsaved changes. This is passed through to SbmlMainModel's Dirty.") def __init__(self, filename=None, views=[], networkViewController=None): """ Sets up some instance variables. Most importantly, it executes the loading of a SBML file, if a filename is given. """ super(ModelController, self).__init__() self.filename = None # will be set by self._loadFile self.sbmlModel = None self.treeModel = None self.selectionModel = None self.proxyModel = None # we have the proxy model here, so that all Views can use it and the same SelectionModel still works (!) self.views = views self.networkViewController = networkViewController # a special place for the NetworkViewController if filename is not None: self._loadFile(filename) def setViews(self, views=None, networkViewController=None): """ Can be used to re-reference the ModelController with Views (either if they haven't been given to the Constructor or if they have changed somehow). This internally calls self._connectViews to set the correct models and a single QSelectionModel on the views. """ if views: self.views = views if networkViewController: self.networkViewController = networkViewController self._connectViews() if self.networkViewController: self.networkViewController._createGraph() def _loadFile(self, filename=None): """ Loads a SBML file. It invokes the creation of a data model and a networkx graph based on the SBML data. @param filename: Name of the SBML file @type filename: str """ if filename is None: return self.filename = filename self.sbmlModel = SBMLMainModel(filename) self.treeModel = self.sbmlModel.MainTreeModel self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged) # self.proxyModel = self.treeModel # DEBUGGING: "disabling" the proxy approach self.proxyModel = QSortFilterProxyModel() self.proxyModel.setSortRole(Qt.UserRole) try: self.proxyModel.setSourceModel(self.treeModel) except Exception, e: # try again logging.debug("ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s" % e) self._loadFile(filename) self.selectionModel = QItemSelectionModel(self.proxyModel) self._connectViews() # probably not needed here, there is no View after __init__ if self.networkViewController: self.networkViewController._createGraph() self.Dirty = False