简体   繁体   中英

Interpreting simple code to python code

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_()

Have you tried just parsing it into a .ui format? That is XML, which is pretty straightforward.

Whichever output format you prefer, try PLY for the lexing and parsing. Otherwise, just use a regular expression to search for the substring with "(" ")" surrounding it and use .split(',') to get the arguments. That's my take.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM