Hi! Hope you're enjoying this blog. I have a new home at www.goldsborough.me. Be sure to also check by there for new posts <3
Showing posts with label fully-functioning. Show all posts
Showing posts with label fully-functioning. Show all posts

Thursday, September 5, 2013

Fully functional PyQt address book

Hi, just wanted to post the code for a program I did a little while ago. It's an address book that let's you store some data about a person. The buttons are in tile-style and a button get's added dynamically when you create a new contact. Have fun.

import sys,pickle,time
from PyQt4 import QtGui, QtCore


f = open("contacts.txt","rb")
try:
    contacts = pickle.loads(f.read())
    print("1")
except:
    print("2")
    contacts = {}
finally:
    f.close()

class New(QtGui.QDialog):

    def __init__(self,parent=None):
        global nvar,cvar,wvar,ovar
        
        QtGui.QDialog.__init__(self,parent)

        self.initUI()

        nvar = False
        cvar = False
        wvar = False
        ovar = False

    def initUI(self):

        self.name = QtGui.QPushButton("Name",self)
        self.name.clicked.connect(self.Name)

        self.fname = QtGui.QLabel("First name",self)
        self.fnameline = QtGui.QLineEdit(self)

        self.lname = QtGui.QLabel("Last name",self)
        self.lnameline = QtGui.QLineEdit(self)

        self.contact = QtGui.QPushButton("Contact",self)
        self.contact.clicked.connect(self.Contact)

        self.num1 = QtGui.QLabel("Telephone number 1",self)
        self.numline1 = QtGui.QLineEdit(self)

        self.numtype1 = QtGui.QComboBox(self)

        self.numtype1.addItem("Mobile")
        self.numtype1.addItem("Work")
        self.numtype1.addItem("Home")
        self.numtype1.addItem("Fax")

        self.num2 = QtGui.QLabel("Telephone number 2",self)
        self.numline2 = QtGui.QLineEdit(self)

        self.numtype2 = QtGui.QComboBox(self)

        self.numtype2.addItem("Mobile")
        self.numtype2.addItem("Work")
        self.numtype2.addItem("Home")
        self.numtype2.addItem("Fax")

        self.email = QtGui.QLabel("Email",self)
        self.emailline = QtGui.QLineEdit(self)

        self.work = QtGui.QPushButton("Work",self)
        self.work.clicked.connect(self.Work)

        self.title = QtGui.QLabel("Title",self)
        self.titleline = QtGui.QLineEdit(self)

        self.company = QtGui.QLabel("Company",self)
        self.companyline = QtGui.QLineEdit(self)

        self.position = QtGui.QLabel("Position",self)
        self.positionline = QtGui.QLineEdit(self)

        self.compsite = QtGui.QLabel("Company Website",self)
        self.compsiteline = QtGui.QLineEdit(self)

        self.other = QtGui.QPushButton("Other",self)
        self.other.clicked.connect(self.Other)

        self.address = QtGui.QLabel("Address",self)
        self.addressline = QtGui.QLineEdit(self)

        self.website = QtGui.QLabel("Website",self)
        self.websiteline = QtGui.QLineEdit(self)

        self.birthday = QtGui.QLabel("Birthday",self)
        self.birthdayline = QtGui.QDateEdit(self)

        self.notes = QtGui.QLabel("Notes",self)
        self.notesline = QtGui.QTextEdit(self)

        self.save = QtGui.QPushButton("Save",self)
        self.save.clicked.connect(self.Save)
        
        self.cancel = QtGui.QPushButton("Cancel",self)
        self.cancel.clicked.connect(lambda: self.hide())

        sub = [self.fname,self.fnameline,self.lname,self.lnameline,
               self.num1,self.numline1,self.numtype1,self.num2,
               self.numline2,self.numtype2,self.email,self.emailline,
               self.title,self.titleline,self.company,
               self.companyline,self.position,self.positionline,self.compsite,
               self.compsiteline,self.address,self.addressline,self.website,
               self.websiteline,self.birthday,self.birthdayline,self.notes,
               self.notesline]

        main = [self.name,self.contact,self.work,self.other]

        widgets = [self.name,self.fname,self.fnameline,self.lname,self.lnameline,
                 self.contact,self.num1,self.numline1,self.numtype1,self.num2,
                 self.numline2,self.numtype2,self.email,self.emailline,
                 self.work,self.title,self.titleline,self.company,
                 self.companyline,self.position,self.positionline,self.compsite,
                 self.compsiteline,self.other,self.address,self.addressline,self.website,
               self.websiteline,self.birthday,self.birthdayline,self.notes,
               self.notesline]

        for i in sub:
            i.hide()

        grid = QtGui.QGridLayout(self)

        pos = 0

        for i in widgets:
            grid.addWidget(i,pos,0,1,2)
            pos +=1

        grid.addWidget(self.save,pos,0,1,1)
        grid.addWidget(self.cancel,pos,1,1,1)

        self.setLayout(grid)

        self.setGeometry(300,200,175,100)
        self.setWindowTitle("Add contact")
        self.setStyleSheet("font-size:13px")

    def Name(self):
        global nvar
        
        if nvar == False:
            self.fname.show()
            self.fnameline.show()
            self.lname.show()
            self.lnameline.show()

            nvar = True
            
        else:
            self.fname.hide()
            self.fnameline.hide()
            self.lname.hide()
            self.lnameline.hide()

            nvar = False

        self.resize(175,100)

    def Contact(self):
        global cvar
        
        if cvar == False:
            self.num1.show()
            self.numline1.show()
            self.numtype1.show()
            self.num2.show()
            self.numline2.show()
            self.numtype2.show()
            self.email.show()
            self.emailline.show()

            cvar = True
            
        else:
            self.num1.hide()
            self.numline1.hide()
            self.numtype1.hide()
            self.num2.hide()
            self.numline2.hide()
            self.numtype2.hide()
            self.email.hide()
            self.emailline.hide()

            cvar = False

        self.resize(175,100)

    def Work(self):
        global wvar
        
        if wvar == False:
            self.title.show()
            self.titleline.show()
            self.company.show()
            self.companyline.show()
            self.position.show()
            self.positionline.show()
            self.compsite.show()
            self.compsiteline.show()

            wvar = True
            
        else:
            self.title.hide()
            self.titleline.hide()
            self.company.hide()
            self.companyline.hide()
            self.position.hide()
            self.positionline.hide()
            self.compsite.hide()
            self.compsiteline.hide()

            wvar = False

        self.resize(175,100)

    def Other(self):
        global ovar

        if ovar == False:
            self.address.show()
            self.addressline.show()
            self.website.show()
            self.websiteline.show()
            self.birthday.show()
            self.birthdayline.show()
            self.notes.show()
            self.notesline.show()

            ovar = True

        else:
            self.address.hide()
            self.addressline.hide()
            self.website.hide()
            self.websiteline.hide()
            self.birthday.hide()
            self.birthdayline.hide()
            self.notes.hide()
            self.notesline.hide()

            ovar = False

        self.resize(175,100)


    def Save(self):
        global contacts,button

        name = self.fnameline.text() + " " + self.lnameline.text()
        fname = self.fnameline.text()
        lname = self.lnameline.text()
        num1 = self.numline1.text()
        numtype1 = self.numtype1.currentIndex()
        num2 = self.numline2.text()
        numtype2 = self.numtype2.currentIndex()
        email = self.emailline.text()
        title = self.titleline.text()
        company = self.companyline.text()
        position = self.positionline.text()
        compsite = self.compsiteline.text()
        address = self.addressline.text()
        birthday = self.birthdayline.date()
        notes = self.notesline.toPlainText()

        if button == "+":
            contacts[name] = {"First name":fname,
                              "Last name":lname,
                              "Telephone number 1":num1,
                              "Type 1":numtype1,
                              "Telephone number 2":num2,
                              "Type 2":numtype2,
                              "Email":email,
                              "Title":title,
                              "Company":company,
                              "Position":position,
                              "Company Website":compsite,
                              "Address":address,
                              "Birthday":birthday,
                              "Notes":notes
                              }
        else:
            del contacts[button]
            contacts[name] = {"First name":fname,
                              "Last name":lname,
                              "Telephone number 1":num1,
                              "Type 1":numtype1,
                              "Telephone number 2":num2,
                              "Type 2":numtype2,
                              "Email":email,
                              "Title":title,
                              "Company":company,
                              "Position":position,
                              "Company Website":compsite,
                              "Address":address,
                              "Birthday":birthday,
                              "Notes":notes
                              }

        f = open("contacts.txt","wb")
        pickle.dump(contacts,f)
        f.close()
        
        self.close()
        
class Main(QtGui.QMainWindow):

    def __init__(self,parent=None):
        QtGui.QMainWindow.__init__(self,parent)
        self.initUI()

    def initUI(self):
        global contacts
        
        centralwidget = QtGui.QWidget()

        self.timer = QtCore.QTimer(self)
        self.timer.start(10)
        self.timer.timeout.connect(self.Hover)

        self.add = QtGui.QPushButton("+",self)
        self.add.setStyleSheet("font-size:40px;background-color:#333333;border: 2px solid #222222")
        self.add.setFixedSize(100,100)

        self.add.clicked.connect(self.Add)

        self.grid = QtGui.QGridLayout()

        self.grid.addWidget(self.add,0,0)
        
        centralwidget.setLayout(self.grid)

        if contacts:
            self.addTile()

        self.setCentralWidget(centralwidget)
     
#---------Window settings --------------------------------
        
        self.setGeometry(300,300,500,100)
        self.setWindowTitle("PyTact")

    def clickContact(self):
        global contacts, button

        sender = self.sender()
        
        ind = self.sender().text().index("\n")
        button = self.sender().text()[:ind] + self.sender().text()[ind+1:]
        
        contact_id = contacts[button]

        self.timer.start(150)
        sender.setStyleSheet("font-size:15px;background-color:#666666;border: 2px solid #555555")

        new = New(self)

        fname = contact_id["First name"]
        new.fnameline.setText(fname)
        lname = contact_id["Last name"]
        new.lnameline.setText(lname)
        num1 = contact_id["Telephone number 1"]
        new.numline1.setText(num1)
        numtype1 = contact_id["Type 1"]
        new.numtype1.setCurrentIndex(numtype1)
        num2 = contact_id["Telephone number 2"]
        new.numline2.setText(num2)
        numtype2 = contact_id["Type 2"]
        new.numtype2.setCurrentIndex(numtype2)
        email = contact_id["Email"]
        new.emailline.setText(email)
        title = contact_id["Title"]
        new.titleline.setText(title)
        company = contact_id["Company"]
        new.companyline.setText(company)
        position = contact_id["Position"]
        new.positionline.setText(position)
        compsite = contact_id["Company Website"]
        new.compsiteline.setText(compsite)
        address = contact_id["Address"]
        new.addressline.setText(address)
        birthday = contact_id["Birthday"]
        new.birthdayline.setDate(birthday)
        notes = contact_id["Notes"]
        new.notesline.setText(notes)

        new.show()

        new.save.clicked.connect(self.addTile)

    def ContextMenu(self):
        global sender
        sender = self.sender()
        
        self.menu = QtGui.QMenu(self)

        remove = QtGui.QAction("Remove",self)
        remove.triggered.connect(self.Remove)

        self.menu.addAction(remove)

        self.menu.show()

    def Remove(self):
        global sender
        global contacts

        del contacts[sender.text()]

        sender.setParent(None)
        
    def addTile(self):
        global contacts
        
        for i in reversed(range(self.grid.count())):
            self.grid.itemAt(i).widget().setParent(None)

        self.grid.addWidget(self.add,0,0)

        h = 1
        v = 0

        for i in contacts.keys():

            ind = i.rindex(" ")
            t = i[:ind]+ "\n" + i[ind:]
            
            b = QtGui.QPushButton(t,self)
            b.setStyleSheet("color:#0191C8;font-size:15px;background-color:#333333;border: 2px solid #222222")
            b.setFixedSize(100,100)
            b.clicked.connect(self.clickContact)

            b.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
            b.customContextMenuRequested.connect(self.ContextMenu)

            self.grid.addWidget(b,v,h)

            h += 1

            if h > 3 and h % 4 == 0:
                v += 1
                h = 0

    def Add(self):
        global button
        
        self.timer.start(150)
        self.add.setStyleSheet("color:#0191C8;font-size:40px;background-color:#666666;border: 2px solid #555555")

        button = self.sender().text()
        
        new = New(self)
        new.show()

        new.save.clicked.connect(self.addTile)

    def Hover(self):
        self.timer.start(10)
        for i in reversed(range(self.grid.count())):
            if i > 0:
                if self.grid.itemAt(i).widget().underMouse() == True:
                    self.grid.itemAt(i).widget().setStyleSheet("color:#0191C8;font-size:15px;background-color:#444444;border: 2px solid #333333")
                else:
                    self.grid.itemAt(i).widget().setStyleSheet("color:#0191C8;font-size:15px;background-color:#333333;border: 2px solid #222222")
            else:
                if self.add.underMouse() == True:
                    self.add.setStyleSheet("color:#0191C8;font-size:40px;background-color:#444444;border: 2px solid #333333")
                else:
                    self.add.setStyleSheet("color:#0191C8;font-size:40px;background-color:#333333;border: 2px solid #222222")


def main():
    app = QtGui.QApplication(sys.argv)
    main= Main()
    main.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

Saturday, August 17, 2013

Fully functional PyQt Email App

Hey there. In my last post I showed you how to send an email in Python, and in this one I'm just going to share a program with you that I made. It's basically a GUI email sender. I made a login window that shows up first and connects to the smpt server (I have radio buttons for Windows Mail, Yahoo Mail and Google Mail) and then the main program where you send the email. The hardest part was implementing a way of attaching files and also displaying them in the window, like if you attach a .doc file, it shows the image of a file with ".doc" on it. A nice thing is however if you attach a .png image, it shows a miniature version of it.

Have fun:


import sys
import os
import time

import smtplib
import mimetypes

from email import encoders
from email.utils import formatdate
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

from PyQt4 import QtGui, QtCore

attachments = []
labels = []

class Login(QtGui.QDialog):
    def __init__(self,parent = None):
        QtGui.QDialog.__init__(self, parent)
        
        self.initUI()

    def initUI(self):

        self.live = QtGui.QRadioButton("Windows Live",self)
        self.gmail = QtGui.QRadioButton("Google Mail",self)
        self.yahoo = QtGui.QRadioButton("Yahoo! Mail",self)

        e = [self.live,self.gmail,self.yahoo]

        for i in e:
            i.clicked.connect(self.Email)

        self.userl = QtGui.QLabel("E-mail:",self)
        self.user = QtGui.QLineEdit(self)

        self.passl = QtGui.QLabel("Password:",self)
        
        self.passw = QtGui.QLineEdit(self)
        self.passw.setEchoMode(self.passw.Password)

        self.echo = QtGui.QCheckBox("Show/Hide password",self)
        self.echo.stateChanged.connect(self.Echo)

        self.go = QtGui.QPushButton("Login",self)
        self.go.clicked.connect(self.Login)

        grid = QtGui.QGridLayout()

        grid.addWidget(self.live,0,0)
        grid.addWidget(self.gmail,0,1)
        grid.addWidget(self.yahoo,0,2)
        grid.addWidget(self.userl,1,0,1,1)
        grid.addWidget(self.user,1,1,1,2)
        grid.addWidget(self.passw,2,1,1,2)
        grid.addWidget(self.passl,2,0,1,1)
        grid.addWidget(self.echo,3,0,1,2)
        grid.addWidget(self.go,3,2)

        self.setLayout(grid)

        self.setGeometry(300,300,350,200)
        self.setWindowTitle("PyMail Login")
        self.setWindowIcon(QtGui.QIcon("PyMail"))
        self.setStyleSheet("font-size:15px;")

    def Echo(self,state):
        if state == QtCore.Qt.Checked:
            self.passw.setEchoMode(self.passw.Normal)
        else:
            self.passw.setEchoMode(self.passw.Password)

    def Email(self):
        global account
        account = self.sender().text()

    def Login(self):
        global account
        global server
        global user

        user = self.user.text()

        if account == "Windows Live":
            server = smtplib.SMTP('smtp.live.com',25)

        elif account == "Google Mail":
            server = smtplib.SMTP('smtp.gmail.com',25)

        elif account == "Yahoo! Mail":
            server = smtplib.SMTP('smtp.mail.yahoo.com',465)

        try:    
            server.ehlo()
            server.starttls()
            server.ehlo()
            server.login(user, self.passw.text())

            self.hide()

            main = Main(self)
            main.show()
            
        except smtplib.SMTPException:
            msg = QtGui.QMessageBox.critical(self, 'Login Failed',
            "Username/Password combination incorrect", QtGui.QMessageBox.Ok | 
            QtGui.QMessageBox.Retry, QtGui.QMessageBox.Ok)

            if msg == QtGui.QMessageBox.Retry:
                self.Login()
        
class Main(QtGui.QMainWindow):

    def __init__(self,parent=None):
        QtGui.QMainWindow.__init__(self,parent)
        self.initUI()

    def initUI(self):
        global user

        self.send = QtGui.QPushButton("Send",self)
        self.send.clicked.connect(self.Send)

        self.from_label = QtGui.QLabel("From",self)

        self.to_label = QtGui.QLabel("To",self)

        self.subject_label = QtGui.QLabel("Subject",self)

        self.from_addr = QtGui.QLineEdit(self)
        self.from_addr.setText(user)

        self.to_addr = QtGui.QLineEdit(self)
        self.to_addr.setPlaceholderText("godfather@corleone.it")

        self.subject = QtGui.QLineEdit(self)
        self.subject.setPlaceholderText("I got an offer you can't refuse")

        self.image = QtGui.QPushButton("Attach file",self)
        self.image.clicked.connect(self.Image)
        
        self.text = QtGui.QTextEdit(self)

        centralwidget = QtGui.QWidget()

        self.grid = QtGui.QGridLayout()

        self.grid.addWidget(self.from_label,0,0)
        self.grid.addWidget(self.from_addr,1,0)
        self.grid.addWidget(self.to_label,2,0)
        self.grid.addWidget(self.to_addr,3,0)
        self.grid.addWidget(self.subject_label,4,0)
        self.grid.addWidget(self.subject,5,0)
        self.grid.addWidget(self.image,6,0)
        self.grid.addWidget(self.text,8,0)
        self.grid.addWidget(self.send,9,0)

        centralwidget.setLayout(self.grid)

        self.setCentralWidget(centralwidget)


#---------Window settings --------------------------------
        
        self.setGeometry(300,300,500,500)
        self.setWindowTitle("PyMail")
        self.setWindowIcon(QtGui.QIcon("PyMail"))
        self.setStyleSheet("font-size:15px")

    def ContextMenu(self):
        global sender
        sender = self.sender()
        
        self.menu = QtGui.QMenu(self)

        remove = QtGui.QAction("Remove",self)
        remove.triggered.connect(self.Remove)

        self.menu.addAction(remove)

        self.menu.show()

    def Remove(self):
        global sender
        global pos
        global labels
        global attachments

        pos -= 1

        ind = labels.index(sender)

        attachments.remove(attachments[ind])

        labels.remove(sender)

        sender.setParent(None)

    def Image(self):
        global path
        global attachments
        global labels
        global filetype
        global l

        path = QtGui.QFileDialog.getOpenFileName(self, "Attach file","/home/")

        if path:
            
            attachments.append(path)

            filetype = path[path.rindex(".")+1:]

            if filetype == "png":
                pic = QtGui.QPixmap(path)
            else:
                if filetype+".png" in os.listdir("C:/Python32/python/pyqt/PyMail/48px/"):
                    print("normal")
                    pic = QtGui.QPixmap("C:/Python32/python/pyqt/PyMail/48px/"+filetype+".png")
                else:
                    print("weird")
                    pic = QtGui.QPixmap("C:/Python32/python/pyqt/PyMail/48px/_blank.png")
                    
            a = QtGui.QLabel(path,self)
            a.setScaledContents(True)
            a.setFixedSize(50,50)
            a.setPixmap(pic)
            a.setToolTip(path)

            a.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
            a.customContextMenuRequested.connect(self.ContextMenu)

            labels.append(a)

            print(attachments,labels)
            
            pos = len(attachments)

            l = [self.from_label,self.from_addr,self.to_label,self.to_addr,self.subject_label,self.subject,self.image,self.text,self.send]
            
            for index,i in enumerate(l):
                self.grid.addWidget(i,index,0,1,pos+1)

                if i in l[-2:]:
                    self.grid.addWidget(i,index+1,0,1,pos+1)

            self.grid.addWidget(a,7,pos-1)
            self.setGeometry(300,300,500,550)
        
    def Send(self):
        global server
        global attachments
        global filetype
        global l
        
        fromaddr = self.from_addr.text()
        toaddr = self.to_addr.text()
        subject = self.subject.text()
        
        msg = MIMEMultipart()
        msg['From'] = fromaddr
        msg['To'] = toaddr
        msg['Subject'] = subject
        msg['Date'] = formatdate()

        body = self.text.toPlainText()
        msg.attach(MIMEText(body,"plain"))

        if attachments:
            for file in attachments:

                ctype, encoding = mimetypes.guess_type(file)

                if ctype is None or encoding is not None:
                    ctype = 'application/octet-stream'
                    
                maintype, subtype = ctype.split('/', 1)

                if maintype == 'text':
                    fp = open(file)
                    att = MIMEText(fp.read(), _subtype=subtype)
                    fp.close()
                elif maintype == 'image':
                    fp = open(file, 'rb')
                    att = MIMEImage(fp.read(), _subtype=subtype)
                    fp.close()
                elif maintype == 'audio':
                    fp = open(file, 'rb')
                    att = MIMEAudio(fp.read(), _subtype=subtype)
                    fp.close()
                else:
                    fp = open(file, 'rb')
                    att = MIMEBase(maintype, subtype)
                    att.set_payload(fp.read())
                    fp.close()
                    encoders.encode_base64(att)

                att.add_header('Content-Disposition', 'attachment', filename=file[file.rindex("/"):])
                msg.attach(att) 

        text = msg.as_string()
        
        try:
            server.sendmail(fromaddr, toaddr, text)

            msg = QtGui.QMessageBox.information(self, 'Message sent',
            "Message sent successfully, clear everything?", QtGui.QMessageBox.Yes | 
            QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)

            if msg == QtGui.QMessageBox.Yes:
                self.to_addr.clear()
                self.subject.clear()
                self.text.clear()

                if attachments:
                    for i in attachments:
                        attachments.remove(i)

                    for i in reversed(range(self.grid.count())):
                        self.grid.itemAt(i).widget().setParent(None)

                    for index,i in enumerate(l):
                        self.grid.addWidget(i,index,0)
            
        except smtplib.SMTPException:
            
            msg = QtGui.QMessageBox.critical(self, 'Error',
            "The message could not be sent, retry?", QtGui.QMessageBox.Yes | 
            QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)

            if msg == QtGui.QMessageBox.Yes:
                self.Send()
        
def main():
    app = QtGui.QApplication(sys.argv)
    login = Login()
    login.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

Oh yeah by the way, the file icons are from here: https://github.com/teambox/Free-file-icons

Thursday, August 8, 2013

Fully functional PyQt Calculator

This is a continuation of my tutorial on a pyqt calculator. I basically worked some more on it, adding an advanced mode. Have fun with the code:


import sys,math
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt
from math import sqrt

num = 0.0
newNum = 0.0
sumAll = 0.0
operator = ""

opVar = True

sumIt = 0

para = 0
paraVar = False
firstNum = 0
firstOp = ""

class Main(QtGui.QMainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.initUI()

    def initUI(self):

        self.centralwidget = QtGui.QWidget(self)

        self.line = QtGui.QLineEdit(self)
        self.line.setReadOnly(True)
        self.line.setAlignment(Qt.AlignRight)
        self.line.setMinimumSize(200,25)

        zero = QtGui.QPushButton("0",self)
        zero.setMinimumSize(35,30)

        one = QtGui.QPushButton("1",self)
        one.setMinimumSize(35,30)

        two = QtGui.QPushButton("2",self)
        two.setMinimumSize(35,30)

        three = QtGui.QPushButton("3",self)
        three.setMinimumSize(35,30)

        four = QtGui.QPushButton("4",self)
        four.setMinimumSize(35,30)

        five = QtGui.QPushButton("5",self)
        five.setMinimumSize(35,30)

        six = QtGui.QPushButton("6",self)
        six.setMinimumSize(35,30)

        seven = QtGui.QPushButton("7",self)
        seven.setMinimumSize(35,30)

        eight = QtGui.QPushButton("8",self)
        eight.setMinimumSize(35,30)

        nine = QtGui.QPushButton("9",self)
        nine.setMinimumSize(35,30)

        switch = QtGui.QPushButton("+/-",self)
        switch.setMinimumSize(35,30)
        switch.clicked.connect(self.Switch)

        point = QtGui.QPushButton(".",self)
        point.setMinimumSize(35,30)
        point.clicked.connect(self.pointClicked)

        div = QtGui.QPushButton("/",self)
        div.move(130,75)
        div.setMinimumSize(35,30)

        mult = QtGui.QPushButton("*",self)
        mult.setMinimumSize(35,30)

        minus = QtGui.QPushButton("-",self)
        minus.setMinimumSize(35,30)

        plus = QtGui.QPushButton("+",self)
        plus.setMinimumSize(35,30)

        sqrt = QtGui.QPushButton("√",self)
        sqrt.setMinimumSize(35,30)

        squared = QtGui.QPushButton("x²",self)
        squared.setMinimumSize(35,30)

        equal = QtGui.QPushButton("=",self)
        equal.setMinimumSize(35,65)
        equal.clicked.connect(self.Equal)

        c = QtGui.QPushButton("C",self)
        c.setMinimumSize(70,30)
        c.clicked.connect(self.C)

        ce = QtGui.QPushButton("CE",self)
        ce.setMinimumSize(70,30)
        ce.clicked.connect(self.CE)

        back = QtGui.QPushButton("Back",self)
        back.setMinimumSize(35,30)
        back.clicked.connect(self.Back)

        self.para = QtGui.QPushButton("( )",self)
        self.para.setMinimumSize(35,30)
        self.para.clicked.connect(self.Para)
        self.para.hide()

        self.power = QtGui.QPushButton("x^y",self)
        self.power.setMinimumSize(35,30)

        self.perc = QtGui.QPushButton("%",self)
        self.perc.setMinimumSize(35,30)

        self.ln = QtGui.QPushButton("ln",self)
        self.ln.setMinimumSize(35,30)
        
        self.fact = QtGui.QPushButton("n!",self)
        self.fact.setMinimumSize(35,30)

        self.eu = QtGui.QPushButton("e",self)
        self.eu.setMinimumSize(35,30)
        self.eu.hide()

        self.pi = QtGui.QPushButton("π",self)
        self.pi.setMinimumSize(35,30)
        self.pi.hide()

        self.sin = QtGui.QPushButton("sin",self)
        self.sin.setMinimumSize(35,30)

        self.cos = QtGui.QPushButton("cos",self)
        self.cos.setMinimumSize(35,30)

        self.tan = QtGui.QPushButton("tan",self)
        self.tan.setMinimumSize(35,30)

        self.asin = QtGui.QPushButton("asin",self)
        self.asin.setMinimumSize(35,30)

        self.acos = QtGui.QPushButton("acos",self)
        self.acos.setMinimumSize(35,30)

        self.sp1 = QtGui.QPushButton(self)
        self.sp1.setMinimumSize(35,30)
        self.sp1.hide()
        self.sp1.setStyleSheet("border-radius:5px;")

        self.sp2 = QtGui.QPushButton(self)
        self.sp2.setMinimumSize(35,30)
        self.sp2.hide()
        self.sp2.setStyleSheet("border-radius:5px;")

        self.sp3 = QtGui.QPushButton(self)
        self.sp3.setMinimumSize(35,30)
        self.sp3.hide()
        self.sp3.setStyleSheet("border-radius:5px;")

        self.sp4 = QtGui.QPushButton(self)
        self.sp4.setMinimumSize(35,30)
        self.sp4.hide()
        self.sp4.setStyleSheet("border-radius:5px;")

        nums = [zero,one,two,three,four,five,six,seven,eight,nine,self.pi,self.eu]

        self.ops = [equal,self.para,back,c,ce,div,mult,minus,plus,self.power,self.perc,self.ln,self.fact,self.sin,self.cos,self.tan,self.asin,self.acos,sqrt,squared]

        for i in nums:
            i.setStyleSheet("color:blue;")
            i.clicked.connect(self.Nums)

        for i in self.ops:
            i.setStyleSheet("color:red;")

        for i in self.ops[5:10]:
            i.clicked.connect(self.Operator)

        for i in self.ops[10:]:
            i.clicked.connect(self.SpecialOperator)
            
        for i in self.ops[9:-2]:
            i.hide()

        self.grid = QtGui.QGridLayout()

#------------ Normal ------------------------

        self.grid.addWidget(self.line,0,0, 1, 5)
        self.grid.addWidget(seven,2,0, 1, 1)
        self.grid.addWidget(eight,2,1, 1, 1)
        self.grid.addWidget(nine,2,2, 1, 1)
        self.grid.addWidget(div,2,3, 1, 1)
        self.grid.addWidget(sqrt,2,4, 1, 1)
        self.grid.addWidget(four,3,0, 1, 1)
        self.grid.addWidget(five,3,1, 1, 1)
        self.grid.addWidget(six,3,2, 1, 1)
        self.grid.addWidget(mult,3,3, 1, 1)
        self.grid.addWidget(squared,3,4, 1, 1)
        self.grid.addWidget(one,4,0, 1, 1)
        self.grid.addWidget(two,4,1, 1, 1)
        self.grid.addWidget(three,4,2, 1, 1)
        self.grid.addWidget(minus,4,3, 1, 1)
        self.grid.addWidget(equal,4,4, 1, 1)
        self.grid.addWidget(zero,5,0, 1, 1)
        self.grid.addWidget(switch,5,1, 1, 1)
        self.grid.addWidget(point,5,2, 1, 1)
        self.grid.addWidget(plus,5,3, 1, 1)
        self.grid.addWidget(back,1,0, 1, 1)
        self.grid.addWidget(c,1,1, 1, 1)
        self.grid.addWidget(ce,1,3, 1, 1)

#------------ Scientific ----------------
        
        self.grid.addWidget(self.para,2,6, 1, 1)
        self.grid.addWidget(self.power,3,6, 1, 1)
        self.grid.addWidget(self.perc,4,6, 1, 1)
        self.grid.addWidget(self.ln,5,6, 1, 1)
        self.grid.addWidget(self.fact,2,7, 1, 1)
        self.grid.addWidget(self.pi,3,7, 1, 1)
        self.grid.addWidget(self.eu,4,7, 1, 1)
        self.grid.addWidget(self.sin,5,7, 1, 1)
        self.grid.addWidget(self.cos,2,8, 1, 1)
        self.grid.addWidget(self.asin,3,8, 1, 1)
        self.grid.addWidget(self.acos,4,8, 1, 1)
        self.grid.addWidget(self.tan,5,8, 1, 1)

        self.grid.addWidget(self.sp1,2,5,1,1)
        self.grid.addWidget(self.sp2,3,5,1,1)
        self.grid.addWidget(self.sp3,4,5,1,1)
        self.grid.addWidget(self.sp4,5,5,1,1)
        
        self.centralwidget.setLayout(self.grid)
        
            
#---------Window settings --------------------------------
        
        self.setGeometry(300,300,210,220)
        self.setFixedSize(212,240)
        self.setWindowTitle("PyCalc")
        self.show()

        self.setCentralWidget(self.centralwidget)

#----------- Menubar ----------------------------------

        self.menubar = self.menuBar()
        menu = self.menubar.addMenu("View")

        normal = QtGui.QAction("Normal",self)
        scientific = QtGui.QAction("Scientific",self)

        menu.addAction(normal)
        menu.addAction(scientific)

        normal.triggered.connect(self.Normal)
        scientific.triggered.connect(self.Scientific)

    def Nums(self):
        global opVar
        
        sender = self.sender()
        
        newNum = sender.text()

        print(newNum)

        if opVar == False:
            if newNum == "e":
                self.line.setText(self.line.text() + str(math.e))
                
            elif newNum == "π":
                self.line.setText(self.line.text() + str(math.pi))
                
            else:
                self.line.setText(self.line.text() + newNum)

        else:
            if newNum == "e":
                print(math.e)
                self.line.setText(str(math.e))
                
            elif newNum == "π":
                print(math.pi)
                self.line.setText(str(math.pi))
                
            else:
                self.line.setText(newNum)
            opVar = False
            
        

    def pointClicked(self):
        
        if "." not in self.line.text():
            self.line.setText(self.line.text() + ".")
            

    def Switch(self):
        global num
        
        try:
            num = int(self.line.text())
            
        except:
            num = float(self.line.text())
     
        num = num - num * 2

        numStr = str(num)
        
        self.line.setText(numStr)

    def Operator(self):
        global num
        global opVar
        global operator
        global sumIt

        sumIt += 1

        if sumIt > 1:
            self.Equal()

        num = self.line.text()

        sender = self.sender()

        operator = sender.text()
        print(operator)
        
        opVar = True

    def SpecialOperator(self):

        sender = self.sender()
        operator = sender.text()
        num = float(self.line.text())

        if operator == "ln":
            num = math.log(num)

        elif operator == "√":
            num = math.sqrt(num)

        elif operator == "x²":
            num = num ** 2

        elif operator == "n!":
            num = math.factorial(num)

        elif operator == "sin":
            num = math.sin(num)

        elif operator == "cos":
            num = math.cos(num)

        elif operator == "tan":
            num = math.tan(num)

        elif operator == "acos":
            num = math.acos(num)

        elif operator == "asin":
            num = math.asin(num)

        elif operator == "%":
            num = num / 100

        self.line.setText(str(num))

    def Equal(self):
        global num
        global newNum
        global sumAll
        global operator
        global opVar
        global sumIt
        global paraVar
        global firstNum
        global firstOp

        sumIt = 0
        if paraVar == True:
            num = firstNum
            operator = firstOp
            
        newNum = self.line.text()

        print(num)
        print(operator)
        print(newNum)
        
        if operator == "+":
            sumAll = float(num) + float(newNum)

        elif operator == "-":
            sumAll = float(num) - float(newNum)

        elif operator == "/":
            sumAll = float(num) / float(newNum)

        elif operator == "*":
            sumAll = float(num) * float(newNum)

        elif operator == "x^y":
            sumAll = math.pow(float(num),float(newNum)) 
            
        print(sumAll)
        self.line.setText(str(sumAll))  
        opVar = True
        paraVar = False

    def Back(self):
        self.line.backspace()

    def C(self):
        self.line.clear()

    def CE(self):
        global newNum
        global sumAll
        global operator
        global num
        global sumIt
        
        self.line.clear()

        num = 0.0
        newNum = 0.0
        sumAll = 0.0
        operator = ""
        sumIt = 0

    def Para(self):
        global para
        global paraVar
        global operator
        global num
        global sumAll
        global newNum
        global firstNum
        global firstOp
        global sumIt

        if para == 0:
            self.line.setText("(")

            firstNum = num
            firstOp = operator

            para = 1
            sumIt = 0
            
        else:
            self.Equal()

            paraVar = True

            para = 0

    def Normal(self):
        self.setFixedSize(212,240)

        self.grid.addWidget(self.line,0,0, 1, 5)

        self.para.hide()
        self.pi.hide()
        self.eu.hide()

        self.sp1.hide()
        self.sp2.hide()
        self.sp3.hide()
        self.sp4.hide()

        for i in self.ops[9:-2]:
            i.hide()
        
    def Scientific(self):
        self.setFixedSize(370,240)

        self.grid.addWidget(self.line,0,0, 1, 9)

        self.para.show()
        self.pi.show()
        self.eu.show()

        self.sp1.show()
        self.sp2.show()
        self.sp3.show()
        self.sp4.show()

        for i in self.ops[9:-2]:
            i.show()

def main():
    app = QtGui.QApplication(sys.argv)
    main= Main()
    main.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


There's no memory storage, simply because I actually never really use it ... but you could add that very simply by adding a couple more buttons and global variables. The code has been tested by numerous oompa loompas in charlie's chocolate factory so everything should be fine.

Thursday, July 25, 2013

Fully functional PyQt weather app

Here's another fully functioning PyQt program I want to share with you. It's a weather app using the pywapi API. The code:

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt

import pywapi

class Main(QtGui.QMainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.initUI()

    def initUI(self):

        self.line = QtGui.QLineEdit(self)
        self.line.move(90,35)
        self.line.resize(500,35)
        self.line.setStyleSheet("font-size:15px;")

        self.src = QtGui.QPushButton(QtGui.QIcon("icons/find.png"),"",self)
        self.src.move(600,34)
        self.src.resize(50,35)
        self.src.clicked.connect(self.Src)
        self.src.setShortcut("RETURN")

        self.pix = QtGui.QPixmap("")

        self.pic = QtGui.QLabel(self)
        self.pic.move(90,110)
        self.pic.resize(128,128)
        self.pic.setPixmap(self.pix)

        self.loc = QtGui.QLabel(self)
        self.loc.move(250,90)
        self.loc.resize(500,100)
        self.loc.setStyleSheet("font-size: 30px;")

        self.temp = QtGui.QLabel(self)
        self.temp.move(250,160)
        self.temp.resize(150,100)
        self.temp.setStyleSheet("font-size:50px;")

        self.hum = QtGui.QLabel(self)
        self.hum.move(410,160)
        self.hum.resize(250,100)
        self.hum.setStyleSheet("font-size:50px;")

        self.text = QtGui.QLabel(self)
        self.text.move(70,236)
        self.text.resize(180,50)
        self.text.setStyleSheet("font-size: 20px;")
        self.text.setAlignment(Qt.AlignCenter)

        self.time = QtGui.QLabel(self)
        self.time.move(250,211)
        self.time.resize(400,100)
        self.time.setStyleSheet("font-size: 20px;")

        self.error = QtGui.QLabel("No such place found ...",self)
        self.error.move(90,70)
        self.error.resize(500,200)
        self.error.setStyleSheet("font-size:40px;")
        self.error.hide()

        # 1

        self.first = QtGui.QLabel(self)
        self.first.move(100,300)
        self.first.resize(300,100)
        self.first.setStyleSheet("font-size:20px;")

        self.firstTemp = QtGui.QLabel(self)
        self.firstTemp.move(380,300)
        self.firstTemp.resize(150,100)
        self.firstTemp.setStyleSheet("font-size:20px;")

        self.firstHum = QtGui.QLabel(self)
        self.firstHum.move(460,300)
        self.firstHum.resize(150,100)
        self.firstHum.setStyleSheet("font-size:20px;")

        self.firstText = QtGui.QLabel(self)
        self.firstText.move(550,300)
        self.firstText.resize(200,100)
        self.firstText.setStyleSheet("font-size:20px;")

        # 2

        self.sec = QtGui.QLabel(self)
        self.sec.move(100,330)
        self.sec.resize(300,100)
        self.sec.setStyleSheet("font-size:20px;")

        self.secTemp = QtGui.QLabel(self)
        self.secTemp.move(380,330)
        self.secTemp.resize(150,100)
        self.secTemp.setStyleSheet("font-size:20px;")

        self.secHum = QtGui.QLabel(self)
        self.secHum.move(460,330)
        self.secHum.resize(150,100)
        self.secHum.setStyleSheet("font-size:20px;")

        self.secText = QtGui.QLabel(self)
        self.secText.move(550,330)
        self.secText.resize(200,100)
        self.secText.setStyleSheet("font-size:20px;")

        # 3

        self.three = QtGui.QLabel(self)
        self.three.move(100,360)
        self.three.resize(300,100)
        self.three.setStyleSheet("font-size:20px;")

        self.threeTemp = QtGui.QLabel(self)
        self.threeTemp.move(380,360)
        self.threeTemp.resize(150,100)
        self.threeTemp.setStyleSheet("font-size:20px;")

        self.threeHum = QtGui.QLabel(self)
        self.threeHum.move(460,360)
        self.threeHum.resize(150,100)
        self.threeHum.setStyleSheet("font-size:20px;")

        self.threeText = QtGui.QLabel(self)
        self.threeText.move(550,360)
        self.threeText.resize(200,100)
        self.threeText.setStyleSheet("font-size:20px;")

        # 4

        self.four = QtGui.QLabel(self)
        self.four.move(100,390)
        self.four.resize(300,100)
        self.four.setStyleSheet("font-size:20px;")

        self.fourTemp = QtGui.QLabel(self)
        self.fourTemp.move(380,390)
        self.fourTemp.resize(150,100)
        self.fourTemp.setStyleSheet("font-size:20px;")

        self.fourHum = QtGui.QLabel(self)
        self.fourHum.move(460,390)
        self.fourHum.resize(150,100)
        self.fourHum.setStyleSheet("font-size:20px;")

        self.fourText = QtGui.QLabel(self)
        self.fourText.move(550,390)
        self.fourText.resize(200,100)
        self.fourText.setStyleSheet("font-size:20px;")

        # 5

        self.five = QtGui.QLabel(self)
        self.five.move(100,420)
        self.five.resize(300,100)
        self.five.setStyleSheet("font-size:20px;")

        self.fiveTemp = QtGui.QLabel(self)
        self.fiveTemp.move(380,420)
        self.fiveTemp.resize(150,100)
        self.fiveTemp.setStyleSheet("font-size:20px;")

        self.fiveHum = QtGui.QLabel(self)
        self.fiveHum.move(460,420)
        self.fiveHum.resize(150,100)
        self.fiveHum.setStyleSheet("font-size:20px;")

        self.fiveText = QtGui.QLabel(self)
        self.fiveText.move(550,420)
        self.fiveText.resize(200,100)
        self.fiveText.setStyleSheet("font-size:20px;")

#---------Window settings --------------------------------
        
        self.setGeometry(300,300,750,500)
        self.setFixedSize(760,520)
        self.setWindowTitle("PySun")
        self.setWindowIcon(QtGui.QIcon("icons/partly.png"))
        self.setStyleSheet("background-color:")
        self.show()

    def Src(self):
        global text
        global temp
        global loc
        global time
        global hum

        global day1
        global day1Temp
        global day1Hum
        global day1Text

        global day2
        global day2Temp
        global day2Hum
        global day2Text

        global day3
        global day3Temp
        global day3Hum
        global day3Text

        global day4
        global day4Temp
        global day4Hum
        global day4Text

        global day5
        global day5Temp
        global day5Hum
        global day5Text
        
        try:
            text = self.line.text()

            location_info = pywapi.get_location_ids(text)

            for i in location_info:
                location_id = i
            for i in location_info.values():
                loc = i

            print(location_id,loc)
            
        except:
            self.text.hide()
            self.time.hide()
            self.pic.hide()
            self.temp.hide()
            self.loc.hide()
            self.hum.hide()
            
            self.error.show()

            self.first.hide()
            self.firstTemp.hide()
            self.firstHum.hide()
            self.firstText.hide()

            self.sec.hide()
            self.secTemp.hide()
            self.secHum.hide()
            self.secText.hide()

            self.three.hide()
            self.threeTemp.hide()
            self.threeHum.hide()
            self.threeText.hide()

            self.four.hide()
            self.fourTemp.hide()
            self.fourHum.hide()
            self.fourText.hide()

            self.five.hide()
            self.fiveTemp.hide()
            self.fiveHum.hide()
            self.fiveText.hide()


        weather_com_result = pywapi.get_weather_from_weather_com(location_id)
        print(weather_com_result['current_conditions']['text'],weather_com_result['current_conditions']['temperature']+"°",weather_com_result['current_conditions']['last_updated'],weather_com_result["current_conditions"]["humidity"])
        
        text = weather_com_result['current_conditions']['text']
        temp = weather_com_result['current_conditions']['temperature']+"°C"
        time = "last updated "+weather_com_result['current_conditions']['last_updated']
        hum = "☂ "+weather_com_result['current_conditions']['humidity']+"%"

        
        day1 = weather_com_result['forecasts'][0]['day_of_week'] + " " + weather_com_result['forecasts'][0]['date']
        day1Temp = weather_com_result['forecasts'][0]['high'] + "/" + weather_com_result['forecasts'][0]['low']
        day1Hum = "☂ "+weather_com_result['forecasts'][0]['day']['humidity']+"%"
        day1Text = weather_com_result['forecasts'][0]['day']['text']

        day2 = weather_com_result['forecasts'][1]['day_of_week'] + " " + weather_com_result['forecasts'][1]['date']
        day2Temp = weather_com_result['forecasts'][1]['high'] + "/" + weather_com_result['forecasts'][1]['low']
        day2Hum = "☂ "+weather_com_result['forecasts'][1]['day']['humidity']+"%"
        day2Text = weather_com_result['forecasts'][1]['day']['text']

        day3 = weather_com_result['forecasts'][2]['day_of_week'] + " " + weather_com_result['forecasts'][2]['date']
        day3Temp = weather_com_result['forecasts'][2]['high'] + "/" + weather_com_result['forecasts'][2]['low']
        day3Hum = "☂ "+weather_com_result['forecasts'][2]['day']['humidity']+"%"
        day3Text = weather_com_result['forecasts'][2]['day']['text']

        day4 = weather_com_result['forecasts'][3]['day_of_week'] + " " + weather_com_result['forecasts'][3]['date']
        day4Temp = weather_com_result['forecasts'][3]['high'] + "/" + weather_com_result['forecasts'][3]['low']
        day4Hum = "☂ "+weather_com_result['forecasts'][3]['day']['humidity']+"%"
        day4Text = weather_com_result['forecasts'][3]['day']['text']

        day5 = weather_com_result['forecasts'][4]['day_of_week'] + " " + weather_com_result['forecasts'][4]['date']
        day5Temp = weather_com_result['forecasts'][4]['high'] + "/" + weather_com_result['forecasts'][4]['low']
        day5Hum = "☂ "+weather_com_result['forecasts'][4]['day']['humidity']+"%"
        day5Text = weather_com_result['forecasts'][4]['day']['text']

        self.Forecast()

    def Forecast(self):
        global text
        global temp
        global loc
        global time
        global hum

        global day1
        global day1Temp
        global day1Hum
        global day1Text

        global day2
        global day2Temp
        global day2Hum
        global day2Text

        global day3
        global day3Temp
        global day3Hum
        global day3Text

        global day4
        global day4Temp
        global day4Hum
        global day4Text

        global day5
        global day5Temp
        global day5Hum
        global day5Text

        self.text.show()
        self.time.show()
        self.pic.show()
        self.temp.show()
        self.loc.show()
        self.hum.show()

        self.first.show()
        self.firstTemp.show()
        self.firstHum.show()
        self.firstText.show()

        self.sec.show()
        self.secTemp.show()
        self.secHum.show()
        self.secText.show()

        self.three.show()
        self.threeTemp.show()
        self.threeHum.show()
        self.threeText.show()

        self.four.show()
        self.fourTemp.show()
        self.fourHum.show()
        self.fourText.show()

        self.five.show()
        self.fiveTemp.show()
        self.fiveHum.show()
        self.fiveText.show()
        
        self.error.hide()

        self.loc.setText(loc)
        self.temp.setText(temp)
        self.text.setText(text)
        self.time.setText(time)
        self.hum.setText(hum)

        self.first.setText(day1)
        self.firstTemp.setText(day1Temp)
        self.firstHum.setText(day1Hum)
        self.firstText.setText(day1Text)

        self.sec.setText(day2)
        self.secTemp.setText(day2Temp)
        self.secHum.setText(day2Hum)
        self.secText.setText(day2Text)

        self.three.setText(day3)
        self.threeTemp.setText(day3Temp)
        self.threeHum.setText(day3Hum)
        self.threeText.setText(day3Text)

        self.four.setText(day4)
        self.fourTemp.setText(day4Temp)
        self.fourHum.setText(day4Hum)
        self.fourText.setText(day4Text)

        self.five.setText(day5)
        self.fiveTemp.setText(day5Temp)
        self.fiveHum.setText(day5Hum)
        self.fiveText.setText(day5Text)

        if text == "Partly Cloudy" or text == "Fair" or text == "AM Clouds / PM Sun":
            self.pix = QtGui.QPixmap("icons/partly.png")
            self.pic.setPixmap(self.pix)
            
        elif text == "Cloudy" or text == "Mostly Cloudy":
            self.pix = QtGui.QPixmap("icons/cloudy.png")
            self.pic.setPixmap(self.pix)

        elif text == "Sunny" or text == "Mostly Sunny":
            self.pix = QtGui.QPixmap("icons/sunny.png")
            self.pic.setPixmap(self.pix)
            
        elif text == "Showers Early" or text == "Showers" or text == "AM Showers" or text == "Few Showers" or text == "Scattered Showers" or text == "Light Rain Shower":
            self.pix = QtGui.QPixmap("icons/rainy.png")
            self.pic.setPixmap(self.pix)

        elif text == "Clear" or text == "Mostly Clear":
            self.pix = QtGui.QPixmap("icons/clear.png")
            self.pic.setPixmap(self.pix)
            self.pic.move(110,110)

        elif text == "Isolated T-Storms" or text == "PM T-Storms" or text == "Scattered T-Storms":
            self.pix = QtGui.QPixmap("icons/stormy.png")
            self.pic.setPixmap(self.pix)
    
        
def main():
    app = QtGui.QApplication(sys.argv)
    main= Main()
    main.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

Enter any location in the world! Copy the code or take any parts you might find useful. If you have any questions or ideas for improvements (I know I could reduce the code by making some lists) leave me a comment. Have fun!

Friday, July 12, 2013

Fully functional PyQt Text Editor

This is not a tutorial, but I want to post this fully functional Text Editor I made with PyQt for other people to copy, analyze, do whatever with. You can find some nice icons with a google search for "Text editor icons" for example.


import sys
import time
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt

var = 0
f = ""
choiceStr = ""
cs = False
wwo = False

tt = True
tf = True
ts = True


class Find(QtGui.QDialog):
    def __init__(self,parent = None):
        QtGui.QDialog.__init__(self, parent)
        
        self.initUI()

    def initUI(self):

        self.lb1 = QtGui.QLabel("Search for: ",self)
        self.lb1.setStyleSheet("font-size: 15px; ")
        self.lb1.move(10,10)

        self.te = QtGui.QTextEdit(self)
        self.te.move(10,40)
        self.te.resize(250,25)

        self.src = QtGui.QPushButton("Find",self)
        self.src.move(270,40)

        self.lb2 = QtGui.QLabel("Replace all by: ",self)
        self.lb2.setStyleSheet("font-size: 15px; ")
        self.lb2.move(10,80)

        self.rp = QtGui.QTextEdit(self)
        self.rp.move(10,110)
        self.rp.resize(250,25)

        self.rpb = QtGui.QPushButton("Replace",self)
        self.rpb.move(270,110)

        self.opt1 = QtGui.QCheckBox("Case sensitive",self)
        self.opt1.move(10,160)
        self.opt1.stateChanged.connect(self.CS)
        
        self.opt2 = QtGui.QCheckBox("Whole words only",self)
        self.opt2.move(10,190)
        self.opt2.stateChanged.connect(self.WWO)

        self.close = QtGui.QPushButton("Close",self)
        self.close.move(270,220)
        self.close.clicked.connect(self.Close)
        
        
        self.setGeometry(300,300,360,250)

    def CS(self, state):
        global cs

        if state == QtCore.Qt.Checked:
            cs = True
        else:
            cs = False

    def WWO(self, state):
        global wwo
        print(wwo)

        if state == QtCore.Qt.Checked:
            wwo = True
        else:
            wwo = False

    def Close(self):
        self.hide()

class Date(QtGui.QDialog):
    def __init__(self,parent = None):
        QtGui.QDialog.__init__(self, parent)
        
        self.initUI()

    def initUI(self):

        self.form = QtGui.QComboBox(self)
        self.form.move(10,10)
        self.form.addItem(time.strftime("%d.%m.%Y"))
        self.form.addItem(time.strftime("%A, %d. %B %Y"))
        self.form.addItem(time.strftime("%d. %B %Y"))
        self.form.addItem(time.strftime("%d %m %Y"))
        self.form.addItem(time.strftime("%X"))
        self.form.addItem(time.strftime("%x"))
        self.form.addItem(time.strftime("%H:%M"))
        self.form.addItem(time.strftime("%A, %d. %B %Y %H:%M"))
        self.form.addItem(time.strftime("%d.%m.%Y %H:%M"))
        self.form.addItem(time.strftime("%d. %B %Y %H:%M"))

        self.form.activated[str].connect(self.handleChoice)
        
        self.ok = QtGui.QPushButton("Insert",self)
        self.ok.move(180,10)

        self.cancel = QtGui.QPushButton("Cancel",self)
        self.cancel.move(180,40)
        self.cancel.clicked.connect(self.Cancel)

        self.setGeometry(300,300,280,70)

    def handleChoice(self,choice):
        global choiceStr

        choiceStr = choice

        print(choiceStr)

    def Cancel(self):
        self.close()
        
class Main(QtGui.QMainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self,None)
        self.initUI()

    def initUI(self):

#------- Toolbar --------------------------------------

#-- Upper Toolbar -- 

        newAction = QtGui.QAction(QtGui.QIcon("icons/new.png"),"New",self)
        newAction.setShortcut("Ctrl+N")
        newAction.setStatusTip("Create a new document from scratch.")
        newAction.triggered.connect(self.New)

        openAction = QtGui.QAction(QtGui.QIcon("icons/open.png"),"Open file",self)
        openAction.setStatusTip("Open existing document")
        openAction.setShortcut("Ctrl+O")
        openAction.triggered.connect(self.Open)

        saveAction = QtGui.QAction(QtGui.QIcon("icons/save.png"),"Save",self)
        saveAction.setStatusTip("Save document")
        saveAction.setShortcut("Ctrl+S")
        saveAction.triggered.connect(self.Save)

        previewAction = QtGui.QAction(QtGui.QIcon("icons/preview.png"),"Page view",self)
        previewAction.setStatusTip("Preview page before printing")
        previewAction.setShortcut("Ctrl+Shift+P")
        previewAction.triggered.connect(self.PageView)

        findAction = QtGui.QAction(QtGui.QIcon("icons/find.png"),"Find",self)
        findAction.setStatusTip("Find words in your document")
        findAction.setShortcut("Ctrl+F")
        findAction.triggered.connect(self.Find)

        cutAction = QtGui.QAction(QtGui.QIcon("icons/cut.png"),"Cut to clipboard",self)
        cutAction.setStatusTip("Delete and copy text to clipboard")
        cutAction.setShortcut("Ctrl+X")
        cutAction.triggered.connect(self.Cut)

        copyAction = QtGui.QAction(QtGui.QIcon("icons/copy.png"),"Copy to clipboard",self)
        copyAction.setStatusTip("Copy text to clipboard")
        copyAction.setShortcut("Ctrl+C")
        copyAction.triggered.connect(self.Copy)

        pasteAction = QtGui.QAction(QtGui.QIcon("icons/paste.png"),"Paste from clipboard",self)
        pasteAction.setStatusTip("Paste text from clipboard")
        pasteAction.setShortcut("Ctrl+V")
        pasteAction.triggered.connect(self.Paste)

        undoAction = QtGui.QAction(QtGui.QIcon("icons/undo.png"),"Undo last action",self)
        undoAction.setStatusTip("Undo last action")
        undoAction.setShortcut("Ctrl+Z")
        undoAction.triggered.connect(self.Undo)

        redoAction = QtGui.QAction(QtGui.QIcon("icons/redo.png"),"Redo last undone thing",self)
        redoAction.setStatusTip("Redo last undone thing")
        redoAction.setShortcut("Ctrl+Y")
        redoAction.triggered.connect(self.Redo)

        dtAction = QtGui.QAction(QtGui.QIcon("icons/datetime.png"),"Insert current date/time",self)
        dtAction.setStatusTip("Insert current date/time")
        dtAction.setShortcut("Ctrl+D")
        dtAction.triggered.connect(self.DateTime)

        printAction = QtGui.QAction(QtGui.QIcon("icons/print.png"),"Print document",self)
        printAction.setStatusTip("Print document")
        printAction.setShortcut("Ctrl+P")
        printAction.triggered.connect(self.Print)

        self.toolbar = self.addToolBar("Options")
        self.toolbar.addAction(newAction)
        self.toolbar.addAction(openAction)
        self.toolbar.addAction(saveAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(printAction)
        #self.toolbar.addAction(pdfAction)
        self.toolbar.addAction(previewAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(findAction)
        self.toolbar.addAction(cutAction)
        self.toolbar.addAction(copyAction)
        self.toolbar.addAction(pasteAction)
        self.toolbar.addAction(undoAction)
        self.toolbar.addAction(redoAction)
        self.toolbar.addSeparator()
        self.toolbar.addAction(dtAction)
        self.toolbar.addSeparator()

        self.addToolBarBreak()

# -- Lower Toolbar -- 

        self.fontFamily = QtGui.QFontComboBox(self)
        self.fontFamily.currentFontChanged.connect(self.FontFamily)

        fontSize = QtGui.QComboBox(self)
        fontSize.setEditable(True)
        fontSize.setMinimumContentsLength(3)
        fontSize.activated.connect(self.FontSize)
        flist = [6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,32,36,40,44,48,
                 54,60,66,72,80,88,96]
        
        for i in flist:
            fontSize.addItem(str(i))

        fontColor = QtGui.QAction(QtGui.QIcon("icons/color.png"),"Change font color",self)
        fontColor.triggered.connect(self.FontColor)

        boldAction = QtGui.QAction(QtGui.QIcon("icons/bold.png"),"Bold",self)
        boldAction.triggered.connect(self.Bold)
        
        italicAction = QtGui.QAction(QtGui.QIcon("icons/italic.png"),"Italic",self)
        italicAction.triggered.connect(self.Italic)
        
        underlAction = QtGui.QAction(QtGui.QIcon("icons/underl.png"),"Underline",self)
        underlAction.triggered.connect(self.Underl)

        alignLeft = QtGui.QAction(QtGui.QIcon("icons/alignLeft.png"),"Align left",self)
        alignLeft.triggered.connect(self.alignLeft)

        alignCenter = QtGui.QAction(QtGui.QIcon("icons/alignCenter.png"),"Align center",self)
        alignCenter.triggered.connect(self.alignCenter)

        alignRight = QtGui.QAction(QtGui.QIcon("icons/alignRight.png"),"Align right",self)
        alignRight.triggered.connect(self.alignRight)

        alignJustify = QtGui.QAction(QtGui.QIcon("icons/alignJustify.png"),"Align justify",self)
        alignJustify.triggered.connect(self.alignJustify)

        indentAction = QtGui.QAction(QtGui.QIcon("icons/indent.png"),"Indent Area",self)
        indentAction.setShortcut("Ctrl+Tab")
        indentAction.triggered.connect(self.Indent)

        dedentAction = QtGui.QAction(QtGui.QIcon("icons/dedent.png"),"Dedent Area",self)
        dedentAction.setShortcut("Shift+Tab")
        dedentAction.triggered.connect(self.Dedent)

        backColor = QtGui.QAction(QtGui.QIcon("icons/backcolor.png"),"Change background color",self)
        backColor.triggered.connect(self.FontBackColor)

        bulletAction = QtGui.QAction(QtGui.QIcon("icons/bullet.png"),"Insert Bullet List",self)
        bulletAction.triggered.connect(self.BulletList)

        numberedAction = QtGui.QAction(QtGui.QIcon("icons/number.png"),"Insert Numbered List",self)
        numberedAction.triggered.connect(self.NumberedList)

        space1 = QtGui.QLabel("  ",self)
        space2 = QtGui.QLabel(" ",self)
        space3 = QtGui.QLabel(" ",self)
        

        self.formatbar = self.addToolBar("Format")
        self.formatbar.addWidget(self.fontFamily)
        self.formatbar.addWidget(space1)
        self.formatbar.addWidget(fontSize)
        self.formatbar.addWidget(space2)
        
        self.formatbar.addSeparator()

        self.formatbar.addAction(fontColor)
        self.formatbar.addAction(backColor)

        self.formatbar.addSeparator()
        
        self.formatbar.addAction(boldAction)
        self.formatbar.addAction(italicAction)
        self.formatbar.addAction(underlAction)
        
        self.formatbar.addSeparator()

        self.formatbar.addAction(alignLeft)
        self.formatbar.addAction(alignCenter)
        self.formatbar.addAction(alignRight)
        self.formatbar.addAction(alignJustify)

        self.formatbar.addSeparator()

        self.formatbar.addAction(indentAction)
        self.formatbar.addAction(dedentAction)
        self.formatbar.addAction(bulletAction)
        self.formatbar.addAction(numberedAction)
        
#------- Text Edit -----------------------------------

        self.text = QtGui.QTextEdit(self)
        self.text.setTabStopWidth(12)
        self.setCentralWidget(self.text)

#------- Statusbar ------------------------------------
        
        self.status = self.statusBar()

        self.text.cursorPositionChanged.connect(self.CursorPosition)


#---------Window settings --------------------------------
        
        self.setGeometry(100,100,700,700)
        self.setWindowTitle("Scriber")
        self.setWindowIcon(QtGui.QIcon("icons/feather.png"))
        self.show()

#------- Menubar --------------------------------------
        
        menubar = self.menuBar()
        file = menubar.addMenu("File")
        edit = menubar.addMenu("Edit")
        view = menubar.addMenu("View")

        file.addAction(newAction)
        file.addAction(openAction)
        file.addAction(saveAction)
        file.addAction(printAction)
        file.addAction(previewAction)

        edit.addAction(undoAction)
        edit.addAction(redoAction)
        edit.addAction(cutAction)
        edit.addAction(copyAction)
        edit.addAction(findAction)
        edit.addAction(dtAction)

        toggleTool = QtGui.QAction("Toggle Toolbar",self,checkable=True)
        toggleTool.triggered.connect(self.handleToggleTool)
        
        toggleFormat = QtGui.QAction("Toggle Formatbar",self,checkable=True)
        toggleFormat.triggered.connect(self.handleToggleFormat)
        
        toggleStatus = QtGui.QAction("Toggle Statusbar",self,checkable=True)
        toggleStatus.triggered.connect(self.handleToggleStatus)

        view.addAction(toggleTool)
        view.addAction(toggleFormat)
        view.addAction(toggleStatus)

    def handleToggleTool(self):
        global tt

        if tt == True:
            self.toolbar.hide()
            tt = False
        else:
            self.toolbar.show()
            tt = True

    def handleToggleFormat(self):
        global tf

        if tf == True:
            self.formatbar.hide()
            tf = False
        else:
            self.formatbar.show()
            tf = True

    def handleToggleStatus(self):
        global ts

        if ts == True:
            self.status.hide()
            ts = False
        else:
            self.status.show()
            ts = True
            
#-------- Toolbar slots -----------------------------------

    def New(self):
        self.text.clear()

    def Open(self):
        filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File')
        f = open(filename, 'r')
        filedata = f.read()
        self.text.setText(filedata)
        f.close()

    def Save(self):
        filename = QtGui.QFileDialog.getSaveFileName(self, 'Save File')
        f = open(filename, 'w')
        filedata = self.text.toPlainText()
        f.write(filedata)
        f.close()

    def PageView(self):
        preview = QtGui.QPrintPreviewDialog()
        preview.paintRequested.connect(self.PaintPageView)
        preview.exec_()

    def Print(self):
        dialog = QtGui.QPrintDialog()
        if dialog.exec_() == QtGui.QDialog.Accepted:
            self.text.document().print_(dialog.printer())

    def PDF(self):
        printer = QtGui.QPrinter()
        printer.setOutputFormat(printer.NativeFormat)
        
        dialog = QtGui.QPrintDialog(printer)
        dialog.setOption(dialog.PrintToFile)
        if dialog.exec_() == QtGui.QDialog.Accepted:
            self.text.document().print_(dialog.printer())
        
        
    def PaintPageView(self, printer):
        self.text.print_(printer)

    def Find(self):
        global f
        
        find = Find(self)
        find.show()

        def handleFind():

            f = find.te.toPlainText()
            print(f)
            
            if cs == True and wwo == False:
                flag = QtGui.QTextDocument.FindBackward and QtGui.QTextDocument.FindCaseSensitively
                
            elif cs == False and wwo == False:
                flag = QtGui.QTextDocument.FindBackward
                
            elif cs == False and wwo == True:
                flag = QtGui.QTextDocument.FindBackward and QtGui.QTextDocument.FindWholeWords
                
            elif cs == True and wwo == True:
                flag = QtGui.QTextDocument.FindBackward and QtGui.QTextDocument.FindCaseSensitively and QtGui.QTextDocument.FindWholeWords
            
            self.text.find(f,flag)

        def handleReplace():
            f = find.te.toPlainText()
            r = find.rp.toPlainText()

            text = self.text.toPlainText()
            
            newText = text.replace(f,r)

            self.text.clear()
            self.text.append(newText)
        
        find.src.clicked.connect(handleFind)
        find.rpb.clicked.connect(handleReplace)


    def Undo(self):
        self.text.undo()

    def Redo(self):
        self.text.redo()

    def Cut(self):
        self.text.cut()

    def Copy(self):
        self.text.copy()

    def Paste(self):
        self.text.paste()

    def DateTime(self):

        date = Date(self)
        date.show()

        date.ok.clicked.connect(self.insertDate)

    def insertDate(self):
        global choiceStr
        print(choiceStr)
        self.text.append(choiceStr)
        
    def CursorPosition(self):
        line = self.text.textCursor().blockNumber()
        col = self.text.textCursor().columnNumber()
        linecol = ("Line: "+str(line)+" | "+"Column: "+str(col))
        self.status.showMessage(linecol)

    def FontFamily(self,font):
        font = QtGui.QFont(self.fontFamily.currentFont())
        self.text.setCurrentFont(font)

    def FontSize(self, fsize):
        size = (int(fsize))
        self.text.setFontPointSize(size)

    def FontColor(self):
        c = QtGui.QColorDialog.getColor()

        self.text.setTextColor(c)
        
    def FontBackColor(self):
        c = QtGui.QColorDialog.getColor()

        self.text.setTextBackgroundColor(c)

    def Bold(self):
        w = self.text.fontWeight()
        if w == 50:
            self.text.setFontWeight(QtGui.QFont.Bold)
        elif w == 75:
            self.text.setFontWeight(QtGui.QFont.Normal)
        
    def Italic(self):
        i = self.text.fontItalic()
        
        if i == False:
            self.text.setFontItalic(True)
        elif i == True:
            self.text.setFontItalic(False)
        
    def Underl(self):
        ul = self.text.fontUnderline()

        if ul == False:
            self.text.setFontUnderline(True) 
        elif ul == True:
            self.text.setFontUnderline(False)
            
    def lThrough(self):
        lt = QtGui.QFont.style()

        print(lt)

    def alignLeft(self):
        self.text.setAlignment(Qt.AlignLeft)

    def alignRight(self):
        self.text.setAlignment(Qt.AlignRight)

    def alignCenter(self):
        self.text.setAlignment(Qt.AlignCenter)

    def alignJustify(self):
        self.text.setAlignment(Qt.AlignJustify)

    def Indent(self):
        tab = "\t"
        cursor = self.text.textCursor()

        start = cursor.selectionStart()
        end = cursor.selectionEnd()

        cursor.setPosition(end)
        cursor.movePosition(cursor.EndOfLine)
        end = cursor.position()

        cursor.setPosition(start)
        cursor.movePosition(cursor.StartOfLine)
        start = cursor.position()


        while cursor.position() < end:
            global var

            print(cursor.position(),end)
            
            cursor.movePosition(cursor.StartOfLine)
            cursor.insertText(tab)
            cursor.movePosition(cursor.Down)
            end += len(tab)

            '''if cursor.position() == end:
                var +=1

            if var == 2:
                break'''
            
            

    def Dedent(self):
        tab = "\t"
        cursor = self.text.textCursor()

        start = cursor.selectionStart()
        end = cursor.selectionEnd()

        cursor.setPosition(end)
        cursor.movePosition(cursor.EndOfLine)
        end = cursor.position()

        cursor.setPosition(start)
        cursor.movePosition(cursor.StartOfLine)
        start = cursor.position()


        while cursor.position() < end:
            global var
            
            cursor.movePosition(cursor.StartOfLine)
            cursor.deleteChar()
            cursor.movePosition(cursor.EndOfLine)
            cursor.movePosition(cursor.Down)
            end -= len(tab)

            '''if cursor.position() == end:
                var +=1

            if var == 2:
                break'''

    def BulletList(self):
        print("bullet connects!")
        self.text.insertHtml("<ul><li> ...</li></ul>")

    def NumberedList(self):
        print("numbered connects!")
        self.text.insertHtml("<ol><li> ...</li></ol>")
         
def main():
    app = QtGui.QApplication(sys.argv)
    main= Main()
    main.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


The first two classes are two Qdialogs, one is for finding and replacing words, the other is for inserting date/time. The rest is the main window. It took me about two days and sleepless nights and I encountered numerous problems but it all worked out great, so see what you can take from it. Have fun!