1

I'm new to PyQt5. I'm currently working on a calculator just for some practice, but for some reason, the app crashes when I use the eval() function in the QLabel().setText() function.

Here's a sample snippet:

import PyQt5.QtWidgets as qtw
import PyQt5.QtGui as qtg

class MainWindow:
    def __init__(self):
        self.win = qtw.QWidget()
        self.win.setLayout(qtw.QVBoxLayout())

        self.label = qtw.QLabel("2+3")
        self.label.setFont(qtg.QFont("consolas", 16))
        self.win.layout().addWidget(self.label)

        self.btn = qtw.QPushButton("Click Me", clicked=self.pressed)
        self.win.layout().addWidget(self.btn)

        self.win.show()

    def pressed(self):
        # self.label.setText("Hello World 123") #  Does not crash
        # print(self.label.text()) #  Does not crash
        self.label.setText(eval(self.label.text())) # Crashes

app = qtw.QApplication([])
main_window = MainWindow()
app.exec_()

Here, the app crashes when I use self.label.setText(eval(self.label.text())). The crash does not happen when I use .setText() or .text() separately (as shown in the snippet), so I'm pretty sure it's not a problem with either of the methods. I'm not able to understand why the app crashes just for using the eval() function.

Is there any solution to this problem? It would be great if anyone could help me out. Thanks in advance.

OS: Windows 11, Python Version: 3.10.5

Lenovo 360
  • 569
  • 1
  • 7
  • 27
  • The real question is: why do you want to use `eval` (which is generally discouraged and should only be used with *extreme* care only when you *actually* know what you're doing)? – musicamante Aug 09 '22 at 15:40
  • @musicamante: Oh! I didn't know. Is there any other way to evaluate a numerical expression? – Lenovo 360 Aug 09 '22 at 15:42

1 Answers1

2

When eval evaluates your expression, that is '2+3', it returns the result of the expression, exactly as it happens in an ordinary interpreted line

>>> 2+3
5

But, all the above elements are int, including the result being printed, while QLabel setText requires a string. Thus

self.label.setText(str(eval(self.label.text())))

str could be indifferently into the eval expression, in that case the result of eval would be of string type.

In any case, keep in mind what @musicamante has commented: whenever possibile, avoid eval and use a custom parser

Buzz
  • 1,102
  • 1
  • 9
  • 24
  • Ah! Can't believe I didn't realize that. Thank you so much! – Lenovo 360 Aug 09 '22 at 16:10
  • You're very welcome. Next time, please, report the exception encountered: it would have been much easier to infer the issue! – Buzz Aug 09 '22 at 16:11
  • The thing is there WAS no exception. I click the button, the app loads for 2 seconds, and closes with `Process finished with exit code -1073740791 (0xC0000409)`. If there was an error, I definitely would've reported that. Thanks. – Lenovo 360 Aug 09 '22 at 16:15
  • Wow very weird. I got the TypeError exception and this let me understand straightforwardly the cause. – Buzz Aug 09 '22 at 16:17
  • 1
    @Lenovo360 Whether you're using an IDE (which not always is able to show the full traceback) or trying to run the script by double clicking it, always try to *also* run it from a terminal or prompt. If you do that with your original script, you will certainly see what caused the error. – musicamante Aug 09 '22 at 16:49
  • @musicamante: Oh yes, you're absolutely right. The traceback shows up when I run it with a terminal. Is there any reason why the traceback doesn't show up when you run it directly from the IDE? I'm using the same interpreter in all places (IDE and Terminal). – Lenovo 360 Aug 09 '22 at 17:00
  • 1
    It may depend on how the IDE works and how its configured (including its debugging). Also, sometimes the IDE might not be able to catch debug warnings/messages that are directly created by Qt. In any case, you should *always* try the program outside of the IDE, even if it doesn't have any problem, as the IDE might use a specific configuration or environment that could make the program behave differently. – musicamante Aug 09 '22 at 17:56