【问题标题】:Adding Custom Widget to QListWidget in QT click issue in QT?在 QT 中的 QT 点击问题中添加自定义小部件到 QListWidget?
【发布时间】:2011-12-25 05:15:14
【问题描述】:

我正在向 QListWidget 添加自定义小部件。 我的自定义小部件包含 2 个标签、1 个按钮
/* 我的自定义小部件

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);

使用上面的代码,我将 mu Custom Widget 项添加到 QListWidget。 现在的问题是我现在在我的 CustomWidget 中使用一个 QPushButton,当我单击 ListWidget 中的 ListWidgetItem 该按钮时,我想将按下状态更改为某个背景图像,并且在释放时它应该恢复正常状态。为此,我使用样式表来这样做但是当我单击按钮时,它不会在双击时获得列表小部件的单击事件(列表的 itemclicked SLOT)。

如何点击一下?

【问题讨论】:

  • 当我之前在 QTreeWidget 中做过类似的事情时,我不必对 itemClicked() 做任何事情。我只需要将按钮连接到任何东西,QTreeWidget 会自行将点击事件向下传播到按钮。
  • 你应该使用模型-视图-委托

标签: qt


【解决方案1】:

这不是那么简单,但它是可行的。问题是当您单击按钮时,按下事件不会传播到列表小部件。因此,您必须找到一种方法将信号传播回列表小部件。

按下按钮时,会发出pressed 信号。当它被释放时,released 信号被发射。我会告诉你如何为其中一个做,你应该为另一个做同样的事情。

最直接的方法是在按钮的pressed 信号和将修改列表背景的插槽之间添加一个连接。你所拥有的是一个QListWidget,其中有一些UserDetails 小部件,每个小部件都有一个QPushButton。所以我们必须从QPushButton 一直向上到QListWidget

在您的UserDetails 类中创建一个新信号,例如buttonPressed() 并将您的按钮的pressed() 信号与其连接。这样,每次在您的小部件中单击按钮时,小部件本身都会通知世界其按钮已被单击。

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

现在我们要通知QListWidget 该按钮已被按下。为了实现这一点,我们必须将来自UserDetailsbuttonPressed 信号与一个插槽连接,我们将插槽称为buttonPressedSlot()

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

现在槽应该检测哪个是发送者(因为所有UserDetails对象都将连接到同一个槽,找到相应的QListWidgetItem并调用将更新此项目背景的槽。

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
  }
}

您应该对released() 信号执行相同的操作。

编辑

如果按钮是公开的,您可以避免额外的信号,例如,如果您的 UserDetails 中有一个返回 ui-&gt;button 的函数 (getButton()),您可能只有一个连接

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

编辑 2

如果您只想在按下按钮时更改按钮的背景,则可以使用stylesheets 来实现。您需要在样式表中输入一个用于正常按钮状态的条目,一个用于pressed 状态的条目。有关可用状态的列表,请查看here。示例代码如下

    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;
     }

请注意,我使用 QListView Descendant Selector 是为了仅获取属于 QListView 的子级的 QPushButtons

【讨论】:

  • 这里的 myitem 是什么? connect(myItem, SIGNAL(pressed()), this, SLOT(buttonPressedSlot()).My ListWidget 在不同的页面,自定义控件在不同的页面。
  • @webcletic :我想更改按钮的背景图像而不是项目,按钮在按下状态时应该有不同的 bgimage 和在释放状态时不同,因为项目没有 setstylesheet 属性来更改 bg图片。
  • 其实上面所有的代码都可以正常工作。我发现的问题是我正在应用一个产生此问题的动力学滚动器(在触摸屏设备的情况下手指滚动),效果在双击而不是在单击按钮的按下状态时应用。
  • 我指的是来自 blog.codeimproved.net/2010/12/… 的动力学 scoller 实现并将其应用到我的 ListWidget。
  • 你知道如何克服这个问题吗?
猜你喜欢
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多