2

I need to restart my application when a button is clicked, but I'm having some problems with it. I've tried two methods:

  1. Tried this suggestion and it indeed restarts the application, but I get a Gtk_IS_INVISIBLE (widget) error for every widget, and all of them look different in the restarted application, with a very "old" look (similar to TkInter widgets). Is there a way so solve this error? Besides this, the application works fine.

  2. I also tried:

    subprocess.Popen("/home/pi/pywork/pyqt/of2.py")
    sys.exit(0)
    

    as suggested here, but I get the following error: OSError: [Errno 13] Permission denied. Is there a way to override this denied permission?

None of them seem to work properly. Is there a way to fix any of them? Do you know an alternative method to restart the application?

Community
  • 1
  • 1
Diogo Magalhães
  • 441
  • 1
  • 9
  • 19
  • 1
    Please clarify what you mean by "restart", because the two examples you give are very different. Do you actually need to create a completely *new* process? Or do you just need to create a new application object and main window within the *current* process? Or perhaps all you need to do is to create a new main window, but using the same application object? What actual problem are you trying solve? – ekhumoro Mar 19 '16 at 21:36
  • I want to close the current process and start a new one. I solved the widget errors on the first suggestion by setting a style on the app, so by placing `setStyle("GTK+")`, the widget errors went away. – Diogo Magalhães Mar 20 '16 at 13:59

2 Answers2

1

You could use QProcess.startDetached:

QProcess.startDetached("/home/pi/pywork/pyqt/of2.py")
sys.exit(0)

You also have to properly add the shebang to your python script:

#!/usr/bin/env python
Community
  • 1
  • 1
Daniele Pantaleone
  • 2,657
  • 22
  • 33
1

The second method gives an error because the file is not executable. You could fix that, but it is probably more robust to just re-run the script using the same python executable. It would also be a good idea to avoid hard-coding the script path.

Here is a simple demo script that implements all that:

import sys, os, subprocess
from PyQt4 import QtCore, QtGui

FILEPATH = os.path.abspath(__file__)

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.button = QtGui.QPushButton(
            'Restart [PID: %d]' % QtGui.qApp.applicationPid(), self)
        self.button.clicked.connect(self.handleButton)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.button)

    def handleButton(self):
        try:
            subprocess.Popen([sys.executable, FILEPATH])
        except OSError as exception:
            print('ERROR: could not restart aplication:')
            print('  %s' % str(exception))
        else:
            QtGui.qApp.quit()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(600, 400, 100, 50)
    window.show()
    sys.exit(app.exec_())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336