2013-08-05 122 views
0

我試圖用QPushButton來調用一個打開QWebView的新實例的函數。有效,但一旦窗口打開,它會再次關閉。 我讀過這個 - PyQt window closes immediately after opening但我不明白如何引用窗口保持打開狀態。PyQt窗口啓動後關閉

import sys 
from PyQt4 import QtCore, QtGui, QtWebKit 
from PyQt4.QtWebKit import QWebSettings 
from PyQt4.QtNetwork import QNetworkAccessManager 
from PyQt4.QtNetwork import * 



UA_STRING = """Test Test Test""" 
vidurl = ("empty") 

def web1(): 

    class YWebPage(QtWebKit.QWebPage): 
     def __init__(self): 
      super(QtWebKit.QWebPage, self).__init__() 

     def userAgentForUrl(self, url): 
      return UA_STRING 


    class Browser(QtGui.QMainWindow): # "Browser" window 


     def __init__(self): 
      QtGui.QMainWindow.__init__(self) 
      self.resize(800,600) # Viewport size 
      self.centralwidget = QtGui.QWidget(self) 
      self.html = QtWebKit.QWebView() 


     def browse(self): 
      self.webView = QtWebKit.QWebView() 
      self.yPage = YWebPage() 
      self.webView.setPage(self.yPage) 
      self.webView.load(QtCore.QUrl(vidurl)) # Video URL 
      self.webView.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled,True) # Enables flash player 
      self.webView.show() 

    x = Browser() 
    # QNetworkProxy.setApplicationProxy(QNetworkProxy(QNetworkProxy.HttpProxy, "proxy.example.com", 8080)) # Proxy setting 
    x.browse() 



def main(): # Dialog window 

    app = QtGui.QApplication(sys.argv) 

    w = QtGui.QWidget() 

    w.resize(200, 450) 
    w.setFixedSize(200, 350) 
    w.move(300, 300) 
    w.setWindowTitle('U-bot 0.1') 

    # Setup GUI 

    # Start Button 
    w.__button = QtGui.QPushButton(w) 
    w.__button.clicked.connect(lambda: web1()) 

    # Text area 
    w.__qle = QtGui.QLineEdit(w) 
    w.__qle.setText ("http://") 
    vidurl = w.__qle.text # Get video url from user 

    # Images 
    pixmap1 = QtGui.QPixmap("ubot.png") 
    lbl1 = QtGui.QLabel(w) 
    lbl1.resize(200, 150) 
    lbl1.setPixmap(pixmap1) 
    lbl1.setScaledContents(True) 

    w.__button.setText('Start') 
    layout = QtGui.QVBoxLayout() 
    layout.addStretch(1) 

    layout.addWidget(w.__qle) 
    layout.addWidget(w.__button) 


    w.setLayout(layout) 
    w.show() 

    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 
    app.exec_() 

回答

4

要保持一個QObject一個參考,你可以保留的變量範圍,或將其添加爲另一個QObject該變量已經停留在範圍內的孩子。

而對於QWidget,家長也應該是QWidget,所以,你的情況,你想使w爲所有QMainWindow S的父母。

def web1(parent): 
    ... 
    class Browser(QtGui.QMainWindow): # "Browser" window 
     def __init__(self, parent): 
      QtGui.QMainWindow.__init__(self, parent) 
      ... 

def main(): 
    ... 
    w.__button.clicked.connect(lambda: web1(w)) 

這也避免了手動維護打開的窗口列表,因爲對象層次結構可以爲您做到這一點。

PS:子窗口顯示爲頂層窗口,而不是w窗口內,因爲QMainWindow(和QDialog)具有Qt::Window標誌默認設置。

+0

謝謝,跟着這個去了。 – metalayer

+0

「爲了保持對QObject的引用,您可以將變量保留在範圍內」是我所需要知道的。爲我點擊了一小撮知識 - 我添加了一行代碼,將對象保留在我的腳本的範圍內,並且我的QWidget窗口保持活動狀態,而不是像以前那樣瞬間消失。 – 10mjg

4

創建每次MainWindow類保持打開瀏覽器的列表,當你打開瀏覽器,只需將其添加到列表中。當瀏覽器窗口關閉時,它將從列表中移除,請參閱closeEvent

import sys 
from PyQt4 import QtCore, QtGui, QtWebKit 
from PyQt4.QtWebKit import QWebSettings 
from PyQt4.QtNetwork import QNetworkAccessManager 
from PyQt4.QtNetwork import * 


UA_STRING = """Test Test Test""" 
vidurl = ("empty") 

class YWebPage(QtWebKit.QWebPage): 
    def __init__(self): 
     super(YWebPage, self).__init__() 

    def userAgentForUrl(self, url): 
     return UA_STRING 


class Browser(QtGui.QMainWindow): # "Browser" window 
    def __init__(self, main, url): 
     QtGui.QMainWindow.__init__(self) 
     self.main = main 
     self.resize(800,600) # Viewport size 
     self.webView = QtWebKit.QWebView() 
     self.setCentralWidget(self.webView) 
     self.yPage = YWebPage() 
     self.webView.setPage(self.yPage) 
     self.webView.load(QtCore.QUrl(url)) # Video URL 
     self.webView.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True) # Enables flash player 

    def closeEvent(self, event): 
     self.main.browsers.remove(self) 
     super(Browser, self).closeEvent(event) 


class MainWindow(QtGui.QWidget): 
    def __init__(self): 
     super(MainWindow, self).__init__() 
     self.browsers = [] 

     self.resize(200, 450) 
     self.setFixedSize(200, 350) 
     self.move(300, 300) 
     self.setWindowTitle('U-bot 0.1') 

     # Setup GUI 

     # Start Button 
     self.__button = QtGui.QPushButton('Start') 
     self.__button.clicked.connect(self.open) 

     # Text area 
     self.__qle = QtGui.QLineEdit() 
     self.__qle.setText("http://") 

     # Images 
     pixmap1 = QtGui.QPixmap("ubot.png") 
     lbl1 = QtGui.QLabel() 
     lbl1.resize(200, 150) 
     lbl1.setPixmap(pixmap1) 
     lbl1.setScaledContents(True) 

     layout = QtGui.QVBoxLayout() 
     layout.addStretch(1) 

     layout.addWidget(self.__qle) 
     layout.addWidget(self.__button) 

     self.setLayout(layout) 

    def open(self): 
     b = Browser(self, self.__qle.text()) 
     b.show() 
     self.browsers.append(b) 


def main(): 
    app = QtGui.QApplication(sys.argv) 
    w = MainWindow() 
    w.show() 
    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 
+2

這個問題的完美答案。窗戶關閉的原因是它失去了,執行後沒有任何參考。該函數被調用,彈出一個窗口,之後它從內存中被清除,因爲函數完成了。當你使用'self'將它鏈接到一個現有的類時,你可以避免這種情況。這個答案甚至更好,因爲它將新窗口附加到列表對象。我認爲這是保持代碼清潔的絕佳解決方案。 – Ecno92

+0

感謝您的回覆。 – metalayer