PDA

View Full Version : QListWidget clicked signal



asieriko
8th August 2007, 14:13
Hello,
I want to know if is it possible to know when a QListWidget has been clicked, i can receive the envent when a QListWidgetItem has been clicked, but no when the QListWidget itself has been.

Thank you,


Asier

marcel
8th August 2007, 15:06
Reimplement mousePressEvent() for the widget.
Remember to call QListWidget::mousePressEvent at the end of it, since all item clicked signals are based on it.

Regards

asieriko
8th August 2007, 17:35
Hello, i've tried this, but i get the following error.



class MyListWidget : public QListWidget
{

Q_OBJECT

protected:
void mousePressEvent(QMouseEvent * e)
{
qDebug("mouse press event MyListWidget");
emit clicked(e->pos());
QListWidget::mousePressEvent();
}

public: signals:
void clicked(const QPoint & pos);
};



error: no matching function for call to ‘MyListWidget::mousePressEvent()’

If i remove the line
QListWidget::mousePressEvent();, it works (i get the press events) but this way i can't get the events made to each item of the list, it's also dificult to select the items.

marcel
8th August 2007, 17:43
You forgot to pass the QMOuseEvent parameter for the base class version.
It is:
QListWidget::mousePressEvent(e);

Regards

asieriko
8th August 2007, 19:01
OK, now it works.
But, i want to be able to recieve such signals when this widget is part of a bigger one. At this point i can read the qDebug text, but i can't use it from an external widget. I mean this widget is in a Layout, and there are various of them.

What shoul i do to receive now, this events?

marcel
8th August 2007, 19:14
What do you mean?
Do you want something like a signal?
You can define a clicked() signal in MyListWidget and emit it in mousePressEvent.

Then you can connect this signal wherever you want.
Be careful with what you do in the slot connected to it, though. Don't do anything that will take a long time, since you will block the event for too long.
However, if you do something that takes a long time, then use Qt::QueuedConnection when connecting to clicked(). This way the slot will execute asynchronously.

Regards

asieriko
8th August 2007, 19:44
Here it is my final code:


class MyListWidget : public QListWidget
{
Q_OBJECT
protected:
void mousePressEvent(QMouseEvent * e)
{
qDebug("mouse press event MyListWidget");
emit click();
QListWidget::mousePressEvent(e);
}
public: signals:
void click();
};


Then i've created another widget which includes this one and i've defined another signal to provide the container of the second widget receive it.


class dayCell : public QWidget{
Q_OBJECT
public:
dayCell(QWidget *parent=0, char *name=0 );
~dayCell();
public slots:
void clicked2();
public: signals:
void clock();
private:
MyListWidget *listWidget;
};

and in the cpp


void dayCell::clicked2()
{
emit clock();
}

And now if i use a dayCell widget i can get the clock() signal that comes here since the MyListWidget.

asieriko
10th August 2007, 14:41
Ok,
And now, how can i know what widget have i clicked if they are created in a loop?



for (i=0;i<5;i++){
dayCell *wi = new dayCell();
connect(wi,SIGNAL(clock()),this,SLOT(aclear()));
}

I mean, if i want to add an item or those things. How can i know what wiget is it? i've tried with Object::sender(), but it doesn't work.


void monthView::aclear()
{
qDebug(qPrintable(QObject::sender()->objectName()));
// addItem("a");
}

I don't get any name printed.

Thanks

marcel
10th August 2007, 14:52
Should work.
try:


dayCell *c = qobject_cast<dayCell*>(sender());

Remember that QObject::sender() is not static. it is only protected.

Otherwise try(but as a last solution):
Add a QObject* parameter to the signal:
BTW, remove public: in front of signals:. Signals are always protected, they don't need visibility modifiers/


signals:
void clock(QObject*);


When you emit the signal, pass this as parameter:


void dayCell::clicked2()
{
emit clock(this);
}


And the slot:


for (i=0;i<5;i++)
{
dayCell *wi = new dayCell();
connect(wi,SIGNAL(clock(QObject*)),this,SLOT(aclea r(QObject*)));
}

void monthView::aclear(QObject* o)
{
dayCell *c = qobject_cast<dayCell*>(o);
if(c)
{
//add items, etc
}
}


Regards

asieriko
10th August 2007, 15:59
Thank you, again, marcel.
Now I've a final question. When a QListWidgetItem is clicked, i get 2 signals, one for the item itself (itemClicked), and the other from the whole widget (mousePressEvent). How can I know what of them is it?
Thanks.

marcel
10th August 2007, 16:10
Well, in mousePressEvent, you can use QListWidget::itemAt(const QPoint&) to see if any item is at the click position.
If you have an item there, don't emit the click signal.

So, the list widget should emit a clicked signal only if you click outside any item.
Otherwise you can't figure out what where the signal is coming from.

Another way is to connect to different slots - one for the list widget and one for the items.

Regards

asieriko
10th August 2007, 16:29
Hi,
I've tried

if (QListWidget::itemAt(e->globalPos())) {qDebug("item");}
and

if (this->itemAt(e->globalPos())) {qDebug("item");}
but none of them work.

marcel
10th August 2007, 16:37
Do not use the global position.
Work in widget coordinates, meaning e->pos().

Regards