Python + Pyside2 ou simplement «Calculatrice»

Bonjour, Habr!

Je m'appelle Sasha. Je suis développeur junior. Je travaille comme testeur de logiciels. J'écris principalement des tests en utilisant Python + Selenium, mais Python est devenu si intéressant que j'ai voulu m'y plonger et apprendre le plus de frameworks possible! Je voulais écrire une application de bureau, ala simple "calculatrice". Mon choix s'est porté sur Pyside2. Je ne prétends pas avoir le code ou la leçon parfait. Il y a simplement un désir de partager l'expérience si quelqu'un, comme moi, veut commencer à tâtonner en Python. Si j'aide quelqu'un, j'ai atteint le résultat.

Commençons!

J'ai écrit mon code dans l'IDE PyBarm de JetBrains. OS - Windows.

Installez PySide2:

pip install PySide2 

Où vous avez le dossier racine Python, allez-y, puis dans le dossier «Lib» -> «site-packages» -> «Pyside2». Vous aurez le programme designer - c'est le programme QtDesigner, qui vous permettra de faire votre propre interface pour votre programme. Il est à noter que lorsque vous créez votre fichier dans le répertoire de votre projet, il aura le format .ui , que Python ne comprendra pas, nous aurons donc besoin de le convertir au format .py , mais c'est plus tard.

Créez d'abord votre formulaire.

image

Nous faisons notre design, appelons les boutons à droite dans la sous-section «Inspecteur d'objets». Il vaut la peine de dire que QtDesigner prend en charge une feuille de style en cascade, et si c'est plus facile, en trouvant le paramètre "styleSheet" dans les propriétés, vous avez la possibilité de créer votre propre conception en fonction des connaissances CSS.

image

Ensuite, nous devons convertir notre fichier .ui dans un format afin que Python le comprenne. Accédez à la ligne de commande et écrivez

 pyside2-uic "you_file.ui" -o "your_file.py" 

Que fait la commande pyside2-uic? Il convertit votre fichier .ui en un fichier python .py et crée une classe Python à partir de celui-ci. Peut-être que des gens avertis diront qu'un fichier ui peut être connecté sans conversion en projet, mais je serai soigné et ferai mieux, comme il est écrit dans les manuels Pyside2.

Ensuite, allez au code.

Ouvrez PyCharm, notre répertoire de projets et créez un fichier appelé calc_ui.py ou quelque chose_ui.py, selon le programme que vous faites. Le préfixe _ui à la fin du fichier nous aidera à ne pas nous perdre dans les fichiers. En termes généraux, cela devrait ressembler à ceci:

image

Commençons par éditer le fichier que nous avons converti de .ui en .py .

Ci-dessous, nous recherchons ce code et le copions, puis le supprimons de ce fichier.

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

Nous créons notre fichier principal, où la logique du programme sera écrite. Je l'ai appelé, comme, sans surprise "calc.py" (ci-dessus sur l'écran du répertoire, il est visible).

Collez-y notre code copié et commencez à le modifier.

import sys nous lancerons au début car c'est une règle de bonne forme.

Nous importons quelques modules nécessaires pour travailler avec notre formulaire et à partir de notre fichier "calc_ui.py" nous importons la classe principale Ui_MainWindow .

Ensuite, modifiez if __name__ . Nous supprimons tout ce qui n'est pas nécessaire. Vous devriez avoir ceci:

 if __name__ == '__main__': #   QApplication app = QtWidgets.QApplication(sys.argv) #    ,     calc = Calculator() #  sys.exit(app.exec_()) 

J'espérais clairement commenter le code. Passons à la création de la classe Calculatrice .

 class Calculator(QtWidgets.QMainWindow, Ui_MainWindow): #   def __init__(self): super().__init__() #    Ui ( ) self.setupUi(self) #    self.show() 

De plus, notre tâche est de nous assurer que quelque chose se passe lorsque nous poussons les boutons "1", "2", "3", etc.

Au même endroit, dans le constructeur de classe, nous déclarons la connexion du bouton à n'importe quelle fonction:

  # pressed self.pushButton.clicked.connect(self.digit_pressed) # 1 self.pushButton_2.clicked.connect(self.digit_pressed) # 2 self.pushButton_3.clicked.connect(self.digit_pressed) # 3 self.pushButton_4.clicked.connect(self.digit_pressed) # 4 self.pushButton_5.clicked.connect(self.digit_pressed) # 5 self.pushButton_6.clicked.connect(self.digit_pressed) # 6 self.pushButton_7.clicked.connect(self.digit_pressed) # 7 self.pushButton_8.clicked.connect(self.digit_pressed) # 8 self.pushButton_9.clicked.connect(self.digit_pressed) # 9 self.pushButton_10.clicked.connect(self.digit_pressed) # 0 self.pushButton_add.clicked.connect(self.pressed_equal) # + self.pushButton_ded.clicked.connect(self.pressed_equal) # - self.pushButton_div.clicked.connect(self.pressed_equal) # / self.pushButton_mul.clicked.connect(self.pressed_equal) # * self.pushButton_exp.clicked.connect(self.pressed_equal) # ** self.pushButton_log.clicked.connect(self.pressed_equal) # log self.pushButton_procent.clicked.connect(self.pressed_equal) # % self.pushButton_ENTER.clicked.connect(self.function_result) # = self.pushButton_C.clicked.connect(self.function_clear) # C self.pushButton_point.clicked.connect(self.make_fractional) # . self.pushButton_delete.clicked.connect(self.function_delete) # < self.pushButton_open_skob.clicked.connect(self.create_big_example) # ( 

