#include #include #include #include #include #include #include #include using namespace std; #include #include #include #include #include class QtTextSink : public QObject, public spdlog::sinks::base_sink { Q_OBJECT public: // 构造函数接收一个 QTextEdit*,但用 QPointer 来包装它 explicit QtTextSink(QTextEdit* textEdit, QObject* parent = nullptr) : QObject(parent), textEdit(textEdit) { } signals: // 定义一个信号,用于在主线程中追加文本 void appendText(const QString& message); protected: // 重写 sink_it_ 方法,处理每条日志 void sink_it_(const spdlog::details::log_msg& msg) override { if (textEdit.isNull()) { // 如果 QTextEdit 已经被删除,则忽略这条日志 return; } spdlog::memory_buf_t formatted; formatter_->format(msg, formatted); QString logMessage = QString::fromStdString(fmt::to_string(formatted)); // 发射信号,通过Qt的事件循环在主线程中安全地更新UI emit appendText(logMessage); } void flush_() override {} private: QPointer textEdit; // 关键:使用 QPointer }; class LabelPair { public: LabelPair(QWidget* parent, int x, int y, int w, int h) { title.setParent(parent); value.setParent(&title); title.setGeometry(x, y, w, h); value.setGeometry(80, 0, w-80, h); title.show(); value.show(); } void setTitle(std::string text) { title.setText(text.c_str()); } void setValue(std::string text) { value.setText(text.c_str()); } QLabel title; QLabel value; }; class MyWorkspace; class MainApp : public QWidget { Q_OBJECT public: MainApp(); void setMyLayout(); private slots: void onTimer(); public: struct { std::shared_ptr weburl {}; std::shared_ptr workspace; } ui; struct { std::shared_ptr main; } layout; std::shared_ptr timer; };