QT6中自定义信号使用注意类型强转

150 阅读1分钟

背景: 开发需要当有鼠标经过QPushButton时,能够触发一个事件,去做一件事

如下自定义HoverButton的类,继承QPushButton,通过enterEvent时发出信号mouseHovered,

    //connect(pbt, &HoverButton::mouseHovered, this, &Widget::Calcarea);

但是使用过程中,connect时发生报错: widget.cpp:38:5: No matching member function for call to 'connect' qobject.h:207:36: candidate function not viable: no known conversion from 'void (HoverButton::*)(bool)' to 'const char *' for 2nd argument qobject.h:210:36: candidate function not viable: no known conversion from 'void (HoverButton::*)(bool)' to 'const QMetaMethod' for 2nd argument qobject.h:228:9: candidate function [with Func1 = void (HoverButton::*)(bool), Func2 = void (Widget::*)()] not viable: cannot convert from base class pointer 'QPushButton *' to derived class pointer 'const typename QtPrivate::FunctionPointer<void (HoverButton::*)(bool)>::Object *' (aka 'const HoverButton *') for 1st argument qobject.h:403:41: candidate function not viable: no known conversion from 'void (HoverButton::*)(bool)' to 'const char *' for 2nd argument qobject.h:277:9: candidate function template not viable: requires 3 arguments, but 4 were provided

  • 问题分析
    错误日志指出无法将QPushButton*转换为HoverButton*,这表明:

    • HoverButton可能是QPushButton的派生类,但在connect调用中未正确限定类型。
    • 信号或槽的发送者/接收者指针类型与实际类不匹配。
  • 解决方案

    • 明确类型转换:使用static_cast显式转换指针类型(需确保类型安全):

      cpp

      connect(static_cast<HoverButton*>(button), &HoverButton::clicked, this, &Widget::onClick);
      
    • 检查类定义:确认HoverButton继承自QPushButton且信号已正确声明。

源码参考

include "hoverbutton.h"

HoverButton::HoverButton(QWidget *parent)
    : QPushButton(parent) {
    // 可在此初始化按钮样式
}

void HoverButton::enterEvent(QEnterEvent *event) {
    QPushButton::enterEvent(event);  // 先调用基类实现
    emit mouseHovered();  // 触发自定义信号
}
#ifndef HOVERBUTTON_H
#define HOVERBUTTON_H
#include <QPushButton>
#include <QEnterEvent>

class HoverButton : public QPushButton {
    Q_OBJECT  // 必须包含Q_OBJECT宏以支持信号槽
public:
    explicit HoverButton(QWidget *parent = nullptr);  // 构造函数声明

signals:
    void mouseHovered(bool checked = false);  // 自定义悬停信号

protected:
    void enterEvent(QEnterEvent *event) override;  // 重写鼠标进入事件
};
#endif // HOVERBUTTON_H