Поймать событие мыши на элементе виджета дерева в QTreeWidget

В виджете дерева у меня есть следующий сигнал:

  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

2 ответа

Решение

Таким образом, решение простое и следующее - просто отправьте заново 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 Также оставлю предыдущий ответ, если кому-то понадобится код или идея.

Создан фильтр событий, подобный этому:

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 () - тоже не повезло. Любой способ решить это?

Другие вопросы по тегам