[PyQt] Non-Modal Dialog

Barry Scott barry at barrys-emacs.org
Sun Oct 6 19:00:16 BST 2019



> On 6 Oct 2019, at 17:18, Chuck Rhode <CRhode at LacusVeris.com> wrote:
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> In the deep past, I've worked with VB, Tk, Pascal Delphi, and Gtk.  I
> seem to recall that all had non-modal dialog boxes for situations where
> you wanted to inform the user through the user interface that a
> long-running task was in progress.  Is this not done anymore?

Isn't just that a none-modal dialog is a Window?
Create the windows, add any controlls you need and update with progress
as it happens.

Barry

> 
> I assume there are still long running tasks such as QPixmap *save*s.
> 
> These tasks cannot emit progress signals for powering a progress bar.
> What alternatives are there?
> 
> I can't get a cursor change to show up.
> 
> Does one nowadays throw up a semitransparent overlay with a spinner?
> That is not so simple or informative as a non-modal dialog, I think.
> 
> I've pored over Stackoverflow posts about Qt from the last decade, and
> I don't see a lot that I can use.  Most say its as simple as
> QMessageBox *open* instead of *exec_*, but this has not been my
> experience with PyQt.  Here is code that works, however:
> 
> #!/usr/bin/python
> # -*- coding: utf-8 -*-
> 
> # nonmodal_example.py
> # 2019 Oct 06 . ccr
> 
> """Demonstrate how to show a non-modal dialog box before starting a
> long-running task.
> 
> """
> 
> from __future__ import division
> import sys
> from PyQt5.QtWidgets import (
>    QApplication,
>    QMainWindow,
>    QWidget,
>    QGridLayout,
>    QPushButton,
>    QMessageBox,
>    )
> from PyQt5.QtGui import (
>    QPixmap,
>    QTransform,
>    )
> from PyQt5.QtCore import(
>    QThread,
>    )
> 
> ZERO = 0
> SPACE = ' '
> NULL = ''
> NUL = '\x00'
> NA = -1
> 
> 
> class ThdWorker(QThread):
> 
>    """An (arbitrarily) long-running task.
> 
>    """
> 
>    def run(self):
>        QThread.sleep(1)
>        WIN.pixmap.save('/tmp/nonmodal_test.png')
>        return
> 
> 
> class WinMain(QMainWindow):
> 
>    """The (trivial) main window of the graphical user interface.
> 
>    """
> 
>    def __init__(self):
>        super(WinMain, self).__init__()
>        self.resize(800, 600)
>        self.central_widget = QWidget(self)
>        self.setCentralWidget(self.central_widget)
>        self.layout = QGridLayout()
>        self.central_widget.setLayout(self.layout)
>        self.btn_run = QPushButton('Run Next Test Scenario', self.central_widget)
>        self.btn_run.setMaximumSize(200, 30)
>        self.btn_run.clicked.connect(self.test_part_1)
>        self.layout.addWidget(self.btn_run)
>        figure = QPixmap()
>        result = figure.load('/usr/share/qt5/doc/qtdesigner/images/designer-screenshot.png')
>        if result:
>            pass
>        else:
>            raise NotImplementedError
>        transformation = QTransform()
>        transformation.scale(5.0, 5.0)
>        self.pixmap = figure.transformed(transformation)
>        return
> 
>    def test_part_1(self):
> 
>        """Fork a thread.
> 
>        """
> 
>        self.popup = QMessageBox(QMessageBox.Information, None, 'This is a test.  Please wait.')
>        self.popup.show()
>        self.thread = ThdWorker(self)
>        self.thread.finished.connect(self.test_part_2)
>        self.thread.start()
>        return
> 
>    def test_part_2(self):
>        self.popup.close()
>        del self.popup
>        del self.thread
>        return
> 
> 
> if __name__ == "__main__":
>    APP = QApplication(sys.argv)
>    WIN = WinMain()
>    WIN.show()
>    result = APP.exec_()
>    sys.exit(result)
> 
> 
> # Fin
> 
> What really gripes me about this example, despite the fact that it
> works for me, is the sleep at the beginning of the thread that starts
> the long running thread.  The sleep is essential.  Although the
> QMessageBox *show* paints its frame, it doesn't have time to paint its
> contents unless the thread pauses before it even gets going.
> 
> There HAS TO BE a more elegant way to allow non-modal dialogs to paint
> completely.  I've tried lots of different Stackoverflow
> recommendations, and nothing works.  I have a more complete (and
> considerably longer) test suite ready to show you that is available upon
> request.
> 
> - -- 
> .. Be Seeing You,
> .. Chuck Rhode, Sheboygan, WI, USA
> .. Weather:  http://LacusVeris.com/WX
> .. 55° — Wind WSW 10 mph
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2
> 
> iEYEARECAAYFAl2aE+IACgkQYNv8YqSjllJHuwCfW+tQv04X3s8e6jE5gWZPqbeN
> kZgAn2nbhXFERp5rmIcEuO6yEvC8+HVF
> =bE0d
> -----END PGP SIGNATURE-----
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt



More information about the PyQt mailing list