def setupUi(self): self.__dataMapper = QDataWidgetMapper(self) self.__dataMapper.setModel(self.__titleModel) propertyText = QByteArray(b'text') self.__dataMapper.addMapping(self.ui.tituloLineEdit, 0, propertyText) self.__dataMapper.addMapping(self.ui.grupoLineEdit, 1, propertyText) self.__dataMapper.addMapping(self.ui.yearLineEdit, 2, propertyText) QObject.connect(self.ui.titlesListView.selectionModel(), SIGNAL('currentRowChanged(QModelIndex,QModelIndex)'), self, SLOT('changeSelectedTitle(QModelIndex,QModelIndex)')) #Dialogo de configuracion self.dialogoConfiguracion = ConfigDialog(self) self.ui.actionConfiguracion.triggered.connect( self.dialogoConfiguracion.open) self.dialogoConfiguracion.finished.connect(self.reloadModelos) self.ui.playButton.clicked.connect(self.launchCurrentVideo) self.ui.stopButton.clicked.connect(self.__ytPlayer.stopVideo) self.ui.pauseButton.clicked.connect(self.__ytPlayer.pauseVideo)
def __init__(self): super().__init__() form = QFormLayout() self.track_id = QSpinBox() self.track_id.setRange(0, 2147483647) self.track_id.setDisabled(True) self.name = QLineEdit() self.album = QComboBox() self.media_type = QComboBox() self.genre = QComboBox() self.composer = QLineEdit() self.milliseconds = QSpinBox() self.milliseconds.setRange(0, 2147483647) # <1> self.milliseconds.setSingleStep(1) self.bytes = QSpinBox() self.bytes.setRange(0, 2147483647) self.bytes.setSingleStep(1) self.unit_price = QDoubleSpinBox() self.unit_price.setRange(0, 999) self.unit_price.setSingleStep(0.01) self.unit_price.setPrefix("$") form.addRow(QLabel("Track ID"), self.track_id) form.addRow(QLabel("Track name"), self.name) form.addRow(QLabel("Composer"), self.composer) form.addRow(QLabel("Milliseconds"), self.milliseconds) form.addRow(QLabel("Bytes"), self.bytes) form.addRow(QLabel("Unit Price"), self.unit_price) self.model = QSqlTableModel(db=db) self.mapper = QDataWidgetMapper() # <2> self.mapper.setModel(self.model) self.mapper.addMapping(self.track_id, 0) # <3> self.mapper.addMapping(self.name, 1) self.mapper.addMapping(self.composer, 5) self.mapper.addMapping(self.milliseconds, 6) self.mapper.addMapping(self.bytes, 7) self.mapper.addMapping(self.unit_price, 8) self.model.setTable("Track") self.model.select() # <4> self.mapper.toFirst() # <5> self.setMinimumSize(QSize(400, 400)) widget = QWidget() widget.setLayout(form) self.setCentralWidget(widget)
def _init_db(self, table_name): self.table_name = table_name self.model = QSqlTableModel(parent=self, db=db_connection()) self.model.setTable(table_name) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.mapper = QDataWidgetMapper(self.model) self.mapper.setModel(self.model) self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit) self.model.dataChanged.connect(self.onDataChange) self.commit_button.clicked.connect(self.saveChanges) self.revert_button.clicked.connect(self.revertChanges)
def ConfigureDataMappers(model, mappings, delegate): mapper = QDataWidgetMapper(model) mapper.setModel(model) mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit) mapper.setItemDelegate(delegate(mapper)) for mapping in mappings: if hasattr(mapping[map_idx.WIDGET], "isCustom"): mapping[map_idx.WIDGET].init_db(model.database()) mapping[map_idx.WIDGET].changed.connect(mapper.submit) # if no USER property we should use QByteArray().setRawData("account_id", 10)) here mapper.addMapping(mapping[map_idx.WIDGET], model.fieldIndex(mapping[map_idx.DB_NAME])) # adjust width of QDateTimeEdits to show full date-time string if isinstance(mapping[map_idx.WIDGET], QDateTimeEdit): mapping[map_idx.WIDGET].setFixedWidth(mapping[ map_idx.WIDGET].fontMetrics().width("00/00/0000 00:00:00") * 1.25) return mapper
def __init__(self, model, nodeFactory, fieldFactory): super(PropertyEditor, self).__init__() self._dataMapper = QDataWidgetMapper() self._dataMapper.setModel(model) self._dataMapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self._model = model self._currentIndex = None self._fieldFactory = fieldFactory self._nodeFactory = nodeFactory # setup ui self.setColumnCount(2) self.setHeaderLabels(['Name', 'Value']) self.setSelectionMode(QAbstractItemView.NoSelection) self.setAlternatingRowColors(True) self.setFocusPolicy(Qt.NoFocus) # create all items per component self._createAllItems() self.resizeColumnToContents(0) self.setColumnWidth(0, self.columnWidth(0) + 20)
def __init__(self, model, parent=None): super(Window, self).__init__(parent) self.model = model # Set up the widgets. nameLabel = QLabel("Na&me:") nameEdit = QLineEdit() # Set up the mapper. self.mapper = QDataWidgetMapper(self) self.mapper.setModel(self.model) self.mapper.addMapping(nameEdit, 0) layout = QGridLayout() layout.addWidget(nameLabel, 0, 0, 1, 1) layout.addWidget(nameEdit, 0, 1, 1, 1) self.setLayout(layout) self.mapper.toFirst()
def __init__(self, parent=None): super(MainWidget, self).__init__(parent) # define tree view self.treeView = QTreeView(self) # insert line edit self.lineEdit1 = QLineEdit(self) self.lineEdit2 = QLineEdit(self) # insert a button group widget self.buttonGroupWidget1 = ButtonGroupWidget(self) self.buttonGroupWidget1.setTitle("Select option") self.buttonGroupWidget1.addRadioButton("Option 1", 1) self.buttonGroupWidget1.addRadioButton("Option 2", 2) self.buttonGroupWidget1.addRadioButton("Option 3", 3) layoutMain = QVBoxLayout(self) layoutMain.addWidget(self.treeView) layoutMain.addWidget(self.lineEdit1) layoutMain.addWidget(self.lineEdit2) layoutMain.addWidget(self.buttonGroupWidget1) # Create the data model and map the model to the widgets. self._model = DataModel() self.treeView.setModel(self._model) self._dataMapper = QDataWidgetMapper() self._dataMapper.setModel(self._model) # the mapping works fine for line edits and combo boxes self._dataMapper.addMapping(self.lineEdit1, 0) self._dataMapper.addMapping(self.lineEdit2, 1) # mapping to custom property self._dataMapper.addMapping(self.buttonGroupWidget1, 1, "selectedOption") self.treeView.selectionModel().currentChanged.connect( self.setSelection)
def __init__(self): QMainWindow.__init__(self) self.setupUi(self) #Initialize db createdb.init_db() model = QSqlRelationalTableModel(self.bookTable) model.setEditStrategy(QSqlTableModel.OnManualSubmit) model.setTable("books") # Remember the indexes of the columns: author_idx = model.fieldIndex("author") genre_idx = model.fieldIndex("genre") # Set the relations to the other database tables: model.setRelation(author_idx, QSqlRelation("authors", "id", "name")) model.setRelation(genre_idx, QSqlRelation("genres", "id", "name")) # Set the localized header captions: model.setHeaderData(author_idx, Qt.Horizontal, self.tr("Author Name")) model.setHeaderData(genre_idx, Qt.Horizontal, self.tr("Genre")) model.setHeaderData(model.fieldIndex("title"), Qt.Horizontal, self.tr("Title")) model.setHeaderData(model.fieldIndex("year"), Qt.Horizontal, self.tr("Year")) model.setHeaderData(model.fieldIndex("rating"), Qt.Horizontal, self.tr("Rating")) if not model.select(): print(model.lastError()) # Set the model and hide the ID column: self.bookTable.setModel(model) self.bookTable.setItemDelegate(BookDelegate(self.bookTable)) self.bookTable.setColumnHidden(model.fieldIndex("id"), True) self.bookTable.setSelectionMode(QAbstractItemView.SingleSelection) # Initialize the Author combo box: self.authorEdit.setModel(model.relationModel(author_idx)) self.authorEdit.setModelColumn( model.relationModel(author_idx).fieldIndex("name")) self.genreEdit.setModel(model.relationModel(genre_idx)) self.genreEdit.setModelColumn( model.relationModel(genre_idx).fieldIndex("name")) # Lock and prohibit resizing of the width of the rating column: self.bookTable.horizontalHeader().setSectionResizeMode( model.fieldIndex("rating"), QHeaderView.ResizeToContents) mapper = QDataWidgetMapper(self) mapper.setModel(model) mapper.setItemDelegate(BookDelegate(self)) mapper.addMapping(self.titleEdit, model.fieldIndex("title")) mapper.addMapping(self.yearEdit, model.fieldIndex("year")) mapper.addMapping(self.authorEdit, author_idx) mapper.addMapping(self.genreEdit, genre_idx) mapper.addMapping(self.ratingEdit, model.fieldIndex("rating")) selection_model = self.bookTable.selectionModel() selection_model.currentRowChanged.connect(mapper.setCurrentModelIndex) self.bookTable.setCurrentIndex(model.index(0, 0)) self.create_menubar()
def __init__(self): super().__init__() layout = QVBoxLayout() form = QFormLayout() self.track_id = QSpinBox() self.track_id.setDisabled(True) self.name = QLineEdit() self.album = QComboBox() self.media_type = QComboBox() self.genre = QComboBox() self.composer = QLineEdit() self.milliseconds = QSpinBox() self.milliseconds.setRange(0, 2147483647) self.milliseconds.setSingleStep(1) self.bytes = QSpinBox() self.bytes.setRange(0, 2147483647) self.bytes.setSingleStep(1) self.unit_price = QDoubleSpinBox() self.unit_price.setRange(0, 999) self.unit_price.setSingleStep(0.01) self.unit_price.setPrefix("$") form.addRow(QLabel("Track ID"), self.track_id) form.addRow(QLabel("Track name"), self.name) form.addRow(QLabel("Composer"), self.composer) form.addRow(QLabel("Milliseconds"), self.milliseconds) form.addRow(QLabel("Bytes"), self.bytes) form.addRow(QLabel("Unit Price"), self.unit_price) self.model = QSqlTableModel(db=db) self.mapper = QDataWidgetMapper() self.mapper.setModel(self.model) self.mapper.addMapping(self.track_id, 0) self.mapper.addMapping(self.name, 1) self.mapper.addMapping(self.composer, 5) self.mapper.addMapping(self.milliseconds, 6) self.mapper.addMapping(self.bytes, 7) self.mapper.addMapping(self.unit_price, 8) self.model.setTable("Track") self.model.select() self.mapper.toFirst() self.setMinimumSize(QSize(400, 400)) controls = QHBoxLayout() # tag::controls[] prev_rec = QPushButton("Previous") prev_rec.clicked.connect(self.mapper.toPrevious) next_rec = QPushButton("Next") next_rec.clicked.connect(self.mapper.toNext) save_rec = QPushButton("Save Changes") save_rec.clicked.connect(self.mapper.submit) # end::controls[] controls.addWidget(prev_rec) controls.addWidget(next_rec) controls.addWidget(save_rec) layout.addLayout(form) layout.addLayout(controls) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)
class PropertyEditor(QTreeWidget): def __init__(self, model, nodeFactory, fieldFactory): super(PropertyEditor, self).__init__() self._dataMapper = QDataWidgetMapper() self._dataMapper.setModel(model) self._dataMapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self._model = model self._currentIndex = None self._fieldFactory = fieldFactory self._nodeFactory = nodeFactory # setup ui self.setColumnCount(2) self.setHeaderLabels(['Name', 'Value']) self.setSelectionMode(QAbstractItemView.NoSelection) self.setAlternatingRowColors(True) self.setFocusPolicy(Qt.NoFocus) # create all items per component self._createAllItems() self.resizeColumnToContents(0) self.setColumnWidth(0, self.columnWidth(0) + 20) def _createAllItems(self): for type, properties in self._allProperties().items(): topItem = self._createComponentItem(type) if type == ComponentType.General: self._createNodeTypeItem(topItem) for property in properties: item = PropertyEditorItem(topItem) item.setText(0, property.label()) field = self._fieldFactory.create(property) self.setItemWidget(item, 1, field) def _allProperties(self): result = {} for type in NodeType.All(): node = self._nodeFactory.create(type) for component in node.components().values(): result[component.type()] = component.propertyMap() return result def _createComponentItem(self, type): names = ComponentType.Names() item = PropertyEditorItem() item.setText(0, names[type]) item.setData(0, Qt.UserRole, type) self.addTopLevelItem(item) item.setExpanded(True) return item def _createNodeTypeItem(self, topItem): self._nodeTypeItem = PropertyEditorItem(topItem) self._nodeTypeItem.setText(0, 'Type') font = self._nodeTypeItem.font( 1 ) # don't ask, this is how it will be the same size as in the editors font.setPointSize(font.pointSize()) self._nodeTypeItem.setFont(1, font) def changeSelection(self, current, prev): node = current.internalPointer() self._currentIndex = current items = self._itemsForNode(node) self._setMapping(current, items) def _itemsForNode(self, node): result = [] names = NodeType.Names() self._nodeTypeItem.setText(1, names[node.type()]) for i in range(self.topLevelItemCount()): item = self.topLevelItem(i) type = item.data(0, Qt.UserRole) component = node.component(type) item.setHidden(not component) if component is None: continue result.extend(self._itemsForComponent(component, item)) return result def _itemsForComponent(self, component, parentItem): result = [] for column, property in enumerate(component.propertyMap()): offset = 1 if component.type( ) == ComponentType.General else 0 # the first item of General is Type item = parentItem.child(column + offset) item.setProperty(property) result.append(item) return result def _setMapping(self, current, items): self._dataMapper.clearMapping() fields = [] for item in items: fields.append(self._mapField(current, item)) parent = current.parent() self._dataMapper.setRootIndex(parent) self._dataMapper.setCurrentModelIndex(current) for field in fields: field.changed.connect( self._dataMapper.submit ) # this MUST be after the setCurrentModelIndex def _mapField(self, current, item): property = item.property() if not property: # General/Type doesn't have a property return field = self.itemWidget(item, 1) parent = current.parent() readOnly = property.readOnly( ) or not parent.isValid() # the top level nodes are read only field.setReadOnly(readOnly) self._dataMapper.addMapping(field, property.column(), b'valueProperty') return field
class MainWindow(QMainWindow): def __init__(self, startWithConfig: None): super().__init__() self.ui = Ui_MainWindow() self.__titleModel = None self.__dataMapper = None self.__ytPlayer = None self.__previousConfigFile = None self.__settings = QSettings('TallerQt', 'QtMetale') #Comprobar si el settings esta cargado o no if startWithConfig is not None: self.__settings.setValue('configFile', startWithConfig) if self.__settings.value('configFile') is None: CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) PATH_TO_FILE = os.path.join(CURRENT_DIR, '../config.yaml') self.__settings.setValue('configFile', PATH_TO_FILE) self.__previousConfigFile = self.__settings.value('configFile') self.dialogoConfiguracion = None self.dialogoInforme = None self.ui.setupUi(self) self.__ytPlayer = YoutubePlayer(widgetToPlay=self.ui.videoPlayerWidget) self.prepareModels() self.setupUi() def setupUi(self): self.__dataMapper = QDataWidgetMapper(self) self.__dataMapper.setModel(self.__titleModel) propertyText = QByteArray(b'text') self.__dataMapper.addMapping(self.ui.tituloLineEdit, 0, propertyText) self.__dataMapper.addMapping(self.ui.grupoLineEdit, 1, propertyText) self.__dataMapper.addMapping(self.ui.yearLineEdit, 2, propertyText) QObject.connect(self.ui.titlesListView.selectionModel(), SIGNAL('currentRowChanged(QModelIndex,QModelIndex)'), self, SLOT('changeSelectedTitle(QModelIndex,QModelIndex)')) #Dialogo de configuracion self.dialogoConfiguracion = ConfigDialog(self) self.ui.actionConfiguracion.triggered.connect( self.dialogoConfiguracion.open) self.dialogoConfiguracion.finished.connect(self.reloadModelos) self.ui.playButton.clicked.connect(self.launchCurrentVideo) self.ui.stopButton.clicked.connect(self.__ytPlayer.stopVideo) self.ui.pauseButton.clicked.connect(self.__ytPlayer.pauseVideo) def launchCurrentVideo(self): self.__ytPlayer.playVideo(self.__dataMapper.currentIndex()) def prepareModels(self): list_titles = Title.readFromYAML(self.__settings.value('configFile')) self.__titleModel = TitlesTableModel(self, list_titles) self.ui.titlesListView.setModel(self.__titleModel) self.ui.titlesListView.setModelColumn(0) self.__ytPlayer.resetPlayList(list_titles) @Slot() def changeSelectedTitle(self, current: QModelIndex, previous: QModelIndex): self.__dataMapper.setCurrentIndex(current.row()) @Slot() def reloadModelos(self, result): currentConfigFile = self.__settings.value('configFile') if currentConfigFile != self.__previousConfigFile: list_titles = Title.readFromYAML( self.__settings.value('configFile')) self.__titleModel.titles = list_titles self.__previousConfigFile = self.__settings.value('configFile')
class AbstractOperationDetails(QWidget): dbUpdated = Signal() def __init__(self, parent=None): QWidget.__init__(self, parent) self.model = None self.table_name = '' self.mapper = None self.modified = False self.name = "N/A" self.layout = QGridLayout(self) self.layout.setContentsMargins(2, 2, 2, 2) self.bold_font = QFont() self.bold_font.setBold(True) self.bold_font.setWeight(75) self.main_label = QLabel(self) self.main_label.setFont(self.bold_font) self.layout.addWidget(self.main_label, 0, 0, 1, 1, Qt.AlignLeft) self.commit_button = QPushButton(self) self.commit_button.setEnabled(False) self.commit_button.setText("✔") self.commit_button.setFont(self.bold_font) self.commit_button.setFixedWidth( self.commit_button.fontMetrics().width("XXX")) self.revert_button = QPushButton(self) self.revert_button.setEnabled(False) self.revert_button.setText("✖️") self.revert_button.setFont(self.bold_font) self.revert_button.setFixedWidth( self.revert_button.fontMetrics().width("XXX")) self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) def _init_db(self, table_name): self.table_name = table_name self.model = QSqlTableModel(parent=self, db=db_connection()) self.model.setTable(table_name) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.mapper = QDataWidgetMapper(self.model) self.mapper.setModel(self.model) self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit) self.model.dataChanged.connect(self.onDataChange) self.commit_button.clicked.connect(self.saveChanges) self.revert_button.clicked.connect(self.revertChanges) def isCustom(self): return True def setId(self, id): self.model.setFilter(f"id={id}") self.mapper.setCurrentModelIndex(self.model.index(0, 0)) @Slot() def onDataChange(self, _index_start, _index_stop, _role): self.modified = True self.commit_button.setEnabled(True) self.revert_button.setEnabled(True) @Slot() def saveChanges(self): if not self.model.submitAll(): logging.fatal( g_tr('AbstractOperationDetails', "Operation submit failed: ") + self.model.lastError().text()) return False self.modified = False self.commit_button.setEnabled(False) self.revert_button.setEnabled(False) self.dbUpdated.emit() return True @Slot() def revertChanges(self): self.model.revertAll() self.modified = False self.commit_button.setEnabled(False) self.revert_button.setEnabled(False) def createNew(self, account_id=0): self.mapper.submit( ) # FIXME there is check for uncommited call before - do we need submit() here? self.model.setFilter(f"{self.table_name}.id = 0") new_record = self.prepareNew(account_id) assert self.model.insertRows(0, 1) self.model.setRecord(0, new_record) self.mapper.toLast() def prepareNew(self, account_id): new_record = self.model.record() return new_record def copyNew(self): row = self.mapper.currentIndex() new_record = self.copyToNew(row) self.model.setFilter(f"{self.table_name}.id = 0") assert self.model.insertRows(0, 1) self.model.setRecord(0, new_record) self.mapper.toLast() def copyToNew(self, row): new_record = self.model.record(row) return new_record
def __init__(self): super().__init__() hlayout = QHBoxLayout() layout = QVBoxLayout() self.filtert = QLineEdit() self.filtert.setPlaceholderText("Search...") self.table = QTableView() vlayout = QVBoxLayout() vlayout.addWidget(self.filtert) vlayout.addWidget(self.table) # Left/right pane. hlayout.addLayout(vlayout) hlayout.addLayout(layout) form = QFormLayout() self.track_id = QSpinBox() self.track_id.setDisabled(True) self.track_id.setRange(0, 2147483647) self.name = QLineEdit() self.album = QComboBox() self.media_type = QComboBox() self.genre = QComboBox() self.composer = QLineEdit() self.milliseconds = QSpinBox() self.milliseconds.setRange(0, 2147483647) self.milliseconds.setSingleStep(1) self.bytes = QSpinBox() self.bytes.setRange(0, 2147483647) self.bytes.setSingleStep(1) self.unit_price = QDoubleSpinBox() self.unit_price.setRange(0, 999) self.unit_price.setSingleStep(0.01) self.unit_price.setPrefix("$") form.addRow(QLabel("Track ID"), self.track_id) form.addRow(QLabel("Track name"), self.name) form.addRow(QLabel("Composer"), self.composer) form.addRow(QLabel("Milliseconds"), self.milliseconds) form.addRow(QLabel("Bytes"), self.bytes) form.addRow(QLabel("Unit Price"), self.unit_price) self.model = QSqlTableModel(db=db) self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(self.model) self.proxy_model.sort(1, Qt.AscendingOrder) self.proxy_model.setFilterKeyColumn(-1) # all columns self.table.setModel(self.proxy_model) # Update search when filter changes. self.filtert.textChanged.connect(self.proxy_model.setFilterFixedString) self.mapper = QDataWidgetMapper() self.mapper.setModel(self.proxy_model) self.mapper.addMapping(self.track_id, 0) self.mapper.addMapping(self.name, 1) self.mapper.addMapping(self.composer, 5) self.mapper.addMapping(self.milliseconds, 6) self.mapper.addMapping(self.bytes, 7) self.mapper.addMapping(self.unit_price, 8) self.model.setTable("Track") self.model.select() # Change the mapper selection using the table. self.table.selectionModel().currentRowChanged.connect( self.mapper.setCurrentModelIndex) self.mapper.toFirst() # tag::controls[] self.setMinimumSize(QSize(800, 400)) controls = QHBoxLayout() prev_rec = QPushButton("Previous") prev_rec.clicked.connect(self.mapper.toPrevious) next_rec = QPushButton("Next") next_rec.clicked.connect(self.mapper.toNext) save_rec = QPushButton("Save Changes") save_rec.clicked.connect(self.mapper.submit) controls.addWidget(prev_rec) controls.addWidget(next_rec) controls.addWidget(save_rec) layout.addLayout(form) layout.addLayout(controls) widget = QWidget() widget.setLayout(hlayout) self.setCentralWidget(widget)