La fonction self.digit_pressed est déjà indiquée dans le code des boutons, regardons-la, que fait-elle si l'utilisateur clique sur le bouton avec des chiffres:

  # lineEdit -  ,         # text() -  ,      # setText() -          # sender() - ,     (   ,    ) def digit_pressed(self): button = self.sender() if self.lineEdit.text() == '0': #        "0",     ,     self.lineEdit.setText(button.text()) else: if self.result == self.lineEdit.text(): self.lineEdit.setText(button.text()) else: self.lineEdit.setText(self.lineEdit.text() + button.text()) self.result = 0 

Des commentaires sur le code sont également présents.

Considérons maintenant une fonction qui répondra aux opérations de pression "+" , "-" , etc.

  clear() -  ,       def pressed_equal(self): button = self.sender() self.first_value = float(self.lineEdit.text()) self.lineEdit.clear() self.label.setText(str(self.first_value) + button.text()) self.equal = button.text() 

Nous écrivons la première valeur dans la variable self.first_value et effaçons notre champ afin d'entrer la valeur de l'opération, puis la sortie vers lineEdit (notre champ d'entrée et de résultat principal) avec le nombre et l'opération.

Pourquoi flotter ? Je peux répondre pour que je décide de tout faire flotter , et lors de la sortie de la valeur dans le bloc de résultat, si le résultat a «.0» à la fin, supprimez cette partie afin que le nombre soit un entier. Je ne pensais pas à un meilleur.

Nous avons maintenant des fonctions pour appuyer sur les chiffres et pour appuyer sur les opérations, quelle est la prochaine étape? Ensuite, nous devons afficher le résultat, c'est le bouton = (ENTER) .

  def function_result(self): if self.equal == '+': self.function_addition() elif self.equal == '-': self.function_subtraction() elif self.equal == "/": self.function_divison() elif self.equal == '*': self.function_multiply() elif self.equal == "^": self.exponentiation() elif self.equal == "%": self.function_percent() elif self.equal == "log": self.function_log() 

Permettez-moi de vous rappeler que la variable self.first_value est maintenant égale à la première variable que nous introduisons et self.equal contient l'opération sur laquelle nous avons cliqué. Après avoir entré le deuxième nombre et appuyé sur = , nous essayons de savoir quelle est l'opération, puis nous déterminons la 2e variable.

Nous passons aux fonctions des opérations. Je l'ai comme ça:

  def function_addition(self): self.determinate_second_value() self.result = float(self.first_value + self.second_value) self.form_result() def function_subtraction(self): self.determinate_second_value() self.result = float(self.first_value - self.second_value) self.form_result() def function_divison(self): self.determinate_second_value() self.result = float(self.first_value / self.second_value) self.form_result() def function_multiply(self): self.determinate_second_value() self.result = float(self.first_value * self.second_value) self.form_result() def function_exponentiation(self): self.determinate_second_value() self.result = float(self.first_value ** self.second_value) self.form_result() def function_percent(self): self.determinate_second_value() self.result = float(self.first_value * (self.second_value / 100)) self.form_result() def function_log(self): self.determinate_second_value() self.result = float(math.log(self.first_value, self.second_value)) self.form_result() 

La fonction self.determinate_second_value () détermine la deuxième valeur de la variable que nous avons entrée. Ce n'est pas un peu logique et tordu, mais en l'état, j'essaierai de prendre en compte toutes les erreurs plus tard dans les commentaires lorsque les gens intelligents diront comment.

Un petit rafraîchissement.

  • self.first_value - a la valeur du premier nombre entré
  • self.equal - a str la variable de l'opération sur laquelle nous avons appuyé
  • self.second_value - a la valeur de la deuxième variable

Ensuite, dans chacune des fonctions d'opérations, nous appelons self.form_result () , qui, étrangement, forme notre résultat. Nous conservons le résultat dans la variable self.result .

  def form_result(self): self.result = str(self.result) if self.result[-2:] == '.0': self.result = self.result[:-2] self.lineEdit.setText(str(self.result)) self.label.clear() 

Je vais expliquer pour self.result [-2:] . [-2:] signifie que nous comparons les 2 derniers caractères de la chaîne avec ".0".

Notre résultat est donc affiché dans le bloc lineEdit principal, félicitations.

Je vais également joindre ici un code qui supprime un caractère d'une chaîne ou le nombre entier ou ajoute "." (point) pour créer un nombre fractionnaire:

  def make_fractional(self): value = self.lineEdit.text() if '.' not in value: self.lineEdit.setText(value + '.') def function_delete(self): value = self.lineEdit.text() self.lineEdit.setText(value[:-1]) def function_clear(self): self.lineEdit.setText('0') 

Tout le code sous le spoiler:

Code entier
 from PySide2 import QtWidgets from calc_ui import Ui_MainWindow import sys import math class Calculator(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() #    Ui ( ) self.setupUi(self) self.show() self.lineEdit.setText('0') self.first_value = None self.second_value = None self.result = None self.example = "" self.equal = "" # pressed self.pushButton.clicked.connect(self.digit_pressed) # 1 self.pushButton_2.clicked.connect(self.digit_pressed) # 2 self.pushButton_3.clicked.connect(self.digit_pressed) # 3 self.pushButton_4.clicked.connect(self.digit_pressed) # 4 self.pushButton_5.clicked.connect(self.digit_pressed) # 5 self.pushButton_6.clicked.connect(self.digit_pressed) # 6 self.pushButton_7.clicked.connect(self.digit_pressed) # 7 self.pushButton_8.clicked.connect(self.digit_pressed) # 8 self.pushButton_9.clicked.connect(self.digit_pressed) # 9 self.pushButton_10.clicked.connect(self.digit_pressed) # 0 self.pushButton_add.clicked.connect(self.pressed_equal) # + self.pushButton_ded.clicked.connect(self.pressed_equal) # - self.pushButton_div.clicked.connect(self.pressed_equal) # / self.pushButton_mul.clicked.connect(self.pressed_equal) # * self.pushButton_exp.clicked.connect(self.pressed_equal) # ** self.pushButton_log.clicked.connect(self.pressed_equal) # log self.pushButton_procent.clicked.connect(self.pressed_equal) # % self.pushButton_ENTER.clicked.connect(self.function_result) # = self.pushButton_C.clicked.connect(self.function_clear) # C self.pushButton_point.clicked.connect(self.make_fractional) # . self.pushButton_delete.clicked.connect(self.function_delete) # < self.pushButton_open_skob.clicked.connect(self.create_big_example) # ( def digit_pressed(self): # sender - ,     (   ,    ) button = self.sender() if self.lineEdit.text() == '0': self.lineEdit.setText(button.text()) else: if self.result == self.lineEdit.text(): self.lineEdit.setText(button.text()) else: self.lineEdit.setText(self.lineEdit.text() + button.text()) self.result = 0 def form_result(self): self.result = str(self.result) if self.result[-2:] == '.0': self.result = self.result[:-2] self.lineEdit.setText(str(self.result)) self.label.clear() def make_fractional(self): value = self.lineEdit.text() if '.' not in value: self.lineEdit.setText(value + '.') def function_delete(self): value = self.lineEdit.text() self.lineEdit.setText(value[:-1]) def function_clear(self): self.lineEdit.setText('0') def pressed_equal(self): button = self.sender() self.first_value = float(self.lineEdit.text()) self.lineEdit.clear() self.label.setText(str(self.first_value) + button.text()) self.equal = button.text() def function_addition(self): self.determinate_second_value() self.result = float(self.first_value + self.second_value) self.form_result() def function_subtraction(self): self.determinate_second_value() self.result = float(self.first_value - self.second_value) self.form_result() def function_divison(self): self.determinate_second_value() self.result = float(self.first_value / self.second_value) self.form_result() def function_multiply(self): self.determinate_second_value() self.result = float(self.first_value * self.second_value) self.form_result() def function_exponentiation(self): self.determinate_second_value() self.result = float(self.first_value ** self.second_value) self.form_result() def function_percent(self): self.determinate_second_value() self.result = float(self.first_value * (self.second_value / 100)) self.form_result() def function_log(self): self.determinate_second_value() self.result = float(math.log(self.first_value, self.second_value)) self.form_result() def determinate_second_value(self): self.second_value = float(self.lineEdit.text()) self.lineEdit.clear() self.label.setText(str(self.first_value) + self.equal + str(self.second_value)) def function_result(self): if self.equal == '+': self.function_addition() elif self.equal == '-': self.function_subtraction() elif self.equal == "/": self.function_divison() elif self.equal == '*': self.function_multiply() elif self.equal == "^": self.exponentiation() elif self.equal == "%": self.function_percent() elif self.equal == "log": self.function_log() if __name__ == '__main__': #   QApplication app = QtWidgets.QApplication(sys.argv) #    calc = Calculator() #  sys.exit(app.exec_()) 


Oui, la calculatrice ne calcule pas les grandes fonctions et expressions, j'y travaille!

Merci beaucoup pour votre attention. Bonne chance et développez-vous! C'est génial.

Je voudrais également vous inviter sur ma chaîne JuniorProger Telegram, où je parle de la vie d'un programmeur junior et de sa façon épineuse mais très intéressante de devenir un spécialiste de l'informatique.

Source: https://habr.com/ru/post/fr458536/


All Articles