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());
}
相关推荐
历程里程碑2 小时前
hot 206
java·开发语言·数据结构·c++·python·算法·排序算法
csbysj20203 小时前
菜单(Menu)
开发语言
yong99903 小时前
基于MATLAB的随机振动界面设计与功率谱密度分析实现
开发语言·matlab
超级种码3 小时前
Java:JavaAgent技术(java.instrument和java.attach)
java·开发语言·python
天天向上10243 小时前
go 配置热更新
开发语言·后端·golang
晨晖24 小时前
顺序查找:c语言
c语言·开发语言·算法
wadesir4 小时前
C++非对称加密实战指南(从零开始掌握RSA加密算法)
开发语言·c++
SunkingYang4 小时前
QT程序怎么接收MFC通过sendmessage发送的信号
qt·mfc·信号·事件·sendmessage·接收消息
SunkingYang4 小时前
Qt中QString 查找子串的完整指南
qt·字符串·qstring·子字符串·查找子串