以下是一个使用PyQt5执行网络请求并在执行过程中显示一个执行中的对话框的完整代码示例:
一、继承QDialog实现
import sys
import requests
from PyQt5.QtWidgets import QApplication, QDialog, QLabel, QVBoxLayout
from PyQt5.QtCore import Qt, QThread, pyqtSignal
class RequestThread(QThread):
finished = pyqtSignal(bool)
def __init__(self, url):
super().__init__()
self.url = url
def run(self):
try:
response = requests.get(self.url)
if response.status_code == 200:
self.finished.emit(True)
else:
self.finished.emit(False)
except:
self.finished.emit(False)
class ProgressDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("执行中")
self.setFixedSize(200, 100)
self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint)
layout = QVBoxLayout(self)
self.label = QLabel("正在执行,请稍候...", self)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
def setMessage(self, text):
self.label.setText(text)
class MainWindow(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle("网络请求")
self.setFixedSize(300, 100)
layout = QVBoxLayout(self)
self.label = QLabel("点击按钮执行网络请求", self)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
self.button = QPushButton("执行请求", self)
self.button.clicked.connect(self.executeRequest)
layout.addWidget(self.button, alignment=Qt.AlignCenter)
self.progressDialog = ProgressDialog(self)
def executeRequest(self):
url = "https://www.example.com"
self.progressDialog.show()
self.progressDialog.setMessage("正在执行网络请求,请稍候...")
self.requestThread = RequestThread(url)
self.requestThread.finished.connect(self.onRequestFinished)
self.requestThread.start()
def onRequestFinished(self, success):
self.progressDialog.hide()
if success:
self.label.setText("网络请求执行成功")
else:
self.label.setText("网络请求执行失败")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
在这个例子中,我们使用了PyQt5的QThread类来在后台执行网络请求,并使用pyqtSignal来在请求完成时向主线程发送信号。ProgressDialog是一个自定义的对话框,用于在执行请求时显示一个执行中的消息。MainWindow是我们的主窗口,包含一个标签和一个按钮,用于触发网络请求。
当用户点击按钮时,我们首先显示一个ProgressDialog,然后创建一个RequestThread,并在其中执行网络请求。一旦请求完成,RequestThread将发出一个finished信号,我们在MainWindow中连接这个信号,以便在请求完成时执行onRequestFinished方法。在这个方法中,我们隐藏ProgressDialog并更新标签以反映请求的结果。
注意,这只是一个简单的示例,用于说明如何在PyQt5中执行网络请求并显示一个执行中的对话框。在实际应用中,您可能需要对代码进行一些修改,以满足您的特定需求。
二、继承QMainWindow
如果您的MainWindow继承自QMainWindow,您需要对代码进行一些修改才能使ProgressDialog正确显示。因为QMainWindow已经有一个菜单栏、工具栏、状态栏等,所以ProgressDialog需要以对话框的形式显示。
import sys
import requests
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QLabel, QVBoxLayout, QAction, QMessageBox
from PyQt5.QtCore import Qt, QThread, pyqtSignal
class RequestThread(QThread):
finished = pyqtSignal(bool)
def __init__(self, url):
super().__init__()
self.url = url
def run(self):
try:
response = requests.get(self.url)
if response.status_code == 200:
self.finished.emit(True)
else:
self.finished.emit(False)
except:
self.finished.emit(False)
class ProgressDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent, Qt.CustomizeWindowHint | Qt.WindowTitleHint)
self.setWindowTitle("执行中")
self.setFixedSize(200, 100)
layout = QVBoxLayout(self)
self.label = QLabel("正在执行,请稍候...", self)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
def setMessage(self, text):
self.label.setText(text)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("网络请求")
self.setFixedSize(300, 100)
centralWidget = QWidget(self)
layout = QVBoxLayout(centralWidget)
self.label = QLabel("点击按钮执行网络请求", centralWidget)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
self.button = QAction("执行请求", self)
self.button.triggered.connect(self.executeRequest)
self.addAction(self.button)
self.progressDialog = ProgressDialog(self)
def executeRequest(self):
url = "https://www.example.com"
self.progressDialog.show()
self.progressDialog.setMessage("正在执行网络请求,请稍候...")
self.requestThread = RequestThread(url)
self.requestThread.finished.connect(self.onRequestFinished)
self.requestThread.start()
def onRequestFinished(self, success):
self.progressDialog.hide()
if success:
self.label.setText("网络请求执行成功")
else:
self.label.setText("网络请求执行失败")
QMessageBox.warning(self, "警告", "网络请求执行失败!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
在这个例子中,我们将ProgressDialog的父窗口设置为MainWindow,并设置了Qt.CustomizeWindowHint | Qt.WindowTitleHint标志,以使其作为对话框显示。我们还使用了QWidget作为MainWindow的中央窗口部件,以便正确放置标签和按钮。
我们还将按钮修改为QAction,并通过addAction将其添加到MainWindow的菜单栏中。当用户点击按钮时,我们将ProgressDialog显示出来,并使用QAction的triggered信号触发executeRequest方法。
在onRequestFinished方法中,我们隐藏ProgressDialog并根据请求结果更新标签。如果请求失败,我们还使用QMessageBox显示一个警告框。
三、模态对话框
如果您希望ProgressDialog显示时,MainWindow中的其他部分不能被操作,但MainWindow本身仍然可以被关闭和最小化,可以使用setWindowModality方法将ProgressDialog设置为ApplicationModal模态对话框。
以下是示例代码,将ProgressDialog设置为ApplicationModal模态对话框:
import sys
import requests
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QLabel, QVBoxLayout, QAction, QMessageBox
class RequestThread(QThread):
finished = pyqtSignal(bool)
def __init__(self, url):
super().__init__()
self.url = url
def run(self):
try:
response = requests.get(self.url)
if response.status_code == 200:
self.finished.emit(True)
else:
self.finished.emit(False)
except:
self.finished.emit(False)
class ProgressDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("执行中")
self.setFixedSize(200, 100)
layout = QVBoxLayout(self)
self.label = QLabel("正在执行,请稍候...", self)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
def setMessage(self, text):
self.label.setText(text)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("网络请求")
self.setFixedSize(300, 100)
centralWidget = QWidget(self)
layout = QVBoxLayout(centralWidget)
self.label = QLabel("点击按钮执行网络请求", centralWidget)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
self.button = QAction("执行请求", self)
self.button.triggered.connect(self.executeRequest)
self.addAction(self.button)
self.progressDialog = ProgressDialog(self)
self.progressDialog.setWindowModality(Qt.ApplicationModal)
def executeRequest(self):
url = "https://www.example.com"
self.progressDialog.show()
self.progressDialog.setMessage("正在执行网络请求,请稍候...")
self.requestThread = RequestThread(url)
self.requestThread.finished.connect(self.onRequestFinished)
self.requestThread.start()
def onRequestFinished(self, success):
self.progressDialog.hide()
if success:
self.label.setText("网络请求执行成功")
else:
self.label.setText("网络请求执行失败")
QMessageBox.warning(self, "警告", "网络请求执行失败!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
使用 setWindowModality 方法将 ProgressDialog 设置为 ApplicationModal 模态对话框会阻止用户与 MainWindow 进行交互,包括关闭和最小化窗口。在这种情况下,您需要为 ProgressDialog 添加一个关闭按钮或使用其他方法来关闭 ProgressDialog。
如果您希望ProgressDialog显示时,MainWindow中的其他部分不能被操作,但MainWindow本身仍然可以被关闭和最小化,可以尝试使用 setEnabled 方法禁用 MainWindow 中的其他部件。
四、禁用其他部件
以下是示例代码,使用 setEnabled 方法禁用 MainWindow 中的其他部件:
import sys
import requests
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QLabel, QVBoxLayout, QAction, QMessageBox
class RequestThread(QThread):
finished = pyqtSignal(bool)
def __init__(self, url):
super().__init__()
self.url = url
def run(self):
try:
response = requests.get(self.url)
if response.status_code == 200:
self.finished.emit(True)
else:
self.finished.emit(False)
except:
self.finished.emit(False)
class ProgressDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("执行中")
self.setFixedSize(200, 100)
layout = QVBoxLayout(self)
self.label = QLabel("正在执行,请稍候...", self)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
def setMessage(self, text):
self.label.setText(text)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("网络请求")
self.setFixedSize(300, 100)
centralWidget = QWidget(self)
layout = QVBoxLayout(centralWidget)
self.label = QLabel("点击按钮执行网络请求", centralWidget)
layout.addWidget(self.label, alignment=Qt.AlignCenter)
self.button = QAction("执行请求", self)
self.button.triggered.connect(self.executeRequest)
self.addAction(self.button)
self.progressDialog = ProgressDialog(self)
def executeRequest(self):
url = "https://www.example.com"
self.progressDialog.show()
self.progressDialog.setMessage("正在执行网络请求,请稍候...")
self.setEnabled(False) # 禁用 MainWindow 中的其他部件
self.requestThread = RequestThread(url)
self.requestThread.finished.connect(self.onRequestFinished)
self.requestThread.start()
def onRequestFinished(self, success):
self.progressDialog.hide()
self.setEnabled(True) # 启用 MainWindow 中的其他部件
if success:
self.label.setText("网络请求执行成功")
else:
self.label.setText("网络请求执行失败")
QMessageBox.warning(self, "警告", "网络请求执行失败!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
在这个例子中,我们使用 setEnabled 方法禁用 MainWindow 中的其他部件。这意味着 ProgressDialog 显示时,用户无法与 MainWindow 中的其他部件进行交互。在网络请求完成后,我们使用 setEnabled 方法启用 MainWindow 中的其他部件。这样,用户就可以在 ProgressDialog 显示时关闭或最小化 MainWindow。
本文提供了一个使用PyQt5在执行网络请求时显示ProgressDialog的完整代码示例,涉及QDialog和QMainWindow的继承,模态对话框的使用,以及禁用其他部件的功能。
665

被折叠的 条评论
为什么被折叠?



