gpt4 book ai didi

c++ - 如果安装在单独的类上,Qt 消息处理程序会崩溃吗?

转载 作者:行者123 更新时间:2023-11-28 02:13:56 24 4
gpt4 key购买 nike

每当有消息发送到我的自定义消息处理程序时,它就会通过段错误导致标记行处的应用程序崩溃。

// main.cpp

void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QStringList data;
data.append(context.category);
data.append(context.file);
data.append(context.function);
data.append(QString(context.line));
data.append(QString(context.version));
Logger::get_obj()->myMessageOutput(type, data, msg);
}

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setApplicationName("MyApp");
a.setWindowIcon(QIcon(":/Icons/MyApp.png"));

Logger log;
qInstallMessageHandler(myMessageOutput);
log.turnOnDebug();

MySplashScreen splash;
splash.show();
a.processEvents();

...

splash.close();
MainWindow *w = new MainWindow();

int errorCode = a.exec();
delete w;
session.destruct();
qDebug() << "\n*** Application exited with error code " << errorCode << " ***";
return errorCode;
}
// logger.h

#ifndef LOGGER_H
#define LOGGER_H

#include <QObject>
#include <QFile>
#include <QTextStream>
#include <QMutex>

class Logger : public QObject
{
Q_OBJECT
public:
void myMessageOutput(QtMsgType type, QStringList context, const QString msg);
explicit Logger(QObject *parent = 0);
~Logger();
static Logger *get_obj() {return ptr;}
static void turnOnDebug() {get_obj()->debugMode = true;}
static void turnOffDebug() {get_obj()->debugMode = false;}
static void moveLogToSession(QString sessionName);

private:
QFile *logFile;
QTextStream *stream;
QMutex *mutex;
bool debugMode;
bool errorMsg;
static Logger *ptr;

void write(QString str);

signals:
void SaveSession();
void FatalSaveSession();

public slots:

};

#endif // LOGGER_H
// logger.cpp

#include <QDir>
#include <QFile>
#include <QMessageBox>
#include <QApplication>
#include "logger.h"
#include "systemvariables.h"

Logger *Logger::ptr = NULL;

Logger::Logger(QObject *parent) : QObject(parent)
{
logFile = NULL;
stream = NULL;
mutex = NULL;
debugMode = false;
errorMsg = false;

ptr = this;
QString path = SystemVariables::getAppData();
QDir dir = QDir(path);
if(dir.exists())
{
path.append("/MyApp/Logs");
dir = QDir(path);
if(!dir.exists())
dir.mkpath(path);

logFile = new QFile(path + "/Session.log");
if(logFile->exists())
logFile->remove();

if(!logFile->open(QFile::WriteOnly | QFile::Text))
{
qFatal("Could not create log file.");
}

stream = new QTextStream(logFile);
stream->setRealNumberNotation(QTextStream::SmartNotation);
stream->setRealNumberPrecision(15);
*stream << "*** MyApp Session Begins ***\n";
}
else
qFatal("Could not create log file.");

mutex = new QMutex();
}

void Logger::myMessageOutput(QtMsgType type, QStringList context, const QString msg)
{
mutex->lock();
QString str = "";
switch (type)
{
case QtDebugMsg:
if(!debugMode)
{
mutex->unlock();
return;
}
write(msg);
break;

case QtInfoMsg:
str.append("\n*** Information ***\n");
str.append(msg + "\n");
str.append("Category: " + context.at(0) + "\n");
str.append("File: " + context.at(1) + "\n");
str.append("Function: " + context.at(2) + "\n");
str.append("Line: " + context.at(3) + "\n");
str.append("Version: " + context.at(4));
str.append("\n*** Information Complete ***\n");
write(str);
break;

case QtWarningMsg:
if(!(context.at(2).contains("setGeometry")))
{
str.append("\n*** Warning ***\n");
...
str.append("\n*** Warning Complete ***\n");
write(str);
errorMsg = true;
emit Logger::ptr->SaveSession();
}
break;

case QtCriticalMsg:
str.append("\n*** Critical ***\n");
...
str.append("\n*** Critical Complete ***\n");
write(str);
errorMsg = true;
emit Logger::ptr->SaveSession();
break;

case QtFatalMsg:
str.append("\n*** Fatal ***\n");
...
str.append("\n*** Fatal Complete ***\n");
write(str);
errorMsg = false;
emit Logger::ptr->FatalSaveSession();
QApplication::exit(-2);
}
Logger::mutex->unlock();
}

void Logger::write(QString str)
{
if(!stream)
return;

if(str.isEmpty())
return;

(*stream) << str; //!!!!!!!!!!!!CRASHES HERE***********
stream->flush();
}

void Logger::moveLogToSession(QString sessionName)
{
QMutex *myMutex = get_obj()->mutex;
myMutex->lock();

QTextStream *myStream = get_obj()->stream;
myStream->flush();
QFile *myLogFile = get_obj()->logFile;
myLogFile->flush();
myLogFile->close();
delete myStream;

QString path = SystemVariables::getAppData() + "/Smovault/Logs";
if(!myLogFile->open(QFile::ReadOnly | QFile::Text))
{
QString errtitle = "FATAL ERROR!";
QString errtxt = myLogFile->errorString() + "\nCould not open the log file: ";
errtxt.append(path + "/Session.log");
errtxt.append(".\nApplication Abort!");
QMessageBox *mb = new QMessageBox(QMessageBox::Critical, errtitle, errtxt);
mb->exec();
delete mb;
QApplication::exit(-1);
}
QTextStream in(myLogFile);
QString data = in.readAll();
myLogFile->close();
myLogFile->remove();
delete myLogFile;

path = SystemVariables::getAppData() + "/Smovault/Sessions/" + sessionName;
myLogFile = new QFile(path + "/Session.log");
if(!myLogFile->open(QFile::WriteOnly | QFile::Text))
{
QString errtitle = "FATAL ERROR!";
QString errtxt = myLogFile->errorString() + "\nCould not write to the log file: ";
errtxt.append(path + "/Session.log");
errtxt.append(".\nApplication Abort!");
QMessageBox *mb = new QMessageBox(QMessageBox::Critical, errtitle, errtxt);
mb->exec();
delete mb;
QApplication::exit(-1);
}
QTextStream out(myLogFile);
out << data;
out.flush();
myLogFile->flush();

myStream = new QTextStream(myLogFile);
myStream->setRealNumberNotation(QTextStream::SmartNotation);
myStream->setRealNumberPrecision(15);

myMutex->unlock();
}

如果有人能帮助我指出我的错误,我将不胜感激。

最佳答案

如果在调用 moveLogToSession 后发生崩溃,我猜这是因为你破坏了流

QTextStream *myStream = get_obj()->stream;
myStream->flush();
...
delete myStream; // here

从不设置新流

myStream = new QTextStream(myLogFile);

get_obj()->stream = myStream; // you need THIS

关于c++ - 如果安装在单独的类上,Qt 消息处理程序会崩溃吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34671245/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com