21 สิงหาคม 2557

Published 8/21/2557 by with 0 comment

สร้าง GUI ด้วย PySide Workshop 1 : ตัวอย่างโปรแกรมคิดเลข

สวัสดีครับทุกท่าน บทความชุด สร้าง GUI ด้วย PySide ได้เดินทางถึงฉบับที่ 5 แล้วครับ ฉบับนี้จะเป็นตัวอย่างโปรแกรมคิดเลขที่สร้างขึ้นโดยใช้  GUI ด้วย PySide ใน Python 3 ครับ
โค้ดข้างล่างนี้เป็นตัวอย่างโปรแกรมคิดเลขครับ โดยมีความสามารถในการบวก ลบ คูณ หาร ยกกำลัง Sqrt 1/x เป็นต้นครับ ลอง ๆ แกะโค้ดกันดูนะครับ :D

โค้ด
import math
from PySide.QtCore import *
from PySide.QtGui import *



class Button(QToolButton):

    def __init__(self, text, parent=None):

        super(Button, self).__init__(parent)



        self.setSizePolicy(QSizePolicy.Expanding,

                QSizePolicy.Preferred)

        self.setText(text)



    def sizeHint(self):

        size = super(Button, self).sizeHint()

        size.setHeight(size.height() + 20)

        size.setWidth(max(size.width(), size.height()))

        return size



class Calculator(QDialog):

    NumDigitButtons = 10



    def __init__(self, parent=None):

        super(Calculator, self).__init__(parent)



        self.pendingAdditiveOperator = ''

        self.pendingMultiplicativeOperator = ''



        self.sumInMemory = 0.0

        self.sumSoFar = 0.0

        self.factorSoFar = 0.0

        self.waitingForOperand = True



        self.display = QLineEdit('0')

        self.display.setReadOnly(True)

        self.display.setAlignment(Qt.AlignRight)

        self.display.setMaxLength(15)



        font = self.display.font()

        font.setPointSize(font.pointSize() + 8)

        self.display.setFont(font)



        self.digitButtons = []



        for i in range(Calculator.NumDigitButtons):

            self.digitButtons.append(self.createButton(str(i),

                    self.digitClicked))



        self.pointButton = self.createButton(".", self.pointClicked) #เชื่อมต่อจุดกับปุ่ม

        self.changeSignButton = self.createButton("\261",

                self.changeSignClicked)



        self.backspaceButton = self.createButton("Backspace",

                self.backspaceClicked)

        self.clearButton = self.createButton("Clear", self.clear)

        self.clearAllButton = self.createButton("Clear All", self.clearAll)



        self.clearMemoryButton = self.createButton("MC", self.clearMemory)

        self.readMemoryButton = self.createButton("MR", self.readMemory)

        self.setMemoryButton = self.createButton("MS", self.setMemory)

        self.addToMemoryButton = self.createButton("M+", self.addToMemory)



        self.divisionButton = self.createButton("\367",

                self.multiplicativeOperatorClicked)

        self.timesButton = self.createButton("\327",

                self.multiplicativeOperatorClicked)

        self.minusButton = self.createButton("-", self.additiveOperatorClicked)

        self.plusButton = self.createButton("+", self.additiveOperatorClicked)



        self.squareRootButton = self.createButton("Sqrt",

                self.unaryOperatorClicked)

        self.powerButton = self.createButton("x\262",

                self.unaryOperatorClicked)

        self.reciprocalButton = self.createButton("1/x",

                self.unaryOperatorClicked)

        self.equalButton = self.createButton("=", self.equalClicked)



        mainLayout = QGridLayout()

        mainLayout.setSizeConstraint(QLayout.SetFixedSize)



        mainLayout.addWidget(self.display, 0, 0, 1, 6) #เพิ่ม Widget เข้ามา

        mainLayout.addWidget(self.backspaceButton, 1, 0, 1, 2)

        mainLayout.addWidget(self.clearButton, 1, 2, 1, 2)

        mainLayout.addWidget(self.clearAllButton, 1, 4, 1, 2)



        mainLayout.addWidget(self.clearMemoryButton, 2, 0)

        mainLayout.addWidget(self.readMemoryButton, 3, 0)

        mainLayout.addWidget(self.setMemoryButton, 4, 0)

        mainLayout.addWidget(self.addToMemoryButton, 5, 0)



        for i in range(1, Calculator.NumDigitButtons):

            row = ((9 - i) / 3) + 2

            column = ((i - 1) % 3) + 1

            mainLayout.addWidget(self.digitButtons[i], row, column)



        mainLayout.addWidget(self.digitButtons[0], 5, 1)

        mainLayout.addWidget(self.pointButton, 5, 2)

        mainLayout.addWidget(self.changeSignButton, 5, 3)



        mainLayout.addWidget(self.divisionButton, 2, 4)

        mainLayout.addWidget(self.timesButton, 3, 4)

        mainLayout.addWidget(self.minusButton, 4, 4)

        mainLayout.addWidget(self.plusButton, 5, 4)



        mainLayout.addWidget(self.squareRootButton, 2, 5)

        mainLayout.addWidget(self.powerButton, 3, 5)

        mainLayout.addWidget(self.reciprocalButton, 4, 5)

        mainLayout.addWidget(self.equalButton, 5, 5)

        self.setLayout(mainLayout)



        self.setWindowTitle("Calculator")



    def digitClicked(self):

        clickedButton = self.sender()

        digitValue = int(clickedButton.text())



        if self.display.text() == '0' and digitValue == 0.0:

            return



        if self.waitingForOperand:

            self.display.clear()

            self.waitingForOperand = False



        self.display.setText(self.display.text() + str(digitValue))



    def unaryOperatorClicked(self):

        clickedButton = self.sender()

        clickedOperator = clickedButton.text()

        operand = float(self.display.text())



        if clickedOperator == "Sqrt":

            if operand < 0.0:

                self.abortOperation()

                return



            result = math.sqrt(operand)

        elif clickedOperator == "x\262":

            result = math.pow(operand, 2.0)

        elif clickedOperator == "1/x":

            if operand == 0.0:

                self.abortOperation()

                return



            result = 1.0 / operand



        self.display.setText(str(result))

        self.waitingForOperand = True



    def additiveOperatorClicked(self):

        clickedButton = self.sender()

        clickedOperator = clickedButton.text()

        operand = float(self.display.text())



        if self.pendingMultiplicativeOperator:

            if not self.calculate(operand, self.pendingMultiplicativeOperator):

                self.abortOperation()

                return



            self.display.setText(str(self.factorSoFar))

            operand = self.factorSoFar

            self.factorSoFar = 0.0

            self.pendingMultiplicativeOperator = ''



        if self.pendingAdditiveOperator:

            if not self.calculate(operand, self.pendingAdditiveOperator):

                self.abortOperation()

                return



            self.display.setText(str(self.sumSoFar))

        else:

            self.sumSoFar = operand



        self.pendingAdditiveOperator = clickedOperator

        self.waitingForOperand = True



    def multiplicativeOperatorClicked(self):

        clickedButton = self.sender()

        clickedOperator = clickedButton.text()

        operand = float(self.display.text())



        if self.pendingMultiplicativeOperator:

            if not self.calculate(operand, self.pendingMultiplicativeOperator):

                self.abortOperation()

                return



            self.display.setText(str(self.factorSoFar))

        else:

            self.factorSoFar = operand



        self.pendingMultiplicativeOperator = clickedOperator

        self.waitingForOperand = True



    def equalClicked(self):

        operand = float(self.display.text())



        if self.pendingMultiplicativeOperator:

            if not self.calculate(operand, self.pendingMultiplicativeOperator):

                self.abortOperation()

                return



            operand = self.factorSoFar

            self.factorSoFar = 0.0

            self.pendingMultiplicativeOperator = ''



        if self.pendingAdditiveOperator:

            if not self.calculate(operand, self.pendingAdditiveOperator):

                self.abortOperation()

                return



            self.pendingAdditiveOperator = ''

        else:

            self.sumSoFar = operand



        self.display.setText(str(self.sumSoFar))

        self.sumSoFar = 0.0

        self.waitingForOperand = True



    def pointClicked(self):

        if self.waitingForOperand:

            self.display.setText('0')



        if "." not in self.display.text():

            self.display.setText(self.display.text() + ".")



        self.waitingForOperand = False



    def changeSignClicked(self):

        text = self.display.text()

        value = float(text)



        if value > 0.0:

            text = "-" + text

        elif value < 0.0:

            text = text[1:]



        self.display.setText(text)



    def backspaceClicked(self):

        if self.waitingForOperand:

            return



        text = self.display.text()[:-1]

        if not text:

            text = '0'

            self.waitingForOperand = True



        self.display.setText(text)



    def clear(self):

        if self.waitingForOperand:

            return



        self.display.setText('0')

        self.waitingForOperand = True



    def clearAll(self):

        self.sumSoFar = 0.0

        self.factorSoFar = 0.0

        self.pendingAdditiveOperator = ''

        self.pendingMultiplicativeOperator = ''

        self.display.setText('0')

        self.waitingForOperand = True



    def clearMemory(self):

        self.sumInMemory = 0.0



    def readMemory(self):

        self.display.setText(str(self.sumInMemory))

        self.waitingForOperand = True



    def setMemory(self):

        self.equalClicked()

        self.sumInMemory = float(self.display.text())



    def addToMemory(self):

        self.equalClicked()

        self.sumInMemory += float(self.display.text())



    def createButton(self, text, member):

        button = Button(text)

        button.clicked.connect(member)

        return button



    def abortOperation(self):

        self.clearAll()

        self.display.setText("####")



    def calculate(self, rightOperand, pendingOperator):

        if pendingOperator == "+":

            self.sumSoFar += rightOperand

        elif pendingOperator == "-":

            self.sumSoFar -= rightOperand

        elif pendingOperator == "\327":

            self.factorSoFar *= rightOperand

        elif pendingOperator == "\367":

            if rightOperand == 0.0:

                return False



            self.factorSoFar /= rightOperand



        return True





if __name__ == '__main__':



    import sys



    app = QApplication(sys.argv)

    calc = Calculator()

    sys.exit(calc.exec_())
หน้าต่างโปรแกรม
การบ้าน หลาย ๆ ท่านคงไม่อยากมีการบ้านกัน แต่ผมขอให้การบ้านสำหรับผู้ที่สนใจการสร้าง GUI ด้วย PySide ครับ การบ้านมีอยู่ว่า
ให้สร้างโปรแกรม digitalclock สร้าง GUI ด้วย PySide แล้วใส่โค้ดโปรแกรมที่สร้างเสร็จแล้วลงที่ช่องความคิดเห็นหรือที่แฟนเพจสมาคม Python Dev แห่งประเทศไทย   พร้อมลิงค์รูปภาพของโปรแกรมครับ ใครที่ทำได้สวยสุด จะได้รับการนำเสนอผลงานที่บล็อกนี้กับที่แฟนเพจสมาคม Python Dev แห่งประเทศไทย และกลุ่ม Python-Thailand ครับ เริ่มส่งได้ตั้งแต่ตอนนี้ถึงวันศุกร์ที่ 29 สิงหาคม พ.ศ.2557 ครับ งานนี้ไม่มีรางวัลให้ครับ

ติดตามบทความต่อไปครับ :)
ขอบคุณครับ

0 ความคิดเห็น:

แสดงความคิดเห็น

แสดงความคิดเห็นได้ครับ :)