Sarah Sarah -4 years ago 368
Python Question

PyQt: How to connect a QStandardItem in a QStandardItemModel to a function

I am creating an application in PyQt in which I have a a list of check boxes which I have created using QStandardItemModel and QStandardItem and it works perfectly. I want to connect the first item in the list which is a 'Select all' check box to a function. This function should be able to check all the other items of the list. I'm trying to do this by the following code:

model = QStandardItemModel(list)
item = QStandardItem("Select all")
model.appendRow(item)
item.setCheckable(True)
model.itemChanged.connect(state_changed)

def state_changed(item):
print ("Hello")


I have added more items to the list from the output of an SQL query and I can see that 'Hello' is printed irrespective of which check box I click. This is my entire code:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtSql import *
def main():
db = QSqlDatabase.addDatabase("QODBC")
db.setHostName('LAPTOP-B79DRPA3')
db.setDatabaseName('local')
db.open()
if (db.open()==False):
QMessageBox.critical(None, "Database Error",
db.lastError().text())

query = QSqlQuery ()
query.exec_ ("select id from [Sarah].[dbo].fraga")

list = QListView()
model = QStandardItemModel(list)

item = QStandardItem("Select all")
model.appendRow(item)
item.setCheckable(True)
model.itemChanged.connect(state_changed)

while (query.next()):
item1 = QStandardItem(str(query.value(0)))
model.appendRow(item1)
item1.setCheckable(True)

list.setModel(model)
list.show()
return app.exec_()

def state_changed(item):
print ("Hello")

if __name__ == '__main__':
app = QApplication(sys.argv)
list = QListView()
model = QStandardItemModel(list)
main()


How do I ensure that the function is invoked only when the state of 'Select All' is changed?

Answer Source

Instead of connecting to QAbstractItemModel.itemChanged signal, connect to QAbstractItemView.clicked signal, which specifies the index clicked. Also, it's advisable not to name a variable list, as it interferes with the built-in list.

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtSql import *
def main():
    db = QSqlDatabase.addDatabase("QODBC")
    db.setHostName('LAPTOP-B79DRPA3')
    db.setDatabaseName('local')
    db.open()
    if (db.open()==False):
      QMessageBox.critical(None, "Database Error",
                db.lastError().text())

    query = QSqlQuery ()
    query.exec_  ("select id from [Sarah].[dbo].fraga")

    list_view = QListView()
    model = QStandardItemModel(list_view)

    item = QStandardItem("Select all")
    model.appendRow(item)
    item.setCheckable(True)
    list_view.clicked.connect(state_changed)

    while (query.next()):
        item1 = QStandardItem(str(query.value(0)))
        model.appendRow(item1)
        item1.setCheckable(True)

    list_view.setModel(model)
    list_view.show()
    return app.exec_()

def state_changed(index):
    if index == 0:
        print ("Hello")

if __name__ == '__main__':
    app  = QApplication(sys.argv)
    list_view = QListView()
    model = QStandardItemModel(list)
    main()
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download