当前位置: 首页 > article >正文

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

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

 连接 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. 处理事件切换图标
    在事件过滤器中根据事件类型切换图标。

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

// 搜索栏设置
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(鼠标离开)事件。

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

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


http://www.kler.cn/a/519870.html

相关文章:

  • 使用Python和Qt6创建GUI应用程序---GUI的一个非常简短的历史
  • 剥离情绪的内耗
  • 【Linux】IPC:匿名管道、命名管道、共享内存
  • 每日一题 427. 建立四叉树
  • 《探秘:人工智能如何为鸿蒙Next元宇宙网络传输与延迟问题破局》
  • SYN Flooding的攻击原理
  • 常见的 Spring 项目目录结构
  • 前端面试策略+项目梳理+项目经验阐述
  • Redis 消息队列详解
  • 亚博microros小车-原生ubuntu支持系列:12 URDF 模型
  • mysql如何修改密码
  • Unity开发一个单人FPS游戏的教程总结
  • 美创科技获浙江省网络空间安全协会年度表彰
  • Linux 中的poll、select和epoll有什么区别?
  • 【学习笔记】计算机网络(二)
  • 第29章 xUnit框架下的测试模式详解
  • 1、云计算
  • 什么是区块链
  • 单链表算法实战:解锁数据结构核心谜题——链表的回文结构
  • Leecode刷题C语言之完成所有交易的初始最少钱数
  • Rust 中的结构体使用指南
  • 積分方程與簡單的泛函分析8.具連續對稱核的非齊次第II類弗雷德霍姆積分算子方程
  • 【矩阵二分】力扣378. 有序矩阵中第 K 小的元素
  • 10 Hyperledger Fabric 介绍
  • 个性化的语言模型构建思路
  • 洛谷 P5709:Apples Prologue / 苹果和虫子