QT中想在QTextEdit控件中使用Qslog日志输出出现问题原因及解决方法

QT中自定义类时使用多重继承问题原因及解决方法

  1. 创建一个名为LogTextEditEx的类继承自QTextEdit和Destination,出现了多重继承的访问权限问题;原因:;class LogTextEditEx : public QTextEdit,Destination{}在Destination前少写了public;继承方式不正确,需要添加public继承,class LogTextEditEx : public QTextEdit,public Destination {};
  2. 在自定义类头文件中 添加Q_OBJECT // 确保有Q_OBJECT宏
  3. error: 'staticMetaObject' is not a member of
    'QsLogging::Destination'
    QMetaObject::SuperData::linkDestination::staticMetaObject(),
    原因:这个错误表明在moc生成的代码中,它试图访问QsLogging::Destination的staticMetaObject,但是Destination类没有这个成员。这是因为Destination可能不是QObject的子类,而我们的LogTextEditEx类试图同时继承QObject和Destination。
    在Qt中,如果一个类要使用信号槽(即包含Q_OBJECT宏),它必须直接或间接继承QObject。而QsLogging::Destination不是一个QObject派生类(它只是一个接口类)。因此,我们不能让一个类同时继承QObject和Destination,然后使用Q_OBJECT宏,因为moc会认为Destination也是一个QObject(但实际上不是)。
    解决方法:最简单的,将QTextEdit继承时放在最前面即可,其它复杂的没试过;
cpp 复制代码
#ifndef LOGTEXTEDITEX_H
#define LOGTEXTEDITEX_H
#include "QsLogDest.h"
#include <QTextEdit>
#include <QMutex>
#include <QObject>
using namespace QsLogging;
class LogTextEditEx : public QTextEdit,public Destination
{
        Q_OBJECT  // 确保有Q_OBJECT宏
public:
    explicit LogTextEditEx(QWidget* parent = nullptr);
    ~LogTextEditEx();
    void write(const QString &message, QsLogging::Level level) override;
    bool isValid() override;

private:
    struct LogMessage {
        QString message;
        int level;
    };
    QList<LogMessage> m_messageBuffer;
    QMutex m_bufferMutex;
    QTimer* m_updateTimer;

    void init();
    void updateTextEdit();
};

#endif // LOGTEXTEDITEX_H
cpp 复制代码
#include "logtexteditex.h"
#include <QScrollBar>
#include <QTimer>
#include <QMutexLocker>
LogTextEditEx::LogTextEditEx(QWidget *parent)
    : QTextEdit(parent)
{
    init();
}
LogTextEditEx::~LogTextEditEx()
{

}
void LogTextEditEx::init()
{
    // 设置为只读
    setReadOnly(true);

    // 设置字体
    QFont font("Consolas", 9);
    setFont(font);

    // 创建定时器,批量更新UI以提高性能
    m_updateTimer = new QTimer(this);
    m_updateTimer->setInterval(100); // 100ms更新一次
    connect(m_updateTimer, &QTimer::timeout,
            this, &LogTextEditEx::updateTextEdit);
    m_updateTimer->start();
}

void LogTextEditEx::write(const QString &message, QsLogging::Level level)
{
    QMutexLocker locker(&m_bufferMutex);
    m_messageBuffer.append({message, static_cast<int>(level)});
}

bool LogTextEditEx::isValid()
{
    return true;
}

void LogTextEditEx::updateTextEdit()
{
    QMutexLocker locker(&m_bufferMutex);
    if (m_messageBuffer.isEmpty())
        return;

    // 批量处理日志消息
    QList<LogMessage> messages = m_messageBuffer;
    m_messageBuffer.clear();
    locker.unlock();

    // 准备HTML内容
    QString html;
    for (const auto& msg : messages) {
        QString color;
        switch (msg.level) {
        case 0: color = "gray"; break;      // Trace
        case 1: color = "blue"; break;      // Debug
        case 2: color = "green"; break;     // Info
        case 3: color = "orange"; break;    // Warn
        case 4: color = "red"; break;       // Error
        case 5: color = "darkred"; break;   // Fatal
        default: color = "black";
        }

        html += QString("<span style='color:%1'>%2</span><br>")
                .arg(color)
                .arg(msg.message.toHtmlEscaped());
    }

    // 更新文本编辑框
    QTextCursor cursor(document());
    cursor.movePosition(QTextCursor::End);
    cursor.insertHtml(html);

    // 限制最大行数
    const int maxLines = 1000;
    int lineCount = document()->lineCount();
    if (lineCount > maxLines) {
        cursor.movePosition(QTextCursor::Start);
        cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor,
                            lineCount - maxLines);
        cursor.removeSelectedText();
    }

    // 自动滚动
    verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
相关推荐
少控科技9 分钟前
QT第6个程序 - 网页内容摘取
开发语言·qt
darkb1rd9 分钟前
八、PHP SAPI与运行环境差异
开发语言·网络安全·php·webshell
历程里程碑12 分钟前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
郝学胜-神的一滴14 分钟前
深入浅出:使用Linux系统函数构建高性能TCP服务器
linux·服务器·开发语言·网络·c++·tcp/ip·程序人生
承渊政道17 分钟前
Linux系统学习【Linux系统的进度条实现、版本控制器git和调试器gdb介绍】
linux·开发语言·笔记·git·学习·gitee
JQLvopkk42 分钟前
C# 轻量级工业温湿度监控系统(含数据库与源码)
开发语言·数据库·c#
玄同7651 小时前
从 0 到 1:用 Python 开发 MCP 工具,让 AI 智能体拥有 “超能力”
开发语言·人工智能·python·agent·ai编程·mcp·trae
czy87874751 小时前
深入了解 C++ 中的 `std::bind` 函数
开发语言·c++
消失的旧时光-19431 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
yq1982043011561 小时前
静思书屋:基于Java Web技术栈构建高性能图书信息平台实践
java·开发语言·前端