PyQt 窗口在打开后关闭
Posted
技术标签:
【中文标题】PyQt 窗口在打开后关闭【英文标题】:PyQt window closes after opening 【发布时间】:2016-09-14 05:35:28 【问题描述】:我有两个文件,分别是main.py和client_window.py。我想在进度条完成进度后显示客户端窗口。但我发现客户端窗口会立即打开和关闭。有人可以建议如何更改代码,以便我掌握正确的逻辑吗?
这是main.py:
"""
This module defines the User Interface
"""
import sys
import time
from cloudL.ui import client_window
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtGui import *
class ProgressBarWidget(QtGui.QDialog):
def __init__(self, parent=None):
super(ProgressBarWidget, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)
self.label = QLabel()
self.tryAgain = QPushButton("Try Again")
self.progressBar = QtGui.QProgressBar(self)
self.progressBar.setRange(0,100)
self.tryAgain.setEnabled(False)
layout.addWidget(self.label)
layout.addWidget(self.progressBar)
layout.addWidget(self.tryAgain)
self.myLongTask = TaskThread()
self.myLongTask.notifyProgress.connect(self.onProgress)
self.myLongTask.start()
def onStart(self):
self.tryAgain.setEnabled(False)
self.myLongTask.start()
self.label.setText("")
def onProgress(self, i):
self.progressBar.setValue(i)
if(self.progressBar.value() == 100):
#app = QApplication(sys.argv)
#global ex
ex = client_window.main()
ex.show()
#ex.main()
#ex.show()
#sys.exit(app.exec_())
else:
self.tryAgain.setEnabled(True)
self.tryAgain.clicked.connect(self.onStart)
self.label.setText("Cannot connect to Server! Please Try Again!")
class TaskThread(QtCore.QThread):
notifyProgress = QtCore.pyqtSignal(int)
def run(self):
for i in range(101):
self.notifyProgress.emit(i)
time.sleep(0.005)
class MainWindow(QWidget):
"""
This window will be the first screen to appear
"""
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
"""
Initializes parameters required by the MainWindow
"""
self.option = "" # to specify the if the selected option is Server or Client
self.ex = None
def main(self):
"""
This function is the origin where the initiation of the control takes place
:return: Returns nothing
"""
mainLayout = QVBoxLayout()
mainLayout.setAlignment(QtCore.Qt.AlignCenter)
radioLayout = QHBoxLayout()
mainLayout.setAlignment(QtCore.Qt.AlignCenter)
label = QLabel()
label.setText("Select whether to act as a Server or a Client")
labelFont = QFont()
labelFont.setBold(True)
labelFont.setPointSize(15)
label.setFont(labelFont)
mainLayout.addWidget(label)
mainLayout.addStretch()
b1 = QRadioButton("Server")
b1.setChecked(True)
b1.toggled.connect(lambda : btnstate(b1))
radioLayout.addWidget(b1)
b2 = QRadioButton("Client")
b2.toggled.connect(lambda : btnstate(b2))
radioLayout.addWidget(b2)
self.option = ""
def btnstate(b):
"""
Nested function to define the action when radio button is toggled
:param b: Button which is toggled currently
:return: Returns nothing
"""
if b.text() == "Server" and b.isChecked() == True:
self.option = "Server"
if b.text() == "Client" and b.isChecked() == True:
self.option = "Client"
start = QPushButton("Start")
mainLayout.addLayout(radioLayout)
mainLayout.addStretch()
mainLayout.addWidget(start)
self.setLayout(mainLayout)
self.setGeometry(400, 200, 300, 300)
self.setWindowTitle("CloudL")
start.clicked.connect(self.showdialog)
def showdialog(self):
"""
A sample message box to check and display which option is chosen
:return: Returns nothing
"""
#app = QApplication(sys.argv)
self.ex = ProgressBarWidget(self)
self.ex.setGeometry(400, 200, 500, 150)
self.destroy()
self.ex.setWindowTitle("CloudL")
self.ex.show()
"""
Execute the required action
"""
app = QApplication(sys.argv)
ex = MainWindow()
ex.main()
ex.show()
sys.exit(app.exec_())
而client_window.py如下:
#client_window.py
import sys
from PyQt4 import QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class myListWidget(QListWidget):
def Clicked(self, item):
QMessageBox.information(self, "ListWidget", "You clicked: " + item.text())
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.listWidget = None
self.initUI()
def initUI(self):
hbox = QHBoxLayout(self)
topleftLayout = QVBoxLayout()
topleftLayout.setAlignment(QtCore.Qt.AlignTop)
topleft = QFrame()
topleft.setFrameShape(QFrame.StyledPanel)
label = QLabel()
label.setText("SERVER LIST")
label.setAlignment(QtCore.Qt.AlignCenter)
topleftLayout.addWidget(label)
self.addServerList(topleftLayout)
topleft.setLayout(topleftLayout)
bottom = QFrame()
bottom.setFrameShape(QFrame.StyledPanel)
splitter1 = QSplitter(Qt.Horizontal)
textedit = QTextEdit()
splitter1.addWidget(topleft)
splitter1.addWidget(textedit)
splitter1.setSizes([100, 200])
splitter2 = QSplitter(Qt.Vertical)
splitter2.addWidget(splitter1)
splitter2.addWidget(bottom)
splitter2.setSizes([225, 100])
hbox.addWidget(splitter2)
self.setLayout(hbox)
QApplication.setStyle(QStyleFactory.create('Cleanlooks'))
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('QSplitter demo')
self.showMaximized()
def addServerList(self, layout):
self.listWidget = myListWidget()
self.listWidget.resize(300, 120)
self.listWidget.addItem("Item 1");
self.listWidget.addItem("Item 2");
self.listWidget.addItem("Item 3");
self.listWidget.addItem("Item 4");
self.listWidget.setWindowTitle('PyQT QListwidget Demo')
self.listWidget.itemClicked.connect(self.listWidget.Clicked)
layout.addWidget(self.listWidget)
def main():
ex = Example()
ex.showMaximized()
return ex
if __name__ == '__main__':
app = QApplication(sys.argv)
main()
sys.exit(app.exec_())
我正在拨打client_window
的电话:
def onProgress(self, i):
self.progressBar.setValue(i)
if(self.progressBar.value() == 100):
#app = QApplication(sys.argv)
#global ex
ex = client_window.main()
ex.show()
#ex.main()
#ex.show()
#sys.exit(app.exec_())
else:
self.tryAgain.setEnabled(True)
self.tryAgain.clicked.connect(self.onStart)
self.label.setText("Cannot connect to Server! Please Try Again!")
另外,如果我在客户端窗口中包含 app = QApplication(sys.argv)
和 sys.exit(app.exec_())
行,我会收到以下错误:
QCoreApplication::exec: 事件循环已经在运行 pyqt 错误
【问题讨论】:
要在 PyQt 中打开一个窗口,您必须在创建和显示小部件之前拥有 app = QtGui.QApplication(sys.argv)。我不知道具体原因,但您可以使用 this 网站作为参考(它对我有用......)祝你好运 这能回答你的问题吗? PyQt: Why does new window close immediately after opening it 【参考方案1】:您需要保留对客户端窗口的引用,否则它将在onProgress
返回时立即被垃圾回收:
def onProgress(self, i):
self.progressBar.setValue(i)
if self.progressBar.value() == 100:
self.client_window = client_window.main()
else:
self.tryAgain.setEnabled(True)
self.tryAgain.clicked.connect(self.onStart)
self.label.setText("Cannot connect to Server! Please Try Again!")
【讨论】:
以上是关于PyQt 窗口在打开后关闭的主要内容,如果未能解决你的问题,请参考以下文章