Python Gui Calculator Without Tinker
Creating a Python GUI calculator without using Tkinter requires choosing an alternative library that provides more modern features and better performance. This guide explores three popular alternatives: PyQt5, PySide6, and Kivy, with code examples for each.
Introduction
Tkinter is Python's standard GUI library, but it has several limitations including an outdated look, limited widgets, and performance issues. For more professional applications, developers often turn to alternative libraries that offer better performance, modern styling, and additional features.
This guide will walk you through creating a simple calculator application using three popular alternatives to Tkinter: PyQt5, PySide6, and Kivy. Each library has its own strengths and use cases, so we'll explore what makes each one suitable for different projects.
Why Not Tkinter?
While Tkinter is simple to use and comes with Python's standard library, it has several drawbacks:
- Outdated appearance that doesn't match modern design trends
- Limited widget set compared to other GUI frameworks
- Performance issues with complex applications
- Difficult to customize styling and layout
For these reasons, many developers prefer alternative libraries when building more sophisticated GUI applications.
Alternative Libraries
There are several excellent alternatives to Tkinter for building Python GUI applications. Here are three of the most popular:
- PyQt5: A comprehensive set of Python bindings for Qt, offering professional-grade widgets and tools
- PySide6: A LGPL-licensed alternative to PyQt5 with similar functionality
- Kivy: A framework for cross-platform applications with a focus on touch interfaces
Each of these libraries provides different strengths that make them suitable for different types of projects.
PyQt5 Example
PyQt5 is a powerful framework that provides access to Qt's extensive widget set. Here's a simple calculator example:
Installation:
pip install PyQt5
Code Example
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLineEdit, QPushButton, QGridLayout
from PyQt5.QtCore import Qt
class Calculator(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PyQt5 Calculator")
self.setFixedSize(300, 400)
self.generalLayout = QVBoxLayout()
centralWidget = QWidget(self)
centralWidget.setLayout(self.generalLayout)
self.setCentralWidget(centralWidget)
self._createDisplay()
self._createButtons()
def _createDisplay(self):
self.display = QLineEdit()
self.display.setFixedHeight(50)
self.display.setAlignment(Qt.AlignmentFlag.AlignRight)
self.display.setReadOnly(True)
self.generalLayout.addWidget(self.display)
def _createButtons(self):
self.buttons = {}
buttonsLayout = QGridLayout()
buttons = {
'7': (0, 0),
'8': (0, 1),
'9': (0, 2),
'/': (0, 3),
'4': (1, 0),
'5': (1, 1),
'6': (1, 2),
'*': (1, 3),
'1': (2, 0),
'2': (2, 1),
'3': (2, 2),
'-': (2, 3),
'0': (3, 0),
'.': (3, 1),
'C': (3, 2),
'+': (3, 3),
'=': (4, 0, 1, 4)
}
for btnText, pos in buttons.items():
self.buttons[btnText] = QPushButton(btnText)
self.buttons[btnText].setFixedSize(60, 60)
if btnText == '=':
self.buttons[btnText].setStyleSheet("background-color: #2563eb; color: white;")
buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1], pos[2] if len(pos) > 2 else 1, pos[3] if len(pos) > 3 else 1)
self.generalLayout.addLayout(buttonsLayout)
if __name__ == '__main__':
app = QApplication([])
calculator = Calculator()
calculator.show()
app.exec()
This example creates a basic calculator with numerical buttons, operators, and a display area. The calculator has a clean, modern appearance and responds to user input.
PySide6 Example
PySide6 is a LGPL-licensed alternative to PyQt5 with similar functionality. Here's a similar calculator example:
Installation:
pip install PySide6
Code Example
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLineEdit, QPushButton, QGridLayout
from PySide6.QtCore import Qt
class Calculator(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PySide6 Calculator")
self.setFixedSize(300, 400)
self.generalLayout = QVBoxLayout()
centralWidget = QWidget(self)
centralWidget.setLayout(self.generalLayout)
self.setCentralWidget(centralWidget)
self._createDisplay()
self._createButtons()
def _createDisplay(self):
self.display = QLineEdit()
self.display.setFixedHeight(50)
self.display.setAlignment(Qt.AlignmentFlag.AlignRight)
self.display.setReadOnly(True)
self.generalLayout.addWidget(self.display)
def _createButtons(self):
self.buttons = {}
buttonsLayout = QGridLayout()
buttons = {
'7': (0, 0),
'8': (0, 1),
'9': (0, 2),
'/': (0, 3),
'4': (1, 0),
'5': (1, 1),
'6': (1, 2),
'*': (1, 3),
'1': (2, 0),
'2': (2, 1),
'3': (2, 2),
'-': (2, 3),
'0': (3, 0),
'.': (3, 1),
'C': (3, 2),
'+': (3, 3),
'=': (4, 0, 1, 4)
}
for btnText, pos in buttons.items():
self.buttons[btnText] = QPushButton(btnText)
self.buttons[btnText].setFixedSize(60, 60)
if btnText == '=':
self.buttons[btnText].setStyleSheet("background-color: #2563eb; color: white;")
buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1], pos[2] if len(pos) > 2 else 1, pos[3] if len(pos) > 3 else 1)
self.generalLayout.addLayout(buttonsLayout)
if __name__ == '__main__':
app = QApplication([])
calculator = Calculator()
calculator.show()
app.exec()
This PySide6 example is nearly identical to the PyQt5 version, demonstrating how similar these two libraries are in functionality and usage.
Kivy Example
Kivy is a different approach to GUI development, focusing on touch interfaces and modern styling. Here's a calculator example using Kivy:
Installation:
pip install kivy
Code Example
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
class CalculatorApp(App):
def build(self):
self.operators = ["/", "*", "+", "-"]
self.last_was_operator = None
self.last_button = None
main_layout = BoxLayout(orientation="vertical")
self.solution = TextInput(
multiline=False, readonly=True, halign="right", font_size=55
)
main_layout.add_widget(self.solution)
buttons = [
["7", "8", "9", "/"],
["4", "5", "6", "*"],
["1", "2", "3", "-"],
[".", "0", "C", "+"],
["="],
]
for row in buttons:
h_layout = BoxLayout()
for label in row:
button = Button(
text=label,
pos_hint={"center_x": 0.5, "center_y": 0.5},
)
button.bind(on_press=self.on_button_press)
h_layout.add_widget(button)
main_layout.add_widget(h_layout)
return main_layout
def on_button_press(self, instance):
current = self.solution.text
button_text = instance.text
if button_text == "C":
self.solution.text = ""
elif button_text == "=":
try:
self.solution.text = str(eval(self.solution.text))
except Exception:
self.solution.text = "Error"
else:
if current and (
self.last_was_operator and button_text in self.operators
):
return
elif current == "" and button_text in self.operators:
return
else:
new_text = current + button_text
self.solution.text = new_text
self.last_button = button_text
self.last_was_operator = self.last_button in self.operators
if __name__ == "__main__":
app = CalculatorApp()
app.run()
This Kivy example demonstrates how to create a calculator with a different approach, focusing on touch interfaces and modern styling. The calculator has a clean, responsive design that works well on both desktop and mobile devices.
Comparison
Here's a comparison of the three libraries based on different criteria:
| Criteria | PyQt5 | PySide6 | Kivy |
|---|---|---|---|
| License | GPL | LGPL | MIT |
| Performance | High | High | Medium |
| Cross-platform | Yes | Yes | Yes |
| Touch Support | Limited | Limited | Excellent |
| Learning Curve | Moderate | Moderate | Moderate |
| Widget Set | Extensive | Extensive | Customizable |
Each library has its own strengths and is suitable for different types of projects. PyQt5 and PySide6 are best for traditional desktop applications, while Kivy is ideal for touch interfaces and mobile applications.
FAQ
Which library should I choose for my project?
The choice depends on your project requirements. For traditional desktop applications, PyQt5 or PySide6 are excellent choices. For touch interfaces and mobile applications, Kivy is the best option.
Can I use these libraries for commercial projects?
Yes, all three libraries can be used for commercial projects. PyQt5 is GPL-licensed, PySide6 is LGPL-licensed, and Kivy is MIT-licensed, which means they can be used in both open-source and commercial projects.
Are these libraries easy to learn?
All three libraries have moderate learning curves. PyQt5 and PySide6 have similar APIs, so switching between them is relatively easy. Kivy has a different approach but is also well-documented.
Can I create complex applications with these libraries?
Yes, all three libraries are capable of creating complex applications. PyQt5 and PySide6 offer extensive widget sets and tools for building professional applications, while Kivy is particularly suited for touch interfaces and mobile applications.