在pyQt中创建一个不可见的层来覆盖整个对话框

2024-09-30 04:37:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在pyqt5应用程序中执行任务时显示微调器。我发现了微调器的这个很好的实现,所以我尝试了:https://github.com/z3ntu/QtWaitingSpinner

演示工作正常,但在演示中,微调器显示在对话框的空白区域。我希望它是一个覆盖整个对话框的覆盖。在

QtWaitingSpinner的作者建议“作为一个替代的例子,下面的代码将创建一个微调器:(1)只要微调器处于活动状态,它就会阻止所有用户输入到主应用程序;(2)每次调用“start”时,都会自动将自己集中在其父控件上;(3)使用默认形状,“大小和颜色设置。”并使用以下代码:

spinner = QtWaitingSpinner(self, True, True, Qt.ApplicationModal)
spinner.start() # starts spinning

但我尝试了这个实现作为一个例子,但没有成功:

^{pr2}$

所以我的目的是创建一个不可见的层,将微调器设置为它唯一的小部件,并在整个对话框窗口中显示半透明层。在

你知道我该怎么做吗?在


Tags: 代码httpsgithubcomtrue应用程序start空白
1条回答
网友
1楼 · 发布于 2024-09-30 04:37:24

一旦我也遇到了这个问题,所以我修改了库,首先激活标志:QtCore.Qt.Dialog | QtCore.Qt.FramelessWindowHint,其他更改必须在updatePosition()方法中完成:

def updatePosition(self):
    if self.parentWidget() and self._centerOnParent:
        parentRect = QtCore.QRect(self.parentWidget().mapToGlobal(QtCore.QPoint(0, 0)), self.parentWidget().size())
        self.move(QtWidgets.QStyle.alignedRect(QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter, self.size(), parentRect).topLeft())

结果如下:

waitingspinnerwidget.py

^{pr2}$

通过上面的方法,我们解决了其中一个问题,另一个问题是urllib.request.urlretrieve()阻塞,因此它将导致GUI冻结,因此解决方案是将其移动到另一个线程,使用以前的响应,我们可以按以下方式执行:

from PyQt5 import QtCore, QtGui, QtWidgets
import urllib.request
from waitingspinnerwidget import QtWaitingSpinner


class RequestRunnable(QtCore.QRunnable):
    def __init__(self, url, destination, dialog):
        super(RequestRunnable, self).__init__()
        self._url = url
        self._destination = destination
        self.w = dialog

    def run(self):
        urllib.request.urlretrieve(self._url, self._destination)
        QMetaObject.invokeMethod(self.w, "FinishedDownload", QtCore.Qt.QueuedConnection)


class DownloadDataDialog(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(DownloadDataDialog, self).__init__(parent)
        self.spinner = QtWaitingSpinner(self, True, True, QtCore.Qt.ApplicationModal)
        tabWidget = QtWidgets.QTabWidget(self)
        tabWidget.addTab(MyTab(), "MyTab")
        mainLayout = QtWidgets.QVBoxLayout(self)
        mainLayout.addWidget(tabWidget)
        self.setWindowTitle("Download option chain data from web")


class MyTab(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(MyTab, self).__init__(parent)

        dataGroup = QtWidgets.QGroupBox('Data')

        getButton = QtWidgets.QPushButton('Download')
        getButton.clicked.connect(self.download_data)

        dataLayout = QtWidgets.QVBoxLayout(self)
        dataLayout.addWidget(getButton)

        mainLayout = QtWidgets.QVBoxLayout(self)
        mainLayout.addWidget(dataGroup)
        mainLayout.addStretch(1)

    def download_data(self):
        self.parentWidget().window().spinner.start()
        url = 'http://www.meff.es/docs/Ficheros/Descarga/dRV/RV180912.zip'
        destination = 'test.zip'
        runnable = RequestRunnable(url, destination, self)
        QtCore.QThreadPool.globalInstance().start(runnable)

    @QtCore.pyqtSlot()
    def FinishedDownload(self):
        self.parentWidget().window().spinner.stop()


if __name__ == '__main__':

    import sys
    app = QtWidgets.QApplication(sys.argv)
    tabdialog = DownloadDataDialog()
    tabdialog.show()
    sys.exit(app.exec_())

enter image description here

相关问题 更多 >

    热门问题