Results 1 to 2 of 2

Thread: Unable to add a QCompleter to a QCombobox in PyQt5

  1. #1
    Join Date
    Feb 2013
    Posts
    8
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Unable to add a QCompleter to a QCombobox in PyQt5

    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.

  2. #2
    Join Date
    Feb 2013
    Posts
    8
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Unable to add a QCompleter to a QCombobox in PyQt5

    It seems that adding the EditRole to the model seems to work...
    I updated the model like this:

    Qt Code:
    1. def data(self, index: QModelIndex, role: int = ...):
    2. if role == Qt.DisplayRole or role == Qt.EditRole:
    3. return self.data[index.row()][index.column()]
    4. return QVariant()
    To copy to clipboard, switch view to plain text mode 

    Now everything seems to work fine and I don't need to access self.lineEdit() and set its text...

Similar Threads

  1. Bug in Qt5.12 or PyQt5.11.3???
    By barkowski@shinobi-mail.de in forum Qt Programming
    Replies: 5
    Last Post: 27th January 2019, 11:21
  2. How does QComboBox uses/calls QCompleter ?
    By boo9 in forum Qt Programming
    Replies: 15
    Last Post: 9th July 2016, 16:01
  3. How can I install pyQt5
    By prachi kamble in forum Installation and Deployment
    Replies: 0
    Last Post: 4th June 2015, 13:13
  4. QComboBox with QCompleter
    By cic in forum Qt Programming
    Replies: 1
    Last Post: 27th September 2013, 20:21
  5. Replies: 1
    Last Post: 12th October 2008, 09:21

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.