QT 在静态函数中发送信号

        今天在使用QT官方提供的函数qInstallMessageHandler输出日志时,因为这个函数的参数需要传的是一个函数,当这个函数是成员函数的时候需要是一个静态函数。但同时当我又需要在这个静态函数中发送消息,这时候就出现问题了,在静态函数中发送信号,会报错:非静态成员函数的非法调用。

        但同时我们的信号又不能被声明为静态的,这时候我们就需要在静态函数中发送信号,我这里使用的方法就是新建一个类,用静态函数发送信号,用新建的类接收,然后再将这个信号发送出去。

        虽然信号不能被声明为静态的,但是类的对象可以是静态的,那我们就可以在静态函数中发射一个静态对象的信号。



代码示例

Tool类中静态函数发送信号,由MainWindow接收

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

// 工具类,用于转发静态信号
class Tool : public QObject
{
    Q_OBJECT
public:
    explicit Tool(QObject *parent = nullptr);
    static void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);

private:
    static Tool *mytool;                                // 定义一个静态ToolA类

signals:
    void SigDeliverMess(QString message);               // 真正发出去的信号
    void SigDeliverMessStatic(QString message);         // 内部信号 用于静态函数调用

private slots:
    void SlotDeliverMessStatic(QString message);        // 内部槽 用于响应内部信号
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void ShowDebugContent(const QString &text);

private:
    Ui::MainWindow *ui;
    Tool *m_tool;
};
#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_tool = new Tool();
    connect(m_tool,&Tool::SigDeliverMess, this, &MainWindow::ShowDebugContent);
    qInstallMessageHandler(m_tool->myMessageOutput);
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_tool;
}

void MainWindow::on_pushButton_clicked()
{
    qDebug() << "hahaha";
}

void MainWindow::ShowDebugContent(const QString &text)
{
    ui->textEdit->append(text);
}

Tool *Tool::mytool = nullptr;               // 类外初始化静态Tool类 mytool

Tool::Tool(QObject *parent) : QObject(parent)
{
    mytool = this;
    connect(this,&Tool::SigDeliverMessStatic,this,&Tool::SlotDeliverMessStatic);    // 关联内部信号与槽
}

void Tool::SlotDeliverMessStatic(QString message)
{
    emit mytool->SigDeliverMess(message);   // 发射出去信号
}

void Tool::myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    switch (type) {
    case QtDebugMsg:
        fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtInfoMsg:
        fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtWarningMsg:
        fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtCriticalMsg:
        fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtFatalMsg:
        fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        abort();
    }

    QString message = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + "\r\n";
    message.append(localMsg);
    emit mytool->SigDeliverMessStatic(message);
}

猜你喜欢

转载自blog.csdn.net/Sakuya__/article/details/127787754