Files
QTradeProgram/Sqbase/qlogviewer.cpp

228 lines
7.3 KiB
C++
Raw Permalink Normal View History

2025-08-15 15:56:40 +08:00
#include "qlogviewer.h"
#include <QDateTime>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QScrollBar>
QLogViewer::QLogViewer(QWidget *parent) : QWidget(parent)
{
// 创建主布局
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(5, 5, 5, 5);
// 创建工具栏
QHBoxLayout* toolbarLayout = new QHBoxLayout;
toolbarLayout->setSpacing(10);
// 日志级别过滤器
QLabel* levelLabel = new QLabel("Log Level:");
levelLabel->setStyleSheet("color: #000;");
levelCombo = new QComboBox;
levelCombo->setStyleSheet("background-color: #333; color: #EEE;");
levelCombo->addItem("All", QVariant(-1));
levelCombo->addItem("DEBUG", QLogManager::LogLevel::SQ_DEBUG);
levelCombo->addItem("INFO", QLogManager::LogLevel::SQ_INFO);
levelCombo->addItem("WARNING", QLogManager::LogLevel::SQ_WARNING);
levelCombo->addItem("ERROR", QLogManager::LogLevel::SQ_ERROR);
levelCombo->addItem("FATAL", QLogManager::LogLevel::SQ_FATAL);
levelCombo->setCurrentIndex(2); // 默认显示INFO及以上
// 搜索框
QLabel* searchLabel = new QLabel("Search:");
searchLabel->setStyleSheet("color: #000;");
searchEdit = new QLineEdit;
searchEdit->setStyleSheet("background-color: #333; color: #EEE;");
searchEdit->setPlaceholderText("Filter logs...");
// 控制按钮
clearBtn = new QPushButton("Clear Logs");
clearBtn->setStyleSheet("background-color: #444; color: #EEE;");
saveBtn = new QPushButton("Save Logs");
saveBtn->setStyleSheet("background-color: #444; color: #EEE;");
//// 添加工具栏组件
//toolbarLayout->addWidget(levelLabel);
//toolbarLayout->addWidget(levelCombo);
//toolbarLayout->addSpacing(10);
//toolbarLayout->addWidget(searchLabel);
//toolbarLayout->addWidget(searchEdit);
//toolbarLayout->addStretch();
//toolbarLayout->addWidget(clearBtn);
//toolbarLayout->addWidget(saveBtn);
// 日志显示区域
logText = new QTextEdit;
logText->setReadOnly(true);
logText->setFontFamily("Consolas");
logText->setFontPointSize(9);
logText->setStyleSheet(R"(
QTextEdit {
background-color: #222;
color: #CCC;
border: 1px solid #444;
border-radius: 2px;
}
)");
// 连接信号
connect(levelCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &QLogViewer::filterLogs);
connect(searchEdit, &QLineEdit::textChanged,
this, &QLogViewer::filterLogs);
connect(clearBtn, &QPushButton::clicked, this, [this](){
logCache.clear();
logText->clear();
});
connect(saveBtn, &QPushButton::clicked,
this, &QLogViewer::saveLogs);
// 添加到主布局
layout->addLayout(toolbarLayout);
layout->addWidget(logText);
// 连接到日志管理器
2026-02-25 23:00:16 +08:00
QLogManager* logManager = QLogManager::Instance();
2025-08-15 15:56:40 +08:00
connect(logManager, &QLogManager::newLog,
this, &QLogViewer::appendLog);
}
void QLogViewer::appendLog(QLogManager::LogLevel level, const QString& logLine)
{
// 添加到缓存
logCache.append(qMakePair(level, logLine));
// 应用当前过滤
applyFilter();
// 自动滚动到底部
QScrollBar* scrollbar = logText->verticalScrollBar();
scrollbar->setValue(scrollbar->maximum());
}
void QLogViewer::filterLogs()
{
// 保存滚动位置
QScrollBar* scrollbar = logText->verticalScrollBar();
int scrollPos = scrollbar->value();
double scrollRatio = scrollPos / (double)scrollbar->maximum();
// 重新应用过滤
logText->clear();
applyFilter();
// 恢复滚动位置
if (scrollbar->maximum() > 0) {
scrollbar->setValue(scrollbar->maximum() * scrollRatio);
}
}
void QLogViewer::applyFilter()
{
int levelFilter = levelCombo->currentData().toInt();
QString searchText = searchEdit->text().toLower();
// 记录当前选中的文本,显示指定等级
QString selectedText = logText->textCursor().selectedText();
// 清空原来数据
logText->clear();
// 过滤并显示日志
for (const auto& log : logCache) {
QLogManager::LogLevel level = log.first;
const QString& logLine = log.second;
// 过滤日志级别,过滤掉低于指定等级的缺陷
if (levelFilter != -1 && (int)level < levelFilter) {
continue;
}
// 过滤搜索文本
if (!searchText.isEmpty() && !logLine.toLower().contains(searchText)) {
continue;
}
// 格式化并添加日志行
QString formattedLog;
switch (level) {
case QLogManager::LogLevel::SQ_DEBUG: formattedLog = "<span style='color:#88AACC'>" + logLine + "</span>"; break;
case QLogManager::LogLevel::SQ_INFO: formattedLog = "<span style='color:#CCCCCC'>" + logLine + "</span>"; break;
case QLogManager::LogLevel::SQ_WARNING: formattedLog = "<span style='color:#FFAA55'>" + logLine + "</span>"; break;
case QLogManager::LogLevel::SQ_ERROR: formattedLog = "<span style='color:#FF5555'>" + logLine + "</span>"; break;
case QLogManager::LogLevel::SQ_FATAL: formattedLog = "<span style='color:#FF3333; font-weight:bold'>" + logLine + "</span>"; break;
}
logText->append(formattedLog);
}
// 恢复选中的文本(如果可能)
if (!selectedText.isEmpty()) {
QTextCursor cursor = logText->textCursor();
cursor.movePosition(QTextCursor::Start);
if (cursor.document()->find(selectedText, cursor).isNull()) {
// 如果选中文本不再存在,清除选中
cursor.clearSelection();
logText->setTextCursor(cursor);
}
}
}
void QLogViewer::saveLogs()
{
// 弹出保存对话框
QString fileName = QFileDialog::getSaveFileName(
this,
"Save Logs",
QString("quant_logs_%1.txt")
.arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")),
"Text Files (*.txt);;All Files (*)"
);
if (fileName.isEmpty()) {
return;
}
// 写入文件
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
// 写入文件头
out << "Quant Trading System Logs\n";
out << "Generated: " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n";
out << "========================================\n\n";
// 写入所有日志行
for (const auto& log : logCache) {
out << log.second << "\n";
}
file.close();
// 记录保存事件
2026-02-25 23:00:16 +08:00
QLogManager::Instance()->log(
2025-08-15 15:56:40 +08:00
QLogManager::LogLevel::SQ_INFO,
QString("Logs saved to: %1 (%2 entries)")
.arg(fileName)
.arg(logCache.size())
);
// 在界面显示成功消息
logText->append("<span style='color:#55FF55'>Logs saved successfully</span>");
} else {
// 记录错误
2026-02-25 23:00:16 +08:00
QLogManager::Instance()->log(
2025-08-15 15:56:40 +08:00
QLogManager::LogLevel::SQ_ERROR,
QString("Failed to save logs: %1").arg(file.errorString())
);
// 在界面显示错误
logText->append("<span style='color:#FF5555'>Failed to save logs: " + file.errorString() + "</span>");
}
}