Qt之日志輸出視窗,按照網上示例 https://jingyan.baidu.com/article/a65957f4d2cce824e67f9b21.html 寫的代碼,
在運行時引起訪問沖突,加鎖或其他方法好像都不行,
根據除錯應該是全域指標呼叫Mainwindow類控制元件和Mainwindow類本身信號槽呼叫同一個控制元件時引起的訪問沖突。
請教各位大拿怎么解決訪問沖突或者有什么更好的方式將日志內容輸出到視窗控制元件
這個是在Mainwindow類外訪問ui。不說別的,上代碼
main.cpp
//定義一個全域指標, 指向主視窗
FMCanera_QT *myWin = NULL;
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
static QMutex mutex;
mutex.lock();
QString text;
switch (type)
{
case QtDebugMsg:
text = QString("<font color=\"#9F5F9F\">Debug:");
break;
case QtWarningMsg:
text = QString("<font color=\"#B5A642\">Warning:");
break;
case QtCriticalMsg:
//myWin->FM_Critical_State = true;
text = QString("<font color=\"#FF0000\">Critical:");
break;
case QtFatalMsg:
text = QString("<font color=\"#800080\">Fatal:");
case QtInfoMsg:
text = QString("<font color=\"#000000\">");
}
QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
QString current_date = QString("(%1)").arg(current_date_time);
QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date);
QString messageWindows = QString("%1 %2 %3").arg(text).arg(current_date).arg(msg);
myWin->showMsg(messageWindows+"</font>"); // 這里呼叫Mainwindow類的控制元件輸出日志資訊
//保存log檔案
QDateTime c_date_time = QDateTime::currentDateTime();
QString c_date1 = c_date_time.toString("yyyy-MM/");
QString c_date2 = c_date_time.toString("yyyy-MM-dd");
QString filePath = "./Log/"+ c_date1;
mkMutiDir(filePath);
QString filename = filePath + c_date2 + ".txt";
QFile file(filename);
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream text_stream(&file);
text_stream << message << "\r\n";
file.flush();
file.close();
mutex.unlock();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FMCanera_QT w;
//將主視窗的指標賦給自定義的全域指標
myWin = &w;
//注冊MessageHandler
qInstallMessageHandler(outputMessage);
w.show();
return a.exec();
}
下面是主視窗內呼叫textBrowser控制元件輸出日志資訊的方法
FMCanera_QT.cpp
//main中呼叫的日志輸出公有方法
void FMCanera_QT::showMsg(QString msg)
{
ui.textBrowser_log->append(msg); //訪問沖突
}
// 私有槽, 定義了textBrowser_控制元件文本出現變化時觸發,將指標滾動到控制元件底部
void FMCanera_QT::setRecTextFouc()
{
ui.textBrowser_log->moveCursor(QTextCursor::End); //訪問沖突
}
運行出錯畫面:
uj5u.com熱心網友回復:
其實我挺好奇你的ui是怎么定義的。難道不應該是一個指標嗎?其次,你這個myWin的用法你覺得對嗎?
myWin->showMsg(messageWindows+"</font>"); // 這里呼叫Mainwindow類的控制元件輸出日志資訊
你在函式void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
中用到myWIn前加上這句,你就知道你錯在哪了。
if (null != myWin) {
...
}
也就是說,你這地方改成這樣:
if (null != myWin) {
myWin->showMsg(messageWindows+"</font>"); // 這里呼叫Mainwindow類的控制元件輸出日志資訊
}
uj5u.com熱心網友回復:
這個ui的定義方式是qt for vs的默認創建方式, 沒有使用指標,習慣了也就沒改。你指的
if (null != myWin) {
...
}
是認為指標為空所有沒有呼叫進去嗎,
實際上已經呼叫的方法體內部了, 并且在大部分時候是正常運行的,只是在長時間測驗時偶爾會出現我說的訪問沖突問題,類似于多執行緒訪問沖突
但是這里是在main內注冊的方法和主表單Mainwindow類內私有槽之間的訪問沖突, 我不太了解這兩個代表的qt視窗主執行緒還是哪個執行緒之間的問題,并且加了執行緒鎖也沒有用
如下:
void FMCanera_QT::showMsg(QString msg)
{
QMutexLocker locker(&m_ShowLock);
ui.textBrowser_log->append(msg); //訪問沖突
//if (FM_Critical_State) //訪問沖突
// m_IOCard_PCM27D24DI_Thread->setData(0, 0, 3000);
//ui.textBrowser_log->moveCursor(QTextCursor::End);
}
void FMCanera_QT::setRecTextFouc()
{
QMutexLocker locker(&m_ShowLock);
ui.textBrowser_log->moveCursor(QTextCursor::End);
}
void FMCanera_QT::showMsg(QString msg)
{
QMutexLocker locker(&m_ShowLock);
ui.textBrowser_log->append(msg); //訪問沖突
//if (FM_Critical_State) //訪問沖突
// m_IOCard_PCM27D24DI_Thread->setData(0, 0, 3000);
//ui.textBrowser_log->moveCursor(QTextCursor::End);
}
void FMCanera_QT::setRecTextFouc()
{
QMutexLocker locker(&m_ShowLock);
ui.textBrowser_log->moveCursor(QTextCursor::End);
}
并且在showMsg 內連續呼叫也會有沖突
如下:
void FMCanera_QT::showMsg(QString msg)
{
ui.textBrowser_log->append(msg);
ui.textBrowser_log->moveCursor(QTextCursor::End);
//if (FM_Critical_State) //訪問沖突
// m_IOCard_PCM27D24DI_Thread->setData(0, 0, 3000);
}
void FMCanera_QT::setRecTextFouc()
{
//ui.textBrowser_log->moveCursor(QTextCursor::End);
}
uj5u.com熱心網友回復:
自己頂一下,祈禱大佬解答啊uj5u.com熱心網友回復:
UI的處理在UI自己的類里實作,不要在非UI的執行緒等其他地方呼叫UI的東西。轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/13889.html
標籤:Qt
下一篇:如何在xib中實作滑動洗掉的效果
