在學習和測試PyQt相關部件功能的時候,老猿經常是不同的窗口新建一個類,再新建一個Application來使用這個窗口類進行測試。
為了減少應用框架代碼的重復開發,老猿決定采用主窗口疊加測試窗口的模式來進行功能測試,即主窗口和主程序基本保持不變,采用主窗口點擊按鈕彈出測試窗口的形式來驗證測試窗口的功能,這樣不用每回都新建工程,也不用重寫(其實基本上是賦值粘貼)主程序的代碼。
於是老猿創建了一個QWidget類型的應用主窗口,在主窗口上加了一個“彈出窗口”的按鈕,並建立了按鈕clicked信號和槽函數之間的連接。槽函數代碼如下:
def popWin(self):
popwin = popWinTestWin() #創建測試窗口對象
popwin.show()
代碼完成后,執行卻發現窗口一閃而逝。進行代碼調試,發現大部分情況下,如果采用單步跟蹤模式則可以,有時也不行,其他都無法正常顯示子窗口。於是到處查資料,沒有查到PyQt在網上有類似的問題,而Qt的C語言代碼倒是碰到過,有人答復是不該在槽函數本地空間中創建對象,會導致棧溢出,也有人說主窗口和彈出窗口不能是同一種類型,但沒有詳細說是大類型如QWidget還是派生類型自定義的。
老猿寫了個測試程序,提供不同類型的彈出窗在不同名字空間創建后彈出的功能。
如圖:
對應槽函數代碼如下:
def createPopwin(self,winTypeChoice):
if winTypeChoice == 0:
w = popWinTestWin()
elif winTypeChoice == 1:
w = widgetPopWin()
else:
w = dialogPopWin()
return w
def popWin(self):
winTypeChoice = self.popTypeChoice.checkedId()
namespaceChoice = self.popNamespaceChoice.checkedId()
if namespaceChoice == 0:
popwin = self.createPopwin(winTypeChoice)
popwin.show()
elif namespaceChoice == 1:
self.popwin = self.createPopwin(winTypeChoice)
self.popwin.show()
else:
QtWidgets.qApp.popwin = self.createPopwin(winTypeChoice)
QtWidgets.qApp.popwin.show()
經過測試發現就是彈窗采用槽函數局部變量創建時存在問題,但問題原因還是沒找到,夜深了直接睡了,第二天一醒來豁然開朗,這個問題其實就是局部變量的生命周期問題,槽函數結束局部變量生命周期結束,因此對應窗口就消失了。所以在槽函數中彈出窗口,必須用非局部變量。

博客地址:https://blog.csdn.net/LaoYuanPython
老猿Python博客文章目錄:https://blog.csdn.net/LaoYuanPython/article/details/98245036