Solved Log issues
-
The most common time I run into this error is when I declare a static variable in my header file, but forget to create it in my code. For example, in your code above you have:
static QTextBrowser *textBrowser;
You've probably got that as a member of yourLog
class defined in your .h file, so in your .cpp file, you need:
QTextBrowser *Log::textBrowser;
-
I have changed code in .cpp file (in constructor):
QTextBrowser *Log::textBrowser; textBrowser->installEventFilter(this); connect(textBrowser, &QTextBrowser::textChanged, this, &Log::checkLogTextBrowser);
but I get
error: C2655: 'Log::textBrowser': definition or redeclaration illegal in current scope
? -
The creation of the
QTextBrowser
does not belong in your constructor, it must be a standalone line in your .cpp file. -
Thanks. I have fixed it but when I use
Log::writeToLog("Some data");
in for exampleTest.cpp
, the app crashes.Code:
Log.h
static void writeToLog(QString logMessage);
Log.cpp
void Log::writeToLog(QString logMessage) { textBrowser->append(logMessage); }
The same crash when I open
Log
also exists. Any suggestions? Thanks.Update:
textBrowser->installEventFilter(this);
It crashes on this line:
connect(textBrowser, &QTextBrowser::textChanged, this, &Log::checkLogTextBrowser);
-
Your static variable is probably uninitialized. It looks to me like you are trying to create something like a Singleton -- are you familiar with that design pattern? My guess is that you are trying to call
writeToLog
without first initializing theQTextBrowser
. Remember that by using a static member function you do not have an object to work with, and therefore it's very possible that your class's constructor is never called. -
In fact, nowhere in any of the code you've entered here do you ever actually instantiate a QTextBrowser. Where is your allocation statement (e.g.
textBrowser = new QTextBrowser;
)? -
Thanks. Now it works but the same as it was without
static
, when I useLog::writeToLog("Some data");
to write toQTextBrowser
in for exampleTest
window and close it, then openLog
window to check data,QTextBrowser
is empty.To open
Log
I use:Log *appLog = new Log(this); appLog->show();
-
How/where are you allocating the
QTextBrowser
? -
I have initialized
textBrowser = new QTextBrowser();
in constructor and in function below because constructor is not called when I callLog::writeToLog("Some data")
inTest.cpp
and app crashes.void Log::writeToLog(QString logMessage) { textBrowser = new QTextBrowser(); textBrowser->append(logMessage); }
But the result is the same (
QTextBrowser
is empty), I think because of two initialization. -
Definitely do not make a new QTextBrowser every time you call writeToLog, that defeats the purpose of making it static. You need to instantiate it one time in any given program run. Start by initializing it to null (or Q_NULLPTR), then in writeToLog check to see if it exists already. If it does not, then allocate it and set its parameters as appropriate, so something like:
QTextBrowser *Log::textBrowser = null; ... void Log::writeToLog(QString logMessage) { if (!textBrowser) { textBrowser = new QTextBrowser; textBrowser->installEventFilter(this); connect(textBrowser, &QTextBrowser::textChanged, this, &Log::checkLogTextBrowser); } textBrowser->append(logMessage); }
-
(Note that my example code won't actually work as written because writeToLog is static, so you don't have a "this" pointer... those two lines will need to be in your constructor, along with appropriate checks to create textBrowser there if needed.)
-
Thanks for code example. It now works. One more question, since
Log::writeToLog(QString logMessage)
is astatic
function I can't usethis
, I get error:log.cpp:116: error: C2355: 'this': can only be referenced inside non-static member functions or non-static data member initializers
. So I need to get the instance of theLog
class. Any ideas? -
Yes, remove those two lines from the if statement in writeToLog, but keep them in an identical if statement in your constructor.
-
I have added also check in constructor, because it crashes when open
Log
without adding anything to it.if (!textBrowser) { textBrowser = new QTextBrowser(); textBrowser->installEventFilter(this); connect(textBrowser, &QTextBrowser::textChanged, this, &Log::checkLogTextBrowser); } else { textBrowser->installEventFilter(this); connect(textBrowser, &QTextBrowser::textChanged, this, &Log::checkLogTextBrowser); }
Also I have notices that
connect(textBrowser, &QTextBrowser::textChanged, this, &Log::checkLogTextBrowser);
is not working. I have some buttons which is disabled and when new log data is added, those buttons should be enabled, but it still disabled.void Log::checkLogTextBrowser() { if (textBrowser->document()->isEmpty()) { saveLog->setEnabled(false); saveLogAs->setEnabled(false); openLog->setEnabled(false); clearLog->setEnabled(false); deleteLog->setEnabled(false); sendLog->setEnabled(false); } else { saveLog->setEnabled(true); saveLogAs->setEnabled(true); openLog->setEnabled(false); clearLog->setEnabled(true); deleteLog->setEnabled(false); sendLog->setEnabled(false); } }
I can use some trigger as
bool checkButtonsState
to check when log is added and then set it true to enable buttons? But whyconnect
is not working? -
Make sure to call checkLogTextBrowser() directly in your constructor as well, to handle anything that was logged before you opened it.
-
Now everything works. Thank you.