Hi,

I have the following code:

Qt Code:
  1. import sys
  2. from functools import partial
  3. from typing import Optional
  4.  
  5. from PyQt5 import QtCore
  6. Qt
  7.  
  8.  
  9. class MyModel(QAbstractTableModel):
  10.  
  11. def __init__(self, parent: Optional[QObject] = None) -> None:
  12. super().__init__(parent=parent)
  13.  
  14. self.headers = ['Nummer', 'Name', 'Gemeinde']
  15. self.data = [
  16. ('010006', 'Alt Duvenstedt', 'Alt Duvenstedt'),
  17. ('010010', 'Altenhof', 'Altenhof'),
  18. ('010012', 'Altwickenbeck (Neuw)', 'Neuwittenbeck'),
  19. ('010021', 'Bargstedt', 'Bargstedt'),
  20. ('010023', 'Barkelsby', 'Barkelsby'),
  21. ('010024', 'Basdorf (Rie)', 'Rieseby'),
  22. ]
  23.  
  24. def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...):
  25. if orientation == Qt.Horizontal and role == Qt.DisplayRole:
  26. return self.headers[section]
  27.  
  28. def columnCount(self, parent: QModelIndex = ...) -> int:
  29. return len(self.headers)
  30.  
  31. def rowCount(self, parent: QModelIndex = ...) -> int:
  32. return len(self.data)
  33.  
  34. def data(self, index: QModelIndex, role: int = ...):
  35. if role == Qt.DisplayRole:
  36. return self.data[index.row()][index.column()]
  37. return QVariant()
  38.  
  39.  
  40. class MyCombobox(QComboBox):
  41.  
  42. def __init__(self, parent: Optional[QWidget] = None) -> None:
  43. super().__init__(parent=parent)
  44.  
  45. self.setFocusPolicy(Qt.StrongFocus)
  46. # self.setEditable(True)
  47.  
  48. # self.filterModel = QSortFilterProxyModel(self)
  49. # self.filterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
  50.  
  51. self.tableView = QTableView(self)
  52. self.setView(self.tableView)
  53. self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
  54. self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
  55. self.tableView.setSortingEnabled(True)
  56. self.tableView.setAutoScroll(False)
  57. self.tableView.horizontalHeader().setStretchLastSection(True)
  58. self.tableView.verticalHeader().hide()
  59.  
  60. # self.completer = QCompleter(self)
  61. # self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
  62. # self.completer.setPopup(self.tableView)
  63. # self.completer.setModel(self.filterModel)
  64. # self.setCompleter(self.completer)
  65.  
  66. # self.lineEdit().textEdited.connect(self.filterModel.setFilterFixedString)
  67. # self.completer.activated.connect(self.onCompleterActivated)
  68.  
  69. def setModel(self, model: QtCore.QAbstractItemModel) -> None:
  70. super().setModel(model)
  71. # self.filterModel.setSourceModel(model)
  72. # self.completer.setModel(self.filterModel)
  73.  
  74. self.tableView.resizeColumnsToContents()
  75. self.tableView.resizeRowsToContents()
  76. self.tableView.setMinimumWidth(self.tableView.horizontalHeader().length())
  77. self.setMinimumWidth(100)
  78.  
  79. def setModelColumn(self, column):
  80. super().setModelColumn(column)
  81. # self.filterModel.setFilterKeyColumn(column)
  82. # self.completer.setCompletionColumn(column)
  83.  
  84. # def onCompleterActivated(self, text):
  85. # if text:
  86. # index = self.findText(str(text))
  87. # self.setCurrentIndex(index)
  88.  
  89.  
  90. def setModelIndex(index: int, target: QComboBox):
  91. target.blockSignals(True)
  92. target.setCurrentIndex(index)
  93. target.blockSignals(False)
  94.  
  95.  
  96. if __name__ == '__main__':
  97. app = QApplication(sys.argv)
  98.  
  99. model = MyModel()
  100. sortModel = QSortFilterProxyModel()
  101. sortModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
  102. sortModel.sort(1, Qt.AscendingOrder)
  103. sortModel.setSourceModel(model)
  104.  
  105. combobox = MyCombobox()
  106. combobox.setModel(sortModel)
  107. combobox.setModelColumn(0)
  108.  
  109. combobox2 = MyCombobox()
  110. combobox2.setModel(sortModel)
  111. combobox2.setModelColumn(1)
  112.  
  113. combobox.currentIndexChanged.connect(partial(setModelIndex, target=combobox2))
  114. combobox2.currentIndexChanged.connect(partial(setModelIndex, target=combobox))
  115.  
  116. widget = QWidget()
  117. layout = QHBoxLayout()
  118. layout.addWidget(QLabel('Nummer'))
  119. layout.addWidget(combobox)
  120. layout.addWidget(QLabel('Name'))
  121. layout.addWidget(combobox2)
  122. layout.addStretch(10)
  123.  
  124. widget.setWindowTitle('Synchronized comboboxes with shared model')
  125. widget.setFixedWidth(500)
  126. widget.setLayout(layout)
  127. widget.show()
  128.  
  129. sys.exit(app.exec_())
To copy to clipboard, switch view to plain text mode 

I have a model which is shared between two comboboxes.
If I select an entry in one combobox, the other combobox should be updated accordingly.
This works fine when the combobox is not set editable.

As soon as I set it editable (uncommenting the code), I am unable to fill the combobox correctly.

There a several issues I don't understand:

  1. The tableview can not be used twice (I guess I have to duplicate the code and create two instances of a tableview, one for the combobox itself and one for the completer?)
  2. If I select something in the tableview of the combobox, the lineedit is not updated
  3. If I connect the textEdited signal of the lineedit and try to change the index "manually", the changes still are not reflected in the combobox.


I removed all completer code as well and only wanted to have an editable combobox with a tableview, but this does not work as well. Only if I set editable to False I have a working combobox again (selecting something in the tableview will set the index and display the correct text).

What am I doing wrong? I can't figure out what the problem is.

The code above should be a working example with two synched readonly comboboxes.
I just want to add autocompletion / filtering to both of them, because this tableview will contain thousands of items later on.