how to call a python script on button click using

2019-02-23 20:20发布

问题:

I have created a form using PyQt4 which has a push button. On this push button I want to call another python script which looks like this:

File1.py:

import sys
from PyQt4 import QtCore, QtGui


from file1_ui import Ui_Form


class MyForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())

File1_ui.py

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(400, 300)
        self.pushButton = QtGui.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(120, 200, 95, 20))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))

        self.retranslateUi(Form)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), Form.close)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("Form", "Close", None, QtGui.QApplication.UnicodeUTF8))

File2.py

import sys
from PyQt4 import Qt
from taurus.qt.qtgui.application import TaurusApplication

app = TaurusApplication(sys.argv)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)

from taurus.qt.qtgui.panel import TaurusForm

panel = TaurusForm()

model = [ 'test/i1/1/%s' % p for p in props ]
panel.setModel(model)

panel.show()
sys.exit(app.exec_())

File1_ui.py is created from the Qtdesigner and then I am using File1.py to execute it.So File2.py when executed alone opens up a panel and displays few attributes.I want this script to be called on the button click in the first form(file1.py) which I created using Qtdesigner.Could you let me know how I could achieve this functionality.Thanks.

回答1:

You will need to make some modifications to File2.py to make the appropriate calls depending on whether it is running standalone or not. When you are launching the script via File1.py there will already be a QApplication instance with event loop running, so trying to create another and run its event loop will cause problems.

Firstly, move the core part of your script into its own function. This will allow you to easily call it from File1.py. You can then handle the case where the script is running standalone and needs to create a QApplication instance and start its event loop. (I am not familiar the the taurus library you are using, but you can probably substitute TaurusApplication for QtGui.QApplication)

File2.py:

import sys
from PyQt4 import QtCore, QtGui

def runscript():
    panel = QtGui.QWidget()
    layout = QtGui.QHBoxLayout(panel)
    return panel # Must return reference or panel will be deleted upon return


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    panel = runscript()
    panel.show()
    sys.exit(app.exec_())

Assuming your files are in the same directory you can simply write import File2 and use File2.runscript() to run your code. You then just need to connect the function to your pushbuttons clicked() signal to run it. The only problem here is that the reference to the QWidget returned from the runscript() function will be lost (and the object deleted) if you connect directly to runscript(). For this reason I created a method launch_script() which saves a reference in MyForm.

File1.py:

import sys
from PyQt4 import QtCore, QtGui

from file1_ui import Ui_Form
import File2

class MyForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)

        # This is a bit of a hack.
        self.ui.pushButton.clicked.connect(self.launch_script)

    def launch_script(self):
        self.panel = File2.runscript()
        self.panel.show()


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())

I don't use Qt Designer, so I don't know the correct way to go about connecting the signal to launch_script(). The code I have written should work, but obviously violates OOP principles and is dependent on the name of the pushbutton widget assigned by the software.