I imatates QT's official documentation to write a calcuator example.
I try to rewrite the source code into python and make some changes. My code is as blow:
import sys
from PySide6.QtWidgets import (QApplication, QSizePolicy, QWidget, QToolButton, QGridLayout)
from PySide6 import QtCore
class Advanced_Calculator(QWidget):
def __init__(self):
super(Advanced_Calculator, self).__init__()
self.mainwindow = QGridLayout(self)
# Digit buttons and operator buttons
self.widget_button = QWidget()
self.button_digit = []
for i in range(0, 10):
self.button_digit.append(Button(str(i)))
self.button_factor = Button("!")
self.button_lbracket = Button("(")
self.button_rbracket = Button(")")
self.button_backspace = Button("<-")
self.button_division = Button("/")
self.button_log = Button("log")
self.button_multiply = Button("X")
self.button_sqrt = Button("√")
self.button_minus = Button("-")
self.button_power = Button("^")
self.button_plus = Button("+")
self.button_abs = Button("|x|")
self.button_const = Button("Const")
self.button_dot = Button(".")
self.button_equal = Button("=")
# Buttons layout with 0 spacing
self.layout_button = QGridLayout()
self.layout_button.setSpacing(0)
self.layout_button.addWidget(self.button_factor, 0, 0, 1, 1)
self.layout_button.addWidget(self.button_lbracket, 0, 1, 1, 1)
self.layout_button.addWidget(self.button_rbracket, 0, 2, 1, 1)
self.layout_button.addWidget(self.button_backspace, 0, 3, 1, 1)
self.layout_button.addWidget(self.button_division, 0, 4, 1, 1)
self.layout_button.addWidget(self.button_log, 1, 0, 1, 1)
for i in range(1, 10):
self.layout_button.addWidget(self.button_digit[i], 3 - ((i - 1) // 3), (i - 1) % 3 + 1, 1, 1)
self.layout_button.addWidget(self.button_multiply, 1, 4, 1, 1)
self.layout_button.addWidget(self.button_sqrt, 2, 0, 1, 1)
self.layout_button.addWidget(self.button_minus, 2, 4, 1, 1)
self.layout_button.addWidget(self.button_power, 3, 0, 1, 1)
self.layout_button.addWidget(self.button_plus, 3, 4, 1, 1)
self.layout_button.addWidget(self.button_power, 3, 0, 1, 1)
self.layout_button.addWidget(self.button_power, 3, 0, 1, 1)
self.layout_button.addWidget(self.button_power, 3, 0, 1, 1)
self.layout_button.addWidget(self.button_power, 3, 0, 1, 1)
self.layout_button.addWidget(self.button_abs, 4, 0, 1, 1)
self.layout_button.addWidget(self.button_const, 4, 1, 1, 1)
self.layout_button.addWidget(self.button_digit[0], 4, 2, 1, 1)
self.layout_button.addWidget(self.button_dot, 4, 3, 1, 1)
self.layout_button.addWidget(self.button_equal, 4, 4, 1, 1)
self.widget_button.setLayout(self.layout_button)
# button layout set to mainwindow
self.mainwindow.addWidget(self.widget_button)
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) -> QtCore.QSize:
size = self.sizeHint()
size.setHeight(size.height + 20)
size.setWidth(max(size.width(), size.height()))
# size.rheight() += 20
# size.rwidth() = max(size.width(), size.height())
return size
if __name__ == "__main__":
app = QApplication([])
Calculator = Advanced_Calculator()
Calculator.show()
sys.exit(app.exec())
When I debug these code, the "Fatal Python error: Cannot recover from stack overflow" occurs. And now it is known to me that the error is caused by the sizeHint() function. Where is the problem?
By the way, the function was rewrite by me with my comprehending of the sizeHint() function. And the official documentation uses the two lines code blow which I made them comments, and it doesn't work, too. Well, I also can't figure out where is the problem.
Consider the code...
def sizeHint(self) -> QtCore.QSize:
size = self.sizeHint()
size.setHeight(size.height + 20)
size.setWidth(max(size.width(), size.height()))
# size.rheight() += 20
# size.rwidth() = max(size.width(), size.height())
return size
The line...
size = self.sizeHint()
causes Button::sizeHint
to call itself leading to infinite recursion and, hence, a stack overflow. Perhaps you meant to call the base class implementation instead...
size = super(Button, self).sizeHint()