0

在树小部件中,我连接了以下信号:

  connect(mTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
          SLOT(onItemClicked(QTreeWidgetItem*, int)));

onItemClicked()插槽如下:

void WidgetBox::onItemClicked(QTreeWidgetItem *item, int )
{
  int index = getPageIndex(item);
  setCurrentIndex(index);
}

int WidgetBox::getPageIndex(QTreeWidgetItem *item)
{
  if (!item) return -1;

  QTreeWidgetItem *parent = item->parent();
  if(parent)  // Parent is top level item
  {
    return mTreeWidget->indexOfTopLevelItem(parent);
  }
  else        // Current item is top level
  {
    return item->treeWidget()->indexOfTopLevelItem(item);
  }
}

void WidgetBox::setCurrentIndex(int index)
{
  if (index != currentIndex() && checkIndex(index))
  {
    mTreeWidget->setCurrentItem(mTreeWidget->topLevelItem(index));
    emit currentIndexChanged(index);
  }
}

但是我无法捕获itemClicked()信号并且onItemClicked()从未执行过,因为顶级项目具有拦截鼠标事件的按钮小部件(使用setItemWidget()方法设置),并且子项目包含容器小部件,其中可能包含任何小部件组合。

这里有一个好的方法来itemClicked()为树小部件的顶级和子项调用这个信号吗?

  • installEventFilter() 用于在项目中找到的所有小部件,如下所示
    QList<QWidget *> widgets = parentWidget.findChildren<QWidget *>();
  • 或者以某种方式建立鼠标事件传播
  • QCoreApplication::postEvent()?

如何更好地组织这样的过程,以便所有小部件都根据需要处理鼠标事件以及 TreeWidget 问题SIGNAL(itemClicked())

复制的完整来源:https ://github.com/akontsevich/WidgetBox

4

2 回答 2

0

像这样创建事件过滤器:

class PageEventFilter : public QObject
{
  Q_OBJECT
public:
  PageEventFilter(QObject *parent, QTreeWidgetItem *item);

protected:
  bool eventFilter(QObject *obj, QEvent *event);

private:
  QTreeWidgetItem *mItem;
};

bool PageEventFilter::eventFilter(QObject *obj, QEvent *event)
{
  if (event->type() == QEvent::MouseButtonPress)
  {
    // Emitate mouse event for parent QTreeWidget
    QMouseEvent *oldEvent = (QMouseEvent *)event;
    QRect itemRect = mItem->treeWidget()->visualItemRect(mItem);
    QPointF mousePos(itemRect.x() + 1, itemRect.y() + 1);
    QMouseEvent *newEvent = new QMouseEvent(oldEvent->type(),
                                            mousePos,
                                            oldEvent->button(),
                                            oldEvent->buttons(),
                                            oldEvent->modifiers());
    QCoreApplication::postEvent(mItem->treeWidget(), newEvent);
    return false; // Sent event to the object (do not filter it)
  }
  else
  {
    // standard event processing
    return QObject::eventFilter(obj, event);
  }
}

将其安装到树小部件项目中的按钮。它创建并向树小部件发送(模仿)鼠标事件,但是树小部件仍然不发送 itemClicked(QTreeWidgetItem*, int) 信号。可能是什么问题?鼠标位置不对?试图将事件发送到viewport() - 也没有运气。有什么办法可以解决这个问题?

于 2016-04-23T23:11:50.173 回答
0

所以解决方案很简单并且如下 - 只需重新发送void itemClicked(QTreeWidgetItem *item, int column);信号PageEventFilter

PageEventFilter::PageEventFilter(QObject *parent, QTreeWidgetItem *item)
  : QObject(parent)
  , mItem(item)
{
  connect(this, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
          mItem->treeWidget(), SIGNAL(itemClicked(QTreeWidgetItem*,int)));
}

bool PageEventFilter::eventFilter(QObject *obj, QEvent *event)
{
  if (event->type() == QEvent::MouseButtonPress)
  {
    // Resend signal to QTreeWidget
    emit itemClicked(mItem, 0);
    return false; // Send event to the object (do not filter it)
  }
  else
  {
    // standard event processing
    return QObject::eventFilter(obj, event);
  }
}

PS 如果有人需要代码或想法,也会留下以前的答案。

于 2016-04-24T00:53:34.657 回答