Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. QDataWidgetMapper addMapping to propertyName
Forum Updated to NodeBB v4.3 + New Features

QDataWidgetMapper addMapping to propertyName

Scheduled Pinned Locked Moved Solved Qt for Python
2 Posts 1 Posters 376 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BamboozledBaboon
    wrote on last edited by BamboozledBaboon
    #1

    Im using pyside6, but I'm referencing these c++ docs and example
    https://doc.qt.io/qt-6/qdatawidgetmapper.html#addMapping-1
    https://doc.qt.io/qt-6/qtwidgets-itemviews-combowidgetmapper-example.html

    I've ported the above c++ example to python/pyside. What I don't understand is how is the addMapping working under the hood in regard to referncing the combobox's currentIndex property?

    self.mapper.addMapping(self.typeComboBox, 2, QByteArray("currentIndex"))
    

    I understand you can use .currentIndex to retrieve the selected combo item for saving to the model, but I don't understand the mechanism that allows the mapper to know what combbox item to select/present as the mapper moves through the main model.

    Finally, if I were to subclass combobox how exactly would I define my own property that I could utilize with mapper.addMapping?

    import sys
    from PySide6.QtCore import QStringListModel, QByteArray
    from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QLabel,\
        QLineEdit, QTextEdit, QComboBox, QPushButton, QDataWidgetMapper, QGridLayout
    from PySide6.QtGui import QStandardItemModel, QStandardItem
    
    
    class MyCombo(QComboBox):
        def __init__(self, parent=None):
            super().__init__(parent=parent)
    
        def xyz(self):
            print("xyz called")
            return self.currentIndex() + 1
    
        def setXyz(self):
            print("setter was called")
    
    
    class MyWindow(QMainWindow):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.setupModel()
    
            self.nameLabel = QLabel("Na&me:")
            self.nameEdit = QLineEdit()
            self.addressLabel = QLabel("&Address:")
            self.addressEdit = QTextEdit()
            self.typeLabel = QLabel("&Type:", )
            self.typeComboBox = QComboBox()
            self.nextButton = QPushButton("&Next")
            self.previousButton = QPushButton("&Previous")
    
            self.nameLabel.setBuddy(self.nameEdit)
            self.addressLabel.setBuddy(self.addressEdit)
            self.typeLabel.setBuddy(self.typeComboBox)
    
            self.typeComboBox.setModel(self.typeModel)
    
            self.mapper = QDataWidgetMapper(self)
            self.mapper.setModel(self.model)
            self.mapper.addMapping(self.nameEdit, 0)
            self.mapper.addMapping(self.addressEdit, 1)
            self.mapper.addMapping(self.typeComboBox, 2, QByteArray("currentIndex"))
            #self.mapper.addMapping(self.typeComboBox, 2, QByteArray("xyz"))
    
            self.previousButton.clicked.connect(self.mapper.toPrevious)
            self.nextButton.clicked.connect(self.mapper.toNext)
            self.mapper.currentIndexChanged.connect(self.updateButtons)
    
            self.layout = QGridLayout()
            self.layout.addWidget(self.nameLabel, 0, 0, 1, 1)
            self.layout.addWidget(self.nameEdit, 0, 1, 1, 1)
            self.layout.addWidget(self.previousButton, 0, 2, 1, 1)
            self.layout.addWidget(self.addressLabel, 1, 0, 1, 1)
            self.layout.addWidget(self.addressEdit, 1, 1, 2, 1)
            self.layout.addWidget(self.nextButton, 1, 2, 1, 1)
            self.layout.addWidget(self.typeLabel, 3, 0, 1, 1)
            self.layout.addWidget(self.typeComboBox, 3, 1, 1, 1)
    
            self.centralWidget = QWidget(self)
            self.centralWidget.setLayout(self.layout)
            self.setCentralWidget(self.centralWidget)
    
            self.setWindowTitle("Delegate Widget Mapper")
            self.mapper.toFirst()
    
        def updateButtons(self, row):
            self.previousButton.setEnabled(row > 0)
            self.nextButton.setEnabled(row < self.model.rowCount())
    
        def setupModel(self):
            items = ["Home", "Work", "Other"]
            self.typeModel = QStringListModel(items)
    
            self.model = QStandardItemModel(5, 3, self)
            names = ["Alice", "Bob", "Carol", "Donald", "Emma"]
            addresses = ["<qt>123 Main Street<br/>Market Town</qt>",
                         "<qt>PO Box 32<br/>Mail Handling Service",
                         "<br/>Service City</qt>",
                         "<qt>The Lighthouse<br/>Remote Island</qt>",
                         "<qt>47338 Park Avenue<br/>Big City</qt>",
                         "<qt>Research Station<br/>Base Camp<br/>Big Mountain</qt>"]
            types = ["0", "1", "2", "0", "2"]
    
            for row in range(5):
                item = QStandardItem(names[row])
                self.model.setItem(row, 0, item)
                item = QStandardItem(addresses[row])
                self.model.setItem(row, 1, item)
                item = QStandardItem(types[row])
                self.model.setItem(row, 2, item)
    
    
    if __name__ == '__main__':
        app = QApplication()
        win = MyWindow()
        win.show()
        sys.exit(app.exec())
    
    
    1 Reply Last reply
    0
    • B Offline
      B Offline
      BamboozledBaboon
      wrote on last edited by BamboozledBaboon
      #2

      Okay, I think I've figured it out. I remember the docs mentioned 'user property' but I glossed over it. Turns out I didn't understand what a QtCore.Property was.
      Here's relevant docs: https://doc-snapshots.qt.io/qtforpython-dev/PySide6/QtCore/Property.html
      Here's a working subclassed combo example that uses a custom property.

      from PySide6.QtCore import Property
      from PySide6.QtWidgets import QComboBox
      
      
      class MyCombo(QComboBox):
      
          def __init__(self, parent=None):
              super().__init__(parent=parent)
      
          def readXyz(self):
              print("read xyz called")
              return self.currentIndex()
      
          def setXyz(self, i):
              print("set xyz called")
              self.setCurrentIndex(i)
      
          xyz = Property(int, readXyz, setXyz)
      
      

      Or a more pythonic(?) version of property getters and setters that I'm used to:

      from PySide6.QtCore import Property
      from PySide6.QtWidgets import QComboBox 
      
      class MyCombo(QComboBox):
      
          @Property(int)
          def xyz(self):
              print("read xyz called")
              return self.currentIndex()
      
          @xyz.setter
          def xyz(self, i):
              print("set xyz called")
              self.setCurrentIndex(i)
      
      1 Reply Last reply
      1
      • B BamboozledBaboon has marked this topic as solved on

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved