PDA

View Full Version : QListWidget SIGNAL Problem



skuda
7th December 2007, 18:47
Hello, i have a problem with a listwidget i have created inside a QToolBox page, if doesnt emit signals, i can select the items but it doesnt emit itemDoubleClicked or itemClicked or itemActivated, i have tried with mouse and keyboard without luck, i have installed an event filter and do a print to every event it pass and i get no event in mouse click, double click, or keyboard enter, but i can navigate through items with keyboard or mouse, anyone has any idea what can be the problem here? or any better way that the eventfilter to debug it? Thanks.

wysota
7th December 2007, 18:54
Could we see some code please?

skuda
7th December 2007, 19:11
yes, sorry, this is pyqt code but i think it is very readable:



self.opePendientesPage = QtGui.QWidget()
self.opePendientesPage.setGeometry(QtCore.QRect(0, 0,171,260))
self.opePendientesPage.setObjectName("opePendientesPage")

self.operacionesPendientesListWidget = QListWidget(self.opePendientesPage)
self.operacionesPendientesListWidget.setFocusPolic y(QtCore.Qt.WheelFocus)
self.operacionesPendientesListWidget.setEditTrigge rs(QtGui.QAbstractItemView.NoEditTriggers)
self.operacionesPendientesListWidget.setObjectName ("operacionesPendientesListWidget")

self.vboxlayout4 = QtGui.QVBoxLayout(self.opePendientesPage)
self.vboxlayout4.setSpacing(1)
self.vboxlayout4.setContentsMargins(0,1,1,1)
self.vboxlayout4.setObjectName("vboxlayout4")
self.vboxlayout4.addWidget(self.operacionesPendien tesListWidget)
self.toolBox.addItem(self.opePendientesPage,QtGui. QIcon(":/images/operaciones_pendientes.png"),"")

self.connect(self.operacionesPendientesListWidget, SIGNAL("itemDoubleClicked(QListWidgetItem)"), self.cargarPendiente)


I have in other pages of the toolbox QPushButtons that launch clicked() signal, i dont know what can be the problem. I have pasted the itemDoubleClicked signal but i have tried with ItemClicked and with itemActivated with the same results.

wysota
7th December 2007, 19:24
Hmmm... correct me if I'm wrong, but your connect statement misses a SLOT() argument...

skuda
7th December 2007, 20:08
No, in PyQt only need the SLOT() when connecting if you are to launch an internal slot of QT (like accept() or reject()) but not for self defined functions, the working code for the buttons is this:



self.connect(self.okButton, SIGNAL("clicked()"), self.accept)


this go the accept function inside the class. But i cant get the signals of the listwidget.

wysota
7th December 2007, 21:44
So cargarPendiente is the name of a function? Can we see it? I understand it doesn't get called, correct? Does the list widget itself work? Can you click it or scroll it?

skuda
7th December 2007, 22:00
The function never is called, the listwidget works as expected, i can scroll, select items and navigate between them with keyboard arrows or mouse clicks. The function only does a print actually to test the signal but it is never emitted.



def cargarPendiente(self, listaItem):
print "ok"

wysota
7th December 2007, 22:18
If the list works, then signals are delivered. Try connecting some signal to a slot that already exists in Qt, like QCoreApplication::quit(). If it works, it means the problem is not with the list widget but with your slot. One more thing - don't you have to flush the output stream for the printed text to become visible on the terminal like in other languages?

skuda
7th December 2007, 22:27
I have tested connect to the quit() SLOT and it doesnt works either, yes in python this is the way to print to console. you can do:

print "Variable Name: " + variableName + " Variable Name2: " + variableName2
or:
print "Variable Name: %s, Variable Name2: %s" % (variableName, variableName2)

to do string formating if you want. wysota i have tested installing an eventfilter to this and print every event.type() that pass the filter, i have not received any event of mouse or keyboard handling.

wysota
7th December 2007, 22:34
Then you did something wrong, because obviously events get delivered, as the list widget works. See if you didn't do any spelling mistakes, that's a common problem with python. And about print, I was asking if you need to add a newline character at the end to flush the output or does Python add it for you itself. In doubt use qDebug() instead of print.

By the way, what did you install thise event filter on? the widget or its viewport?

Oh... and it could help if you provided more code.

One more thing - check if connect() returns true or false.

skuda
7th December 2007, 22:48
yes print add newlines at the end of every print statement, i use very much print to debug inside this application.



def eventFilter(self, object, event):
print event.type()
return QMainWindow.eventFilter(self, object, event)

in _init_ function i install the eventfilter with:
self.operacionesPendientesListWidget.installEventF ilter(self)


it prints this events:
when i mouseover: 129
when i left the widget: 12, 77, 12, 25, 9
when i doubleclick or click i get no signal.

i have found a detail, i get the signals when i enter in the toolbox but i am filtering listwidget, can be the problem that toolbox intercepts the mouse events? but i can select items and move between them with cursors ¿?

the way i create the items:



def dejarPendiente(self, codigoCliente, numeroIdentificador):
hora = QTime().currentTime().toString(FORMATO_HORA)
if self.sender() == self.ventaWidget:
item = QListWidgetItem(QIcon(":/images/pantalla_ventas.png"), self.tr("%1 %2").arg(codigoCliente).arg(hora))
item.setData(Qt.UserRole, QVariant(numeroIdentificador))
self.operacionesPendientesListWidget.insertItem(0, item)

wysota
7th December 2007, 23:23
The toolbox shouldn't be filtering the list widget and even if it did, it wouldn't steal its events so eventually they'd reach the listview. The listview itself installs an event filter on its viewport, but this is not important right now. Your problem is that emited signal doesn't trigger your slot. Again, could you check if connect returns true or false?

skuda
8th December 2007, 00:07
returns True

do i have any way to see the signals emitted by the ListWidget?

wysota
8th December 2007, 00:15
You can use a signal spy (for example the one that comes with QTestLib).

I'm pretty sure the list widget is fine and there is some stupid problem we don't see with your slot.

skuda
8th December 2007, 00:54
signal spy seems not to be wrapped in PyQt but i have found anything interesting, i have changed my code to use qlistview and a oversimplified qabstractlistmodel subclass, here you have the relevant code:



self.listView = QListView(self.opePendientesPage)
self.connect(self.listView, SIGNAL("doubleClicked(QModelIndex)"), self.cargarPendiente)
self.listmodel = listModel()
self.listView.setModel(self.listmodel)

class listModel(QAbstractListModel):
def __init__(self, parent=None):
super(listModel, self).__init__(parent)
self.nullvariant = QVariant()

def rowCount(self, index=QModelIndex()):
return 1

def data(self, index, role=Qt.DisplayRole):
row = index.row()
if not index.isValid():
return self.nullvariant
if role == Qt.DisplayRole or role == Qt.EditRole:
return QVariant(QString("TEST"))
else:
return self.nullvariant



all the other code is exactly as before and i have put the new listview in the same toolbox page where was the qlistwidget but this works, when i doubleclick in TEST string inside the qlistview i have my function executed so we have any ghost here :)

skuda
8th December 2007, 11:01
ok i have made a small sample with the problem i have with listwidget, the connects prints true (anyway python do an exception if the object or slot names dont exists), this one is the complete code and it doesnt works either.



#!/usr/bin/env python
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class ListWidgetTest(QDialog):
def __init__(self, parent=None):
super(ListWidgetTest, self).__init__(parent)

listWidget = QListWidget()
layout = QVBoxLayout()
layout.addWidget(listWidget)
self.setLayout(layout)

self.connect(listWidget, SIGNAL("itemDoubleClicked(QListWidgetItem)"), self.printTest)
self.connect(listWidget, SIGNAL("itemClicked(QListWidgetItem)"), self.printTest)
self.connect(listWidget, SIGNAL("itemActivated(QListWidgetItem)"), self.printTest)
item = QListWidgetItem(self.tr("TESTING SIGNALS"))
item.setData(Qt.UserRole, QVariant(1))
listWidget.insertItem(0, item)

def printTest(self, item):
print "ok!!"


if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
dialog = ListWidgetTest()
dialog.show()
app.exec_()

skuda
8th December 2007, 12:27
well i have found the solution, like ever you have reason wysota, the problem was in the connect method. They should be SIGNAL("itemDoubleClicked(QListWidgetItem *)") because of this was not working grrrrr. Many thanks.

wysota
8th December 2007, 13:54
Hmm... in that case connect() should have returned false...

skuda
8th December 2007, 14:42
but returned true, if in c++ it doesnt do should be a PyQt problem, i dont know

infernal211283
28th October 2009, 15:42
Thanks, helped me with my task :)