Bokambo
Bokambo

Reputation: 4480

Adding Custom Widget to QListWidget in QT click issue in QT?

I am adding custom widget to QListWidget. My Custom Widget contains 2 Labels, 1 Button
/* My Custom Widget

UserDetails *myItem = new UserDetails(0,"  ALOA, Jeon");
UserDetails *myItem1 = new UserDetails(0,"  LOUIS, Stacy");
QListWidgetItem *item = new QListWidgetItem();
QListWidgetItem *item1 = new QListWidgetItem();
item->setSizeHint(QSize(0,45));
item1->setSizeHint(QSize(0,45));
ui->listWidget->addItem(item);
ui->listWidget->addItem(item1);
ui->listWidget->setItemWidget(item,myItem);
ui->listWidget->setItemWidget(item1,myItem1);

Using above Code I am adding mu Custom Widget item to QListWidget. Now the problem is I am using One QPushButton in my CustomWidget now when i click on ListWidgetItem in ListWidget that button i want to change pressed state to some background-image and on release it should come back to normal state.For that I using stylesheet to do so but when i click on button it does not get click event of the List Widget (itemclicked SLOT of List) on double click it gets.

How to get on single click ?

Upvotes: 1

Views: 7470

Answers (1)

pnezis
pnezis

Reputation: 12331

This is not that simple, however it is doable. The problem is that when you click on the button the press event is not propagated to the list widget. So you have to find a way to propagate the signal back to the list widget.

When the button is pressed the pressed signal is emitted. When it is released the released signal is emitted. I will show you how to do it for one of them, you should do the same for the other.

The most straight forward way to do what you want is to add a connection between the pressed signal of the button and the slot which will modify the background of your list. What you have is a QListWidget in which there are some UserDetails widgets each of which has a QPushButton. So we have to go all the way up from the QPushButton to the QListWidget.

In your UserDetails class create a new signal, eg buttonPressed() and connect your button's pressed() signal with it. This way every time the button is clicked in your widget the widget itself will notify the world that its button has been clicked.

connect(ui->button, SIGNAL(pressed()), this, SIGNAL(buttonPressed())

Now we want to notify the QListWidget that the button has been pressed. In order to achieve this we have to connect the buttonPressed signal from the UserDetails with a slot, let's call the slot buttonPressedSlot()

connect(myItem, SIGNAL(pressed()), this, SLOT(buttonPressedSlot())

Now the slot should detect which is the sender (since all UserDetails objects will get connected to the same slot, find the corresponding QListWidgetItem and call the slot that will update the background of this item.

void LiwstWidgetClick::buttonPressedSlot()
{
  QObject* signalSender = QObject::sender();

  UserDetails* p = qobject_cast<UserDetails *>(signalSender);

      if (p == NULL)
         return;

  // Get Position in list widget
  for (unsigned i=0; i<ui->listWidget->count(); i++)
  {
    QListWidgetItem* item = ui->listWidget->item(i);
    if (ui->listWidget->itemWidget(item) == p)
        cellClicked(item); // THIS IS YOUR FUNCTION THAT CHANGES THE
                                       // BACKGROUND OF THE GIVEN ITEM
  }
}

You should do the same for the released() signal.

EDIT

If the button was public you could avoid the extra signal, eg if you had a function (getButton()) in your UserDetails that returned the ui->button you could have just one connection

connect(myItem->button(), SIGNAL(pressed()), this, SLOT(buttonPressedSlot()));

EDIT 2

If you just want to change the background of you button when it is pressed then you can achieve it using stylesheets. You need to entries in your stylesheet one for the normal button state and one for the pressed state. For a list of available states have a look here. Sample code follows

    QListView QPushButton {
         color: grey;
         border-image: url(/path/to/image1) 3 10 3 10;
     }

     QListView  QPushButton:pressed {
         color: red;
         border-image: url(/path/to/image2) 3 10 3 10;
     }

Notice that I use the QListView Descendant Selector in order to get only these QPushButtons that are children of a QListView

Upvotes: 3

Related Questions