QT 子視窗—>主視窗 訊號和槽的互動
阿新 • • 發佈:2019-01-27
背景:
要實現的功能:
主視窗MainWindow中開啟子視窗UdpChannel後,子視窗傳送一個訊號,傳遞一個QString,要求在主視窗的QTextBrowser中打印出來!(比如操作的日誌資訊)
實現原理:
①在子視窗中宣告訊號
②在主視窗中宣告並實現槽函式
③在主視窗中庸connect繫結訊號和槽
④子視窗中傳送訊號(emit)
具體實現:
①UdpChannel.h檔案中
//日誌列印訊號
signals:
voidGetUdpLogMsg(QStringmsg);//不需要實現②MainWindow.h檔案中 //訊號-槽的方式列印日誌
publicslots:
voidPrintLogMsg(QStringmsg);
MainWindow.cpp檔案中對槽進行實現
voidMainWindow::PrintLogMsg(QStringmsg)
{
ui->outputTxt->append(msg);
}
③在MainWindow.cpp檔案中進行繫結
udp=newUdpChannel(ui->mdiArea);
//繫結從udpChannel中傳送過來的日誌列印訊號
connect(udp,SIGNAL(GetUdpLogMsg(QString)),this,SLOT(PrintLogMsg(QString)));
showWidgetOnMDI(udp);注意:不是在MainWindow這個類的建構函式中繫結,教訓啊! ④在UdpChannel.cpp檔案中傳送訊號 //傳送日誌列印訊號
voidUdpChannel::on_UDPButton_clicked()
{
emitGetUdpLogMsg("UDPchannel中的日誌資訊");
}
總結:
①connect()繫結函式,如果放到主視窗的建構函式中,此時,子視窗的類還沒新建物件,沒有分配記憶體地址,如果new一個物件,程式不會報錯(搜一下,有好新手跟我一樣有這個疑問),但是新建的子視窗物件與通過主視窗的點選按鈕後,新建的子視窗物件是兩碼事,在記憶體中是兩個不同的地址,我們要繫結的應該是後者與主視窗的訊號槽繫結,所以,connect函式應該放到主視窗點選子視窗按鈕程式碼裡面。
②connect()繫結函式,如果放到子視窗的建構函式中,傳送用this,接收用主視窗指標,原理一樣,如果此處新建主視窗物件,然後建立連線,其實記憶體中有兩個主視窗物件了,繫結的並不是我想顯示日誌資訊的主視窗物件,此處可以直接調用出視窗已新建好物件的指標。
③connect(),在子視窗和主視窗互動的過程中,其實放到哪裡不重要,重要的是傳送和接收的指標一定要是已新建好的主視窗/子視窗物件的指標,並且確保是新建好後再執行該connect()繫結函式。