GUI Programming with PySide

In this example, we develop a simple GUI dialog which creates a PFC model. The pyside Python extension module provides bindings to the Qt GUI programming library used by PFC.

First we import the itasca module and some submodules from the pyside2 package.

from PySide2 import QtCore, QtGui, QtWidgets, shiboken2

import itasca as it

To incorporate the dialog we are creating into the PFC GUI we need to get access to the Itasca GUI doc widget.

dockWidget = it.dockWidget("Demo GUI","",True)

dockWidget = shiboken2.wrapInstance(int(dockWidget),QtWidgets.QDockWidget)

widget = dockWidget.widget()

Next we define our dialog as a derived class of the QtGui.QWidget class.

class Window(QtWidgets.QWidget):

    def __init__(self, parent = None):

        QtWidgets.QWidget.__init__(self, parent)



        mainLayout = QtWidgets.QVBoxLayout()

        self.setLayout(mainLayout)



        self.setWindowTitle(self.tr("Demo GUI"))



        verticalGroupBox = QtWidgets.QGroupBox("Settings")

        layout1 = QtWidgets.QVBoxLayout()

        ballLimit = 10000

        msg = "Number of balls (between {} and {}):"

        labelBalls = QtWidgets.QLabel(msg.format(0, ballLimit));

        layout1.addWidget(labelBalls)

        spinBox = QtWidgets.QSpinBox(self)

        spinBox.setRange(0, ballLimit)

        spinBox.setValue(1000)

        layout1.addWidget(spinBox)

        verticalGroupBox.setLayout(layout1)

        mainLayout.addWidget(verticalGroupBox)



        horizontalGroupBox = QtWidgets.QGroupBox("Actions")

        layout = QtWidgets.QHBoxLayout()

        buttons = []

        for i in range(4):

            button = QtWidgets.QPushButton("Button %d" % (i + 1))

            layout.addWidget(button)

            buttons.append(button)

        horizontalGroupBox.setLayout(layout)

        mainLayout.addWidget(horizontalGroupBox)



        #change the name of the first button to new and connect to a command

        buttons[0].setText("New")

        def onButton0():

            it.command("model new")

        buttons[0].clicked.connect(onButton0)



        #change the names of the later buttons

        buttons[1].setText("Domain")

        def onButton1():

            it.command("model domain extent -10 10")

        buttons[1].clicked.connect(onButton1)



        buttons[2].setText("Generate Balls")

        def onButton2():

            nballs = spinBox.value()

            try:

                it.command("ball generate number {}".format(nballs))

            except RuntimeError as error:

                warning_box = QtWidgets.QMessageBox(main)

                msg = "A PFC error has occurred: {}"

                warning_box.setText(msg.format(error))

                warning_box.show()

        buttons[2].clicked.connect(onButton2)



        buttons[3].setText("Show Balls")

        def onButton3():

            it.command('''

                plot create

                plot clear

                plot active on

                plot background 'white'

                plot item create ball

                plot show''')

        buttons[3].clicked.connect(onButton3)

Finally, we connect our dialog to the PFC GUI as a dockable window and bring it to the top level.

widget.layout().addWidget(Window())

dockWidget.show()

dockWidget.raise_()

Clicking the New, Domain, Generate Balls and Show Balls buttons in sequence results in the image below.

../../../../../../../_images/gui_ex.png

Example File

The source code for the examples here is gui_example.py.