Results 1 to 3 of 3

Thread: How to filter items of a combobox in tableview and QSqlRelationalTableModel?

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jun 2021
    Posts
    2
    Qt products
    Platforms
    Unix/X11

    Default How to filter items of a combobox in tableview and QSqlRelationalTableModel?

    Hi everybody. i know this forum is for c++ but as it is related to Qt i asked it here may somebody help.

    I am trying learning PyQt5. I made an app. In my app I have a tableview that is set as below:

    Qt Code:
    1. self.table = QTableView()
    2. self.model = QSqlRelationalTableModel(self)
    3. self.model.setTable('main')
    4. self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
    5. self.model.setRelation(1, QSqlRelation("Names", "nameOfCm", "nameOfCm"))
    6. self.model.setRelation(2, QSqlRelation("Types", "type_IDs", "typeOfCm"))
    7. self.model.setRelation(8, QSqlRelation("Places", "placeName", "placeName"))
    8. self.model.select()
    9. self.table.setModel(self.model)
    10. self.table.setItemDelegate(QSqlRelationalDelegate(self.table))
    To copy to clipboard, switch view to plain text mode 

    By using QSqlRelationalDelegate I have comboboxes in some columns of the table.

    Column No:1 is the name of some electronic components (like Transistor Or IC etc.).

    Column No:2 is the type of this electronic components (For example PNP, NPNOp-Amp, Micro and so on).

    When I click on combobox in column "type"(Column No:2) it shows all type of electronic components no matter what I have selected in combobox column "name" (Column No:1).
    I want to filter these items in such a way that only related items for combobox "name" show in the combobox "type".

    For example If I choose transistor from "name", combobox "type" shows: NPN, PNP.
    And if I choose IC, combobox "type" shows: Micro, Op_Amp.

    what should I do ?

    This is simplified code( you need to ad components by clicking on "add components" button above the table:

    Qt Code:
    1. import sys
    2. from PyQt5.QtCore import Qt
    3. from PyQt5.QtWidgets import *
    4. from PyQt5.QtSql import *
    5.  
    6. connectDB = QSqlDatabase.addDatabase("QSQLITE")
    7. connectDB.setDatabaseName('test.db')
    8. connectDB.open()
    9. query = QSqlQuery()
    10. createNameTable='CREATE TABLE IF NOT EXISTS "Names" ("nameOfCm" TEXT, PRIMARY KEY("nameOfCm"))'
    11. createTypeTable='CREATE TABLE IF NOT EXISTS "Types" ("type_IDs" TEXT, "typeOfCm" TEXT,PRIMARY KEY("type_IDs"))'
    12. createMainTable='CREATE TABLE IF NOT EXISTS "main" ("partnumber" TEXT,"name" TEXT,"type" TEXT,PRIMARY KEY("partnumber"))'
    13.  
    14. query.exec(createNameTable)
    15. query.exec(createTypeTable)
    16. query.exec(createMainTable)
    17. query.exec("INSERT INTO Names (nameOfCm) VALUEs ('IC')")
    18. query.exec("INSERT INTO Names (nameOfCm) VALUEs ('Transistor')")
    19. query.exec("INSERT INTO Types (type_IDs,typeOfCm) VALUEs ('Transistor1','NPN')")
    20. query.exec("INSERT INTO Types (type_IDs,typeOfCm) VALUEs ('Transistor2','PNP')")
    21. query.exec("INSERT INTO Types (type_IDs,typeOfCm) VALUEs ('IC1','Op_AMP')")
    22. query.exec("INSERT INTO Types (type_IDs,typeOfCm) VALUEs ('IC2','Micro')")
    23.  
    24. class main (QMainWindow):
    25. def __init__(self):
    26. super(main,self).__init__()
    27. self.setWindowTitle('My Electronic Inventory v: 0.1')
    28. self.setGeometry(10, 10, 400 , 500)
    29. self.UI()
    30. self.show()
    31. self.databaseIsConect()
    32.  
    33. def UI(self):
    34.  
    35. self.mainCentralWidget = QWidget()
    36. self.mainLayout = QVBoxLayout()
    37. self.setCentralWidget(self.mainCentralWidget)
    38. self.centralWidget().setLayout(self.mainLayout)
    39.  
    40. self.newComponentButton= QPushButton("Add component")
    41. self.newComponentButton.clicked.connect(self.newComponentButtonClicked)
    42.  
    43. self.table= QTableView()
    44. self.model = QSqlRelationalTableModel(self)
    45. self.model.setTable('main')
    46. self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
    47. self.model.setRelation(1, QSqlRelation("Names", "nameOfCm", "nameOfCm"))
    48. self.model.setRelation(2, QSqlRelation("Types", "type_IDs", "typeOfCm"))
    49. self.model.select()
    50. self.table.setModel(self.model)
    51. self.table.setItemDelegate(QSqlRelationalDelegate(self.table))
    52. self.table.setEditTriggers(QAbstractItemView.DoubleClicked|QAbstractItemView.AnyKeyPressed)
    53. self.model.setHeaderData(0,Qt.Horizontal,('Part Number'))
    54. self.model.setHeaderData(1,Qt.Horizontal,('Name'))
    55. self.model.setHeaderData(2,Qt.Horizontal,('Type'))
    56.  
    57. self.mainLayout.addWidget(self.newComponentButton)
    58. self.mainLayout.addWidget(self.table)
    59.  
    60. def databaseIsConect(self):
    61. if connectDB.isOpen():
    62. print("Databsae Is Connected")
    63. else:
    64. print("Erorr!. Databsae Is Not Connected")
    65. def newComponentButtonClicked(self):
    66. row = self.model.rowCount()
    67. self.model.insertRow(row)
    68. if __name__ == '__main__':
    69. app = QApplication(sys.argv)
    70. ex = main()
    71. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 

    After some try, I managed to solve part of my problem by sub-classing QSqlRelationalTableModel:
    Qt Code:
    1. class mysqlmodel(QSqlRelationalTableModel):
    2. def __init__(self, parent):
    3. super().__init__()
    4.  
    5. def setData(self, item, value, role):
    6.  
    7. super().setData(item,value, role)
    8. a= item.siblingAtColumn(1).data()
    9. self.relationModel(2).setFilter("type_IDs like '"+a+"%'")
    10. return True
    To copy to clipboard, switch view to plain text mode 
    This works for my purpose, but there are issues:

    At first run, if you want to change an item in combobox 2, it shows all options, but after modifications it shows just item belongs to item in combobox 1.
    If you change an item in combobox 2 of row no 2, then you want to change an item in combobox 2 of row 3, it shows options for the "PREVIOUS" row unless you submit that(for example by pressing enter button or clicking somewhere else within the table) and then automatically it changes to options for current row, and now you can select the right item.
    Last edited by yousef; 30th June 2021 at 16:57.

Similar Threads

  1. Replies: 0
    Last Post: 14th August 2018, 12:57
  2. Replies: 0
    Last Post: 31st October 2010, 22:55
  3. Combobox entries filter as I type
    By yazwas in forum Qt Programming
    Replies: 3
    Last Post: 8th August 2009, 15:04
  4. QSqlRelationalTableModel and comboBox
    By musti in forum Newbie
    Replies: 9
    Last Post: 14th October 2007, 10:43
  5. Realtime TableView filter with (lineEdit)
    By xgoan in forum Qt Programming
    Replies: 2
    Last Post: 21st December 2006, 16:17

Tags for this Thread

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.