0

Is it possible to pause a python script when certain conditions are met so that a user can enter in an input through a popup window, preferably a pyside2 slider or a qlineedit and then resume the script after the user has given the value.

The only thing I could find was qMessageBox question but the only options I can put in that are 2 buttons which in this case isn't useful.

Any help will be highly appreciated.

Thanks!!

dege
  • 65
  • 9
  • From what I understand you want a custom QMessageBox, you could show an image of what you want, on the other hand if it is a QSlider, when should the QMessageBox be closed? and the same for a QLineEdit – eyllanesc Sep 19 '18 at 18:32
  • I don't want a QMessageBox, I found that's the only thing I found in PySide2 that pauses until a user returns with a yes or no. In my case I want that to happen but either with a slider or a qlinedit – dege Sep 19 '18 at 18:34
  • 1
    Why do you think it pauses ?, QMessageBox does not pause anything, the application keeps running but the window should freeze, what it does is that the next line of code does not run while it remains open that is different to pause. The solution is to use QDialog as indicated in the answer, but I stress that the application is not being paused, it is only being prevented from executing the next line. – eyllanesc Sep 19 '18 at 18:39
  • yeah sorry, my python terminology is seriously lacking, I did mean to prevent the next line from executing. Thanks eyllanesc – dege Sep 20 '18 at 03:18

1 Answers1

1

You can use a QDialog. http://pyside.github.io/docs/pyside/PySide/QtGui/QDialog.html

https://wiki.qt.io/Qt_for_Python_Tutorial_SimpleDialog

Do something like below.

from PySide import QtGui  # from PySide2 import QtWidgets or from qtpy import QtWidgets

dialog = QtGui.QDialog()
lay = QtGui.QFormLayout()
dialog.setLayout(lay)

slider = QtGui.QSlider()
lay.addRow(QtGui.QLabel('Slider'), slider)

... # Accept buttons

ans = dialog.exec_()  # This will block until the dialog closes
# Check if dialog was accepted?

value = slider.value()

... # Continue code.

Similar to the exec_ QMessageBox is this exmaple. https://gist.github.com/tcrowson/8152683242018378a00b

You can probably use a QMessageBox and set the layout to change the look.

What is going on?

Essential PySide works by running an event loop. It runs this infinite while loop that takes events off of a queue an processes them. Any mouse movement or button click is an event.

app = QApplication([])

app.exec_()  # This is running the event loop until the application closes.
print('here')  # This won't print until the application closes

You could manually reproduce this with any widget.

app = QApplication([])  # Required may be automatic with IPython

slider = QSlider()  # No Parent
slider.show()

# Slider is not visible until the application processes the slider.show() event
app.processEvents()
while slider.isVisible():  # When user clicks the X on the slider it will hide the slider
    app.processEvents()  # Process events like the mouse moving the slider

print('here')  # This won't print until the Slider closes

... # Continue code script
justengel
  • 6,132
  • 4
  • 26
  • 42
  • using `app.processEvents()` stinks, it is not recommended to use processEvents (), the GUI should be able to handle it, and not force it. – eyllanesc Sep 19 '18 at 18:46
  • @eyllanesc Correct. I was just explaining what was happening in the script. – justengel Sep 19 '18 at 18:47
  • @justengel read https://stackoverflow.com/questions/2150966/should-i-use-qcoreapplicationprocessevents-or-qapplicationprocessevents because that is not correct, then he will try to use it and boom at some point explodes. – eyllanesc Sep 19 '18 at 18:48
  • @justengel I want to give you a downvote, `while slider.isVisible(): app.processEvents()` does not equal an `exec_()` by nowhere – eyllanesc Sep 19 '18 at 18:50
  • @eyllanesc I am guessing that the person who asked the question is not really running a GUI. The question indicates that he is running a script and just wants a widget to display temporarily. If this is the case the QDialog is what he should be using. The application code was merely an example of an infinite loop. – justengel Sep 19 '18 at 18:50
  • @justengel A GUI can be part of a script, and for any widget to show up it needs a QApplication, so what you point out is not correct. I agree with you that the solution is QDialog but its explanation stinks. – eyllanesc Sep 19 '18 at 18:52
  • @justengel Instead of using processEvents you could use QEventLoop. – eyllanesc Sep 19 '18 at 18:54
  • @justengel the while still stinking, an improvement would be the following: `slider = QtWidgets.QSlider(QtCore.Qt.WA_DeleteOnClose) slider.show() loop = QtCore.QEvenLoop() slider.destroyed.connect(loop.quit) loop.exec_()` – eyllanesc Sep 19 '18 at 18:59
  • @eyllanesc Why? Why bother creating an entire QEventLoop. You are missing the entire point of my explanation and are getting hung up on one simple example. The "QDialog" my main focus for the answer of this question. It answers the question. The app.processEvents() is merely an example of what is happening in the background. It is showing a while loop to show that `exec_()` is blocking. The stack overflow question you previously referred to involves threading. Threads and GUIs are way outside the realm of this question. – justengel Sep 19 '18 at 19:00
  • @justengel You should not use processEvents for any reason, with or without threads, the explanation is part of the answer, if you want to explain could do it in pseudocodigo without using processEvents or slider.isVisible(), for example: `while isRunning: process events` – eyllanesc Sep 19 '18 at 19:03
  • @eyllanesc Your example `slider = QtWidgets.QSlider(QtCore.Qt.WA_DeleteOnClose)` doesn't even work. When the slider closes it is destroyed. Once it is destroyed you can't get the value from the slider. The question is regarding a script that temporarily asks the user for some input. If the widget is deleted you can't get the input without another function and signal to connect to. That is overly complicated for this question. – justengel Sep 19 '18 at 19:04
  • @justengel As I said it is an idea, my position is as follows, avoid using processEvents, use a pseudocode so it is general and do not fall into the error of promoting bad practice. There I will remove my downvote and give it an upvote (I was going to give it but I saw that), for me the answer as correct is QDialog as it points out. – eyllanesc Sep 19 '18 at 19:06