1

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 ?

Bokambo
  • 4,204
  • 27
  • 79
  • 130
  • When I've done a similar thing in QTreeWidget before, I have not had to do anything with itemClicked(). I just had to connect the button to whatever, the QTreeWidget propagates the click event down to the button by itself. – cmannett85 Nov 09 '11 at 13:24
  • 1
    You should use Model-View-Delegate – fasked Dec 30 '13 at 10:00

1 Answers1

3

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

eric
  • 7,142
  • 12
  • 72
  • 138
pnezis
  • 12,023
  • 2
  • 38
  • 38
  • What is myitem here ? connect(myItem, SIGNAL(pressed()), this, SLOT(buttonPressedSlot()).My ListWidget is in different page and custom control is different page. – Bokambo Nov 10 '11 at 05:42
  • @webcletic : I want to change the background-image of the button not the item , button should have diffrent bgimage on pressed state & different on release state as Item does not have setstylesheet property to change the bg image. – Bokambo Nov 10 '11 at 06:23
  • Actually all above code works fine . The problem i figured out is that i am applying one kineticscroller(finger scrolling in case of touch screen device) that is giving this problem , effects getting applied on double click not on single click pressed state of button. – Bokambo Nov 10 '11 at 08:53
  • I am referring kinetic scoller implementation from http://blog.codeimproved.net/2010/12/kinetic-scrolling-with-qt-the-what-and-the-how/ and applying it to my ListWidget. – Bokambo Nov 10 '11 at 08:55
  • Do you have any idea how to overcome this problem ? – Bokambo Nov 10 '11 at 12:01