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