关于QLineEdit 添加的QAction图标的交互问题

如上图,我们创建了一个搜索栏,添加了一个带有图标的动作,然后你可能会想将鼠标移动 到这个图标上面时让这个图标变色, 首先,我需要回忆一下Qt的信号和槽机制。++QAction有hovered信号,但可能没有直接的"离开"信号++。也就是说,当鼠标进入动作时会触发hovered。给出如下代码:

cpp 复制代码
 连接 hovered 信号
    connect(searchAction, &QAction::hovered, this, [=]() {
    
        searchAction->setIcon(QIcon(":/Res/menuIcon/search-blue.svg")); // 设置为手形指针
    
     });

在代码中,用户连接了hovered信号,当鼠标悬停在动作上时,图标变成蓝色。刚开始可能会以为成功了,实则不然。在鼠标移出该图标时,图标仍然为蓝色。。。该怎么办呢?

这时候可能需要用到QWidget的enterEvent和leaveEvent,或者考虑使用事件过滤器来捕捉鼠标的进入和离开事件。

不过,QAction本身并不是QWidget的子类 ,所以不能直接处理鼠标事件。那怎么办呢?可能应该查找与QAction相关联的控件,比如QToolButton,因为QLineEdit添加的QAction通常会有一个内部的QToolButton来实现显示。

当将QAction添加到QLineEdit时,QLineEdit会为这个动作创建一个QToolButton作为它的子控件。这时候可以尝试获取这个按钮,然后监听它的enter和leave事件,或者使用样式表来改变图标的状态。

或者,考虑使用事件过滤器,监控QLineEdit的QAction的位置,当鼠标移动到该区域之外时,恢复图标。但这样可能比较复杂。

另一个思路是,当鼠标进入QAction时改变图标,当离开时恢复。但QAction本身可能不提供离开的信号,所以可能需要通过事件过滤器来监听鼠标离开事件。

具体步骤可能是这样的:首先,获取QAction对应的widget,也就是那个按钮。可以通过QLineEdit的findChild方法查找QToolButton,或者遍历子控件。找到对应的QToolButton之后,安装事件过滤器到该按钮,然后在事件过滤器中处理鼠标进入和离开的事件,改变图标。

或者,使用样式表来设置不同状态下的图标。例如,设置按钮的hover状态图标为蓝色,普通状态为黑色。这样可能更简单,不需要编写额外的代码。

但用户使用的是QAction的图标,可能样式表的方法需要针对具体的按钮设置。或者,如果QAction的图标设置是通过样式表的话,可能需要调整。不过用户目前是在代码中直接设置图标,所以可能需要另一种方式。

例如,当QToolButton的hover状态改变时,自动切换图标。或者,直接使用QToolButton的setIcon方法,并在事件过滤器中处理enter和leave事件。

所以,可能的解决方案是:

  1. 获取QAction对应的QToolButton

    使用findChildren遍历QLineEdit的子控件,找到关联的QToolButton。

  2. 安装事件过滤器

    监听按钮的鼠标进入和离开事件。

  3. 处理事件切换图标

    在事件过滤器中根据事件类型切换图标。

那具体如何实现呢?代码入下:

cpp 复制代码
// 搜索栏设置
ui->search_lineEdit->setPlaceholderText(QStringLiteral("搜索"));
ui->search_lineEdit->setFixedWidth(200); // 使用 fixedWidth 正确设置宽度

// 创建动作并设置图标
const auto searchAction = new QAction(QIcon(":/Res/menuIcon/search-black.svg"), "搜索", ui->search_lineEdit);
ui->search_lineEdit->addAction(searchAction, QLineEdit::TrailingPosition);

// 获取关联的QToolButton
QToolButton* searchButton = nullptr;
foreach (QToolButton* btn, ui->search_lineEdit->findChildren<QToolButton*>()) {
    if (btn->defaultAction() == searchAction) {
        searchButton = btn;
        break;
    }
}

// 安装事件过滤器
if (searchButton) {
    searchButton->installEventFilter(this);
}

// 在类头文件中声明 eventFilter 函数
// protected:
//     bool eventFilter(QObject *watched, QEvent *event) override;

// 实现事件过滤器
bool YourClass::eventFilter(QObject* watched, QEvent* event) {
    QToolButton* button = qobject_cast<QToolButton*>(watched);
    if (button && button->defaultAction() == searchAction) {
        if (event->type() == QEvent::Enter) {
            searchAction->setIcon(QIcon(":/Res/menuIcon/search-blue.svg"));
        } else if (event->type() == QEvent::Leave) {
            searchAction->setIcon(QIcon(":/Res/menuIcon/search-black.svg"));
        }
    }
    return QObject::eventFilter(watched, event);
}

代码解释

  • 使用findChildren查找QLineEdit中所有QToolButton,通过比较defaultAction确认目标按钮。

  • 通过事件过滤器监听按钮的QEvent::Enter(鼠标进入)和QEvent::Leave(鼠标离开)事件。

  • 在事件处理中切换图标,实现悬停变色效果。

这样即可在鼠标移入时显示蓝色图标,移出时恢复黑色图标。

相关推荐
QT 小鲜肉4 小时前
【个人成长笔记】Qt 中 SkipEmptyParts 编译错误解决方案及版本兼容性指南
数据库·c++·笔记·qt·学习·学习方法
OneSea4 小时前
Debian编译Qt5
linux·qt
看到我,请让我去学习4 小时前
Qt 控件 QSS 样式大全(通用属性篇)
开发语言·c++·qt
曦樂~10 小时前
【Qt】信号与槽(Signal and Slot)- 简易计算器
开发语言·数据库·qt
十五年专注C++开发10 小时前
QDarkStyleSheet: 一个Qt应用的暗色主题解决方案
开发语言·c++·qt·qss
Algebraaaaa1 天前
什么是前端、后端与全栈开发,Qt属于什么?
开发语言·前端·qt
大美B端工场-B端系统美颜师1 天前
工控软件开发选择难?Electron、Qt、WPF 对比
qt·electron·wpf
QT 小鲜肉1 天前
【个人成长笔记】Qt Creator快捷键终极指南:从入门到精通
开发语言·c++·笔记·qt·学习·学习方法
feiyangqingyun1 天前
Qt项目作品在苹果macos上编译运行效果/视频监控系统/物联网平台等
开发语言·qt·macos
fsnine1 天前
Python图形化界面——pyqt5教程
开发语言·python·qt