点击QComboBox某项无法触发mousePressEvent
时间: 2024-02-02 19:05:27 浏览: 73
如果你发现重写 `QComboBox` 的 `mousePressEvent` 方法后,点击某一项无法触发该方法,可能是因为 `QComboBox` 中默认使用了一个 `QAbstractItemView` 来显示下拉列表,而这个视图会拦截掉 `mousePressEvent` 事件,导致我们自定义的 `mousePressEvent` 方法无法被触发。
为了解决这个问题,我们可以在 `MyComboBox` 类中重写 `showPopup` 和 `hidePopup` 方法,手动设置 `QAbstractItemView` 的鼠标事件过滤器,将事件过滤器改为 `MyComboBox` 实例本身。这样,`QAbstractItemView` 就会将鼠标事件转发给 `MyComboBox` 实例,从而触发我们自定义的 `mousePressEvent` 方法。
下面是修改后的 `MyComboBox` 类的实现代码:
```cpp
class MyComboBox : public QComboBox
{
Q_OBJECT
public:
MyComboBox(QWidget *parent = nullptr);
~MyComboBox();
signals:
void itemClicked(int index);
protected:
void mousePressEvent(QMouseEvent *event);
void showPopup();
void hidePopup();
private:
int findItem(const QPoint &pos);
};
```
```cpp
MyComboBox::MyComboBox(QWidget *parent)
: QComboBox(parent)
{
}
MyComboBox::~MyComboBox()
{
}
void MyComboBox::mousePressEvent(QMouseEvent *event)
{
int index = findItem(event->pos());
if (index != -1) {
emit itemClicked(index);
}
QComboBox::mousePressEvent(event);
}
void MyComboBox::showPopup()
{
QComboBox::showPopup();
QAbstractItemView *view = this->view();
view->installEventFilter(this);
}
void MyComboBox::hidePopup()
{
QComboBox::hidePopup();
QAbstractItemView *view = this->view();
view->removeEventFilter(this);
}
int MyComboBox::findItem(const QPoint &pos)
{
QStyleOptionComboBox option;
initStyleOption(&option);
const QRect rect = style()->subControlRect(QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, this);
QAbstractItemView *view = this->view();
for (int i = 0; i < view->model()->rowCount(); ++i) {
QRect itemRect = view->visualRect(view->model()->index(i, 0));
itemRect.translate(rect.topLeft());
if (itemRect.contains(pos)) {
return i;
}
}
return -1;
}
```
在上面的代码中,我们重写了 `showPopup` 和 `hidePopup` 方法,分别在下拉列表显示和隐藏时,设置 `QAbstractItemView` 的事件过滤器为 `MyComboBox` 实例本身。这样,我们就可以正常触发自定义的 `mousePressEvent` 方法了。
阅读全文