Python, PyQT, understanding modules, classes, and objects... :)

 
0
 

Hi guys, still Noob here, so i apologize for not using the correct terminology. I will be as detailed and accurate as possible!

I've been using QT Designer, and been trying to figure out how to "combine" the GUI ive created with the python script I wrote before making a GUI.

I had my .py script made before I even knew about PyQT, QtGUI, and Qt Designer. My understanding on modules, classes, and objects are weak to say the least, as is my understanding on python also.

After visiting http://www.riverbankcomputing.co.uk/software/pyqt/intro I have a much better understanding of PyQT's modules classes and objects (and what a lot of them there are! LOL)

But that has not helped me figure out how to get my gui and program to work together?

To help narrow down my question, I am able to change my .uic to .py and further to .exe figured that out a few days ago, so i really need some help just understanding how to get my GUI buttons to "run/execute" parts of my script.. and pass some variables to it as well. If my thinking is correct, i think i need to make parts of my original script as "objects" in my GUI script?

My project is to build a driver dispatch SMS application. My program will fetch an email from gmail, parse and truncate it, then send the truncated chunks as a text message to a delivery driver as an sms text. The project is in two pieces, one piece is the GUI and the other is the part that gets email, processes it (as mentioned previously) and then sends it through twilio. Both parts work correctly seperately (although, im sure they are not the most efficient and professional looking).

My GUI has two main goals, one is to dispatch email orders to driver, and the other is to provide a regular texting gateway for dispatcher to text back and forth to drivers. I have a set of buttons designated for dispatching drivers who are scheduled to work that day. Then I have a text browser, a text edit, and a set of buttons that are designated for SMS'ing drivers who are scheduled to work that day.

The two things I am trying to figure out are:

1. when a "dispatch employee" button is pressed, I am trying to get the following to happen: A) i want it to run my "get email, process, send text" code and B) pass the employees phone number (im guessing as a variable) to the portion of code that communicates with twilio.

2. with the text edit, text browser and SMS Employee buttons, I would like for the SMS conversation to be displayed when a driver's button is selected, and then for any comments typed into the text edit area to be SMS'd to the driver who is selected when the "Send SMS button" is clicked. (I am going to add the "Send SMS button" as I just thought of that now.)

I will include, both, my GUI code(sorry, it is very long) and my program code... then revisit the question again... (for the millionth time LOL)


GUI code... SMStextdriver.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(570, 604)
        self.textBrowser = QtGui.QTextBrowser(Form)
        self.textBrowser.setGeometry(QtCore.QRect(0, 130, 561, 301))
        self.textBrowser.setObjectName(_fromUtf8("textBrowser"))
        self.textEdit = QtGui.QTextEdit(Form)
        self.textEdit.setGeometry(QtCore.QRect(0, 440, 561, 61))
        self.textEdit.setObjectName(_fromUtf8("textEdit"))
        self.layoutWidget = QtGui.QWidget(Form)
        self.layoutWidget.setGeometry(QtCore.QRect(0, 0, 561, 131))
        self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
        self.gridLayout = QtGui.QGridLayout(self.layoutWidget)
        self.gridLayout.setMargin(0)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.pushButton = QtGui.QPushButton(self.layoutWidget)
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
        self.lcdNumber = QtGui.QLCDNumber(self.layoutWidget)
        self.lcdNumber.setObjectName(_fromUtf8("lcdNumber"))
        self.gridLayout.addWidget(self.lcdNumber, 0, 1, 1, 1)
        self.line_2 = QtGui.QFrame(self.layoutWidget)
        self.line_2.setFrameShape(QtGui.QFrame.VLine)
        self.line_2.setFrameShadow(QtGui.QFrame.Sunken)
        self.line_2.setObjectName(_fromUtf8("line_2"))
        self.gridLayout.addWidget(self.line_2, 0, 2, 3, 1)
        self.pushButton_4 = QtGui.QPushButton(self.layoutWidget)
        self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))
        self.gridLayout.addWidget(self.pushButton_4, 0, 3, 1, 1)
        self.lcdNumber_6 = QtGui.QLCDNumber(self.layoutWidget)
        self.lcdNumber_6.setObjectName(_fromUtf8("lcdNumber_6"))
        self.gridLayout.addWidget(self.lcdNumber_6, 0, 4, 1, 1)
        self.pushButton_2 = QtGui.QPushButton(self.layoutWidget)
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.gridLayout.addWidget(self.pushButton_2, 1, 0, 1, 1)
        self.lcdNumber_2 = QtGui.QLCDNumber(self.layoutWidget)
        self.lcdNumber_2.setObjectName(_fromUtf8("lcdNumber_2"))
        self.gridLayout.addWidget(self.lcdNumber_2, 1, 1, 1, 1)
        self.pushButton_5 = QtGui.QPushButton(self.layoutWidget)
        self.pushButton_5.setObjectName(_fromUtf8("pushButton_5"))
        self.gridLayout.addWidget(self.pushButton_5, 1, 3, 1, 1)
        self.lcdNumber_5 = QtGui.QLCDNumber(self.layoutWidget)
        self.lcdNumber_5.setObjectName(_fromUtf8("lcdNumber_5"))
        self.gridLayout.addWidget(self.lcdNumber_5, 1, 4, 1, 1)
        self.pushButton_3 = QtGui.QPushButton(self.layoutWidget)
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.gridLayout.addWidget(self.pushButton_3, 2, 0, 1, 1)
        self.lcdNumber_3 = QtGui.QLCDNumber(self.layoutWidget)
        self.lcdNumber_3.setObjectName(_fromUtf8("lcdNumber_3"))
        self.gridLayout.addWidget(self.lcdNumber_3, 2, 1, 1, 1)
        self.pushButton_6 = QtGui.QPushButton(self.layoutWidget)
        self.pushButton_6.setObjectName(_fromUtf8("pushButton_6"))
        self.gridLayout.addWidget(self.pushButton_6, 2, 3, 1, 1)
        self.lcdNumber_4 = QtGui.QLCDNumber(self.layoutWidget)
        self.lcdNumber_4.setObjectName(_fromUtf8("lcdNumber_4"))
        self.gridLayout.addWidget(self.lcdNumber_4, 2, 4, 1, 1)
        self.line = QtGui.QFrame(self.layoutWidget)
        self.line.setFrameShape(QtGui.QFrame.HLine)
        self.line.setFrameShadow(QtGui.QFrame.Sunken)
        self.line.setObjectName(_fromUtf8("line"))
        self.gridLayout.addWidget(self.line, 3, 0, 1, 5)
        self.pushButton_15 = QtGui.QPushButton(Form)
        self.pushButton_15.setGeometry(QtCore.QRect(480, 570, 84, 25))
        self.pushButton_15.setObjectName(_fromUtf8("pushButton_15"))
        self.widget = QtGui.QWidget(Form)
        self.widget.setGeometry(QtCore.QRect(0, 510, 176, 89))
        self.widget.setObjectName(_fromUtf8("widget"))
        self.gridLayout_2 = QtGui.QGridLayout(self.widget)
        self.gridLayout_2.setMargin(0)
        self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
        self.pushButton_7 = QtGui.QPushButton(self.widget)
        self.pushButton_7.setObjectName(_fromUtf8("pushButton_7"))
        self.gridLayout_2.addWidget(self.pushButton_7, 0, 0, 1, 1)
        self.pushButton_10 = QtGui.QPushButton(self.widget)
        self.pushButton_10.setObjectName(_fromUtf8("pushButton_10"))
        self.gridLayout_2.addWidget(self.pushButton_10, 0, 1, 1, 1)
        self.pushButton_8 = QtGui.QPushButton(self.widget)
        self.pushButton_8.setObjectName(_fromUtf8("pushButton_8"))
        self.gridLayout_2.addWidget(self.pushButton_8, 1, 0, 1, 1)
        self.pushButton_12 = QtGui.QPushButton(self.widget)
        self.pushButton_12.setObjectName(_fromUtf8("pushButton_12"))
        self.gridLayout_2.addWidget(self.pushButton_12, 1, 1, 1, 1)
        self.pushButton_9 = QtGui.QPushButton(self.widget)
        self.pushButton_9.setObjectName(_fromUtf8("pushButton_9"))
        self.gridLayout_2.addWidget(self.pushButton_9, 2, 0, 1, 1)
        self.pushButton_11 = QtGui.QPushButton(self.widget)
        self.pushButton_11.setObjectName(_fromUtf8("pushButton_11"))
        self.gridLayout_2.addWidget(self.pushButton_11, 2, 1, 1, 1)
        self.widget1 = QtGui.QWidget(Form)
        self.widget1.setGeometry(QtCore.QRect(240, 510, 187, 91))
        self.widget1.setObjectName(_fromUtf8("widget1"))
        self.gridLayout_3 = QtGui.QGridLayout(self.widget1)
        self.gridLayout_3.setMargin(0)
        self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
        self.pushButton_13 = QtGui.QPushButton(self.widget1)
        self.pushButton_13.setObjectName(_fromUtf8("pushButton_13"))
        self.gridLayout_3.addWidget(self.pushButton_13, 0, 0, 1, 1)
        self.pushButton_14 = QtGui.QPushButton(self.widget1)
        self.pushButton_14.setObjectName(_fromUtf8("pushButton_14"))
        self.gridLayout_3.addWidget(self.pushButton_14, 1, 0, 1, 1)

        self.retranslateUi(Form)
        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", "Dispatch Emp 1", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_4.setText(QtGui.QApplication.translate("Form", "Dispatch Emp 4", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("Form", "Dispatch Emp 2", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_5.setText(QtGui.QApplication.translate("Form", "Dispatch Emp 5", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_3.setText(QtGui.QApplication.translate("Form", "Dispatch Emp 3", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_6.setText(QtGui.QApplication.translate("Form", "Dispatch Emp 6", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_15.setText(QtGui.QApplication.translate("Form", "End of Day", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_7.setText(QtGui.QApplication.translate("Form", "SMS Emp 1", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_10.setText(QtGui.QApplication.translate("Form", "SMS Emp 4", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_8.setText(QtGui.QApplication.translate("Form", "SMS Emp 2", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_12.setText(QtGui.QApplication.translate("Form", "SMS Emp 5", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_9.setText(QtGui.QApplication.translate("Form", "SMS Emp 3", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_11.setText(QtGui.QApplication.translate("Form", "SMS Emp 6", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_13.setText(QtGui.QApplication.translate("Form", "SMS DRIVER", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_14.setText(QtGui.QApplication.translate("Form", "SMS DRIVER 40 Minute Warning", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

and here is my "get, process, and send text.py" script (Still, tweaking it to clean up, and make more efficient over time as i learn)

import re import sys import time import email import quopri import imaplib from twilio.rest import TwilioRestClient # GET MAIL def extract_body(payload): if isinstance(payload,str): return payload else: return '\n'.join([extract_body(part.get_payload()) for part in payload]) conn = imaplib.IMAP4_SSL("imap.gmail.com", 993) conn.login("GMAIL USER ID HERE", "GMAIL Password here") conn.select() typ, data = conn.search(None, 'UNSEEN') try: for num in data[0].split(): typ, msg_data = conn.fetch(num, '(RFC822)') for response_part in msg_data: if isinstance(response_part, tuple): msg = email.message_from_string(response_part[1]) subject=msg['subject'] #not necessary print(subject) #not necessary payload=msg.get_payload() body=extract_body(payload) print(body) #not necessary removed=quopri.decodestring(body) #trying without stripped=re.sub('<[^<]+?>', '',removed) #trying without print(removed) #changed from stripped to try without # head, sep, tail = removed.partition('subject line.') #needs to be examined file=open("c:\\neworderup.txt", "w") file.write(removed) #changed from body writes file of cleaned and parsed data file.close() typ, response = conn.store(num, '+FLAGS', r'(\Seen)') finally: try: conn.close() except: pass conn.logout() # Need to experiment with quopri, could probably remove one instance of it. # Need to experiment with sub, could probably be removed also. file1=open("c:\\neworderup.txt", "r") toremove = file1.read() toquo=re.sub('<[^<]+?>', '', toremove) removed=quopri.decodestring(toquo) string=removed file1.close() split=string.split() joined=" ".join(string.split()) # removes xtra WS and empty lines parsed=joined #processed=parsed[parsed.index("Rate:"):parsed.index("Best,")] #parses string... no longer needed here. final = re.sub(r"\Rate:\s?","",parsed) #changed from processed file2=open("c:\\neworderupstep2.txt", "w") file2.write(final) #writes file of cleaned and parsed data file2.close() file3 = open('C:\\neworderupstep2.txt') # this section chunks the chunks = [] # file to 120 character lengths while "file is not empty": chunk = file3.read(110) if not chunk: break chunks.append(chunk) file3.close() # writes each chunk to own file and SMS's it for i,name in enumerate(chunks): file4 = open("C:\\neworderupchunked"+str(i+1)+".txt","w") file4.write(name+"\n") account_sid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Find these values at auth_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # [url]https://twilio.com/user/account[/url]
    client = TwilioRestClient(account_sid, auth_token)

    message = client.sms.messages.create(to="Employee Phone Number VAriable Here", from_="Twilio Number Here",
                                     body="%s" % (name+"\n"))

    file4.close()
    time.sleep(1.0)

exit()

Sorry for the long ugly code! :)

I don't need everything coded in, if someone could just write one of the dispatch button click actions for me, I can add the rest, and probably even adapt it for the SMStext buttons... but im also wondering how to get the driver/dispatch conversation displayed.. probably save to file, then open and append whenever a text between driver and dispatch happens.

Hope some of this makes sense..

thanks in advance for any help, advice, code! Cheers!

Featured Replies in this Discussion

  • Here is an example how to connect a button to a label ... ...
    Post Contains: Code
  • I downloaded the 32 bit version for Python 2.7 from: ... The Windows self installer is called: PySide-1.1.0qt474.win32-py2.7.exe It installs easily without problems.
    Post Contains: Links
  • I took vegaseat's sample code and made it even simpler: ... Here is the XML file "form_button_ ... " created by the Designer program: ... If you are mildly familiar with HTML or XML, it isn't that hard to understand this common Markup Language code.
    Post Contains: Links Code
  • Just one more example of using PySide and the QT Designer program can be found here: ...
    Post Contains: Links
 
1
 

Here is an example how to connect a button to a label ...

'''
run_button_label1.py

a simple loader for .ui XML files generated with PySide Designer
the Designer's XML file was saved as "button_label1.ui"

it contains a QMainWindow form with a QPushButton and a QLabel

select the QPushButton and use the Desiger's "Edit Signals/Slots" (F4) 
to connect (drag) the QPushButton signal via clicked()
to the QLabel slot via clear() 

# PySide is the official LGPL-licensed version of PyQT
tested with PySide474 and Python27/Python32
'''

from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtUiTools import QUiLoader

def on_click():
    label.setText("hello")

# create the application
app = QApplication([])

# create the ui loader
loader = QUiLoader()
# and load the form's ui file
widget = loader.load("button_label1.ui")
widget.show()

# create the pushbutton and label objects
# (for correct names check the .ui file)
button = widget.findChild(QPushButton, 'pushButton')
label = widget.findChild(QLabel, 'label')

# if the button is clicked clear and change the label text
# uses newer connect style (4.7)
button.clicked.connect(on_click)

# execute the application
app.exec_()
Comments
quick and direct
 
0
 

Hello Vegaseat! Thanks for editing and commenting on my post... I am going to look into pyside, right after this!

I found a tutorial, that seems to have pointed me in the right direction... covers, signals, slots, connections and methods/functions!

Here is a link that might be of use to others also!

I will post my final code when i finish... hopefully soon, but may take me forever! LOL

http://talk.maemo.org/showpost.php?p=515218&postcount=59

the info i am concentrating on is about halfway down through the tutorial...

"But, of course, nothing works! So we close out and decide we want those buttons to actually do something. We know we have 5 buttons, and 1 menu item, so we know we are going to need 6 connects. So lets try some:"

class MyForm(QtGui.QMainWindow):
        def __init__(self, parent=None):
                #build parent user interface
                QtGui.QWidget.__init__(self, parent)
                self.ui = Ui_MainWindow()
                self.ui.setupUi(self)

                #connect buttons
                QtCore.QObject.connect(self.ui.btnAdd, QtCore.SIGNAL('clicked()'), self.doAdd)
                QtCore.QObject.connect(self.ui.btnAllAdd, QtCore.SIGNAL('clicked()'), self.doAllAdd)
                QtCore.QObject.connect(self.ui.btnRemove, QtCore.SIGNAL('clicked()'), self.doRemove)
                QtCore.QObject.connect(self.ui.btnAllRemove, QtCore.SIGNAL('clicked()'), self.doAllRemove)
                QtCore.QObject.connect(self.ui.btnAddNew, QtCore.SIGNAL('clicked()'), self.doAddNew)
                QtCore.QObject.connect(self.ui.actionQuit, QtCore.SIGNAL('triggered()'), QtGui.qApp, QtCore.SLOT('quit()'))

and the following section as well:

"Now, we've connected all 6 items to something. But python has no idea what the things like "self.doAdd" and "self.doAllAdd" are. The only one of those connects that will work is the last one for the "Quit" menu item because we connected it to a built-in qt "quit" slot.

So, now we create various functions (also called methods) that correspond to the names we connected the buttons to:"

#Create Sub's
        def doAdd(self):
                add = 1
                for i in range(self.ui.listRight.count()): #let's not create duplicates, so lets do a search.
                        if self.ui.listRight.item(i).text() == self.ui.listLeft.currentItem().text():
                                add = 0
                if add: #Okay, it wasn't found.  Let's add it.
                        self.ui.listRight.addItem(self.ui.listLeft.currentItem().text())

        def doAllAdd(self): #This ones easy, just clear the right one, go through all the left items and add them.
                self.ui.listRight.clear() 
                for i in range(self.ui.listLeft.count()):
                        self.ui.listRight.addItem(self.ui.listLeft.item(i).text())

        def doRemove(self): #Easy again, just remove the selected item.
                self.ui.listRight.takeItem(self.ui.listRight.currentRow())

        def doAllRemove(self): #Super Easy.
                self.ui.listRight.clear()

        def doAddNew(self): #Pretty easy, just add to the left what is in the text box, then clear it out.
                self.ui.listLeft.addItem(self.ui.lineNew.text())
                self.ui.lineNew.clear()

The link takes you to the full tutorial! Maybe will benefit someone else!

 
0
 

The PyQT or PySide Designer creates an XML code file with extension .ui that really does not have to be translated to a Python code .py file. I find the the XML file more readable than the Python file you make from it. All you need to write is the UI loader program in Python that loads the forms and widgets and then acts on it.

You can quickly change the XML code with the Designer program. After a while you can actually edit the XML file directly with minor changes you want.

 
0
 

Hello again Vegas Eat!

I've been reading up on pyside and trying to install throughout the day... i keep getting error messages... I hope to have it up and running soon, it sounds great! Not that I understand to much about it yet, but i'm imagining it will make developing much smoother for me.

I'll keep you updated... thanks again for the additional information! :)

 
1
 

I downloaded the 32 bit version for Python 2.7 from:
http://qt-project.org/wiki/PySide_Binaries_Windows

The Windows self installer is called:
PySide-1.1.0qt474.win32-py2.7.exe

It installs easily without problems.

Comments
direct and worked
 
1
 

I took vegaseat's sample code and made it even simpler:

''' run_form_button_label1.py a simple loader for .ui XML files generated with PySide Designer the Designer's XML file was saved as "form_button_label1.ui" it contains a QWidget form with a QPushButton and a QLabel The QPushButton and QLabel are not connected using the Designer the connection is done by this loader programming code PySide is the official LGPL-licensed version of PyQT I downloaded the 32 bit version for Python 2.7 from: http://qt-project.org/wiki/PySide_Binaries_Windows
The Windows self installer is called:
PySide-1.1.0qt474.win32-py2.7.exe
this also installs the Designer program
'''

from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtUiTools import QUiLoader

def on_click():
    '''the button has been clicked, change the label text'''
    label.setText("hello")

# create the application
app = QApplication([])

# create the ui loader
loader = QUiLoader()
# and load the form's ui file created by Designer
widget = loader.load("form_button_label1.ui")
widget.show()

# create the pushbutton and label objects
# (for correct names check the .ui file)
button = widget.findChild(QPushButton, 'pushButton')
label = widget.findChild(QLabel, 'label')

# if the button is clicked, change the label text
# uses newer connect style (4.7)
button.clicked.connect(on_click)

# execute the application
app.exec_()

Here is the XML file "form_button_label1.ui" created by the Designer program:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>84</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>75</width>
     <height>23</height>
    </rect>
   </property>
   <property name="text">
    <string>PushButton</string>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>50</y>
     <width>46</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>TextLabel</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

If you are mildly familiar with HTML or XML, it isn't that hard to understand this common Markup Language code.

 
0
 

Thanks HiHe, reinstalled the download from the link you provided and everything went smooth this time! And thanks for revisiting vegaseats code, I would say i'm better with html than python, which actually doesnt say much! LOL Thanks again, im working it!

 
0
 

Actually, the ui_to_python translator program spits out rather complex Python code.

You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: