I build a lot of very basic QT repetitive programs at work with QT python then compile them with py2exe. These are used by my coworkers at controllers for another program. I am wonder how I could build a python interpreter that would convert simple commands into actual python code similar to the way Processing converts a simplified code into java.
For example the "simple code" file may read:
slider('Distance', 'dist', 50, 100, 'int')
button('Apply Changes', 'apply')
which I would then interpret into a pyQT program form using types below:
slider(label, name, min, max, type)
button(label, name)
These would all be written to new python file, which when run would generate the appropriate form. The part I am stuck on is how to interpret the "simple code" into python code.
Thanks in advance
Solution #1
The code below is uses the regex and split idea by SPEN-zar to identify the widget type, then parse the inputs to generate the necessary outputs. Obviously, this will be expanded upon to generate real pyQT file, but this is the basic demonstrates the basic logic.
Thank you for the help.
import re
input = ["slider('Distance', 'dist', 50, 100, 'int')", "button('Apply Changes', 'apply')"]
pattern = r"([a-z]+)\s*\((.*)\)"
rexp = re.compile(pattern)
for line in input:
content = rexp.findall(line)
if content[0][0] == 'slider':
params = content[0][1].split(',')
name = params[0]
label = params[1]
minimum = float(params[2])
maximum = float(params[3])
print 'Slider Type: name-%s, label-%s, min-%f, max-%f' % (name, label, minimum, maximum)
elif content[0][0] == 'button':
params = content[0][1].split(',')
name = params[0]
label = params[1]
print 'Button Type: name-%s, label-%s' % (name, label)
else:
print 'This widget type is not recognized'
Solution #2
After doing further research into blender's suggestion, I have modified the code below that uses a class to define a button. This class can then be easily added to the form as many times as needed. By building classes for all the types needed it would be easy to easy generate forms as well maintain and add to the library.
from PyQt4 import QtGui, QtCore
import sys
class Main(QtGui.QMainWindow):
def __init__(self, parent = None):
super(Main, self).__init__(parent)
# main button
self.addButton = QtGui.QPushButton('button to add other widgets')
self.addButton.clicked.connect(self.addWidget)
# scroll area widget contents - layout
self.scrollLayout = QtGui.QFormLayout()
# scroll area widget contents
self.scrollWidget = QtGui.QWidget()
self.scrollWidget.setLayout(self.scrollLayout)
# scroll area
self.scrollArea = QtGui.QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setWidget(self.scrollWidget)
# main layout
self.mainLayout = QtGui.QVBoxLayout()
# add all main to the main vLayout
self.mainLayout.addWidget(self.addButton)
self.mainLayout.addWidget(self.scrollArea)
# central widget
self.centralWidget = QtGui.QWidget()
self.centralWidget.setLayout(self.mainLayout)
# set central widget
self.setCentralWidget(self.centralWidget)
def addButton(self):
self.scrollLayout.addRow(Test())
class Test(QtGui.QWidget):
def __init__( self, parent=None):
super(Test, self).__init__(parent)
self.pushButton = QtGui.QPushButton('I am in Test widget')
self.pushButton.clicked.connect(self.testPush)
layout = QtGui.QHBoxLayout()
layout.addWidget(self.pushButton)
self.setLayout(layout)
def testPush(self):
print "The test button was pushed!"
app = QtGui.QApplication(sys.argv)
myWidget = Main()
for i in xrange(5):
myWidget.addButton()
myWidget.show()
app.exec_()