I'm in the process of making a calculator for a project, and I wanted it so that if I press an action in the menu bar it turns into a scientific calculator, and if I uncheck it, it goes back to a basic calculator.
So far I was able to successfully add the buttons for the scientific calculator, but I want it to go to the left of the horizontal layout (so the basic buttons are on the right, and the advance buttons are on the left) but I have no idea how to do that. I also don't know yet how to revert it back to a basic calculator once it becomes a scientific calculator. Also for some reason the actions of the buttons of the scientific calculator don't seem to be working properly (if I type a button, it should add a text to the QLineEdit
). I'm quite at a loss as I don't know where to go from here.
Below I've created a simple example of what I did with my calculator.
import sys, os
from PyQt6.QtCore import *
from PyQt6.QtWidgets import *
from PyQt6.QtGui import *
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.allbuttons = {}
#self.setFixedSize(200, 200)
self.setWindowTitle('Try')
self.verlayout = QVBoxLayout()
self.horlayout = QHBoxLayout()
self.qline()
self.wid1()
self.verlayout.addLayout(self.horlayout)
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
self.centralwidget.setLayout(self.verlayout)
def qline(self):
self.line = QLineEdit()
self.line.setFixedHeight(35)
self.verlayout.addWidget(self.line)
def wid1(self):
buttons = QGridLayout()
buttondict = {
'A': (0, 0),
'B': (0, 1),
'C': (1, 0),
'D': (1, 1)
}
for btn, pos in buttondict.items():
self.allbuttons[btn] = QPushButton(btn)
self.allbuttons[btn].setFixedSize(20, 20)
buttons.addWidget(self.allbuttons[btn], pos[0], pos[1])
self.horlayout.addLayout(buttons)
def wid2(self):
buttons = QGridLayout()
buttondict = {
'E': (0, 0),
'F': (0, 1),
'G': (1, 0),
'H': (1, 1)
}
for btn, pos in buttondict.items():
self.allbuttons[btn] = QPushButton(btn)
self.allbuttons[btn].setFixedSize(20, 20)
buttons.addWidget(self.allbuttons[btn], pos[0], pos[1])
self.horlayout.addLayout(buttons)
class Menu:
def __init__(self, MainWindow):
super().__init__()
self.view = MainWindow
self.menuBar = QMenuBar()
self.menuBar.setGeometry(QRect(0, 0, 277, 22))
self.view.setMenuBar(self.menuBar)
self.open = QMenu(self.menuBar)
self.open.setTitle('Open')
self.menuBar.addAction(self.open.menuAction())
self.this = QAction(self.menuBar)
self.this.setText('This')
self.this.setCheckable(True)
self.open.addAction(self.this)
self.this.triggered.connect(self.show_new_window)
def show_new_window(self, checked):
if checked:
self.view.wid2()
#self.view.resize(300, 200)
else:
pass
app = QApplication(sys.argv)
w = MainWindow()
m = Menu(w)
w.show()
app.exec()
Instead of wanting to remove and add layouts you should use a QStackedWidget:
import sys
from functools import cached_property
from PyQt6.QtCore import QRect, Qt
from PyQt6.QtGui import QAction
from PyQt6.QtWidgets import (
QApplication,
QGridLayout,
QLineEdit,
QMainWindow,
QMenu,
QMenuBar,
QPushButton,
QStackedWidget,
QVBoxLayout,
QWidget,
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Try")
central_widget = QWidget()
self.setCentralWidget(central_widget)
lay = QVBoxLayout(central_widget)
lay.addWidget(self.lineedit)
lay.addWidget(self.stacked_widget, alignment=Qt.AlignmentFlag.AlignCenter)
maps = [
{"A": (0, 0), "B": (0, 1), "C": (1, 0), "D": (1, 1)}, # first page
{"E": (0, 0), "F": (0, 1), "G": (1, 0), "H": (1, 1)}, # second page
]
for m in maps:
page = self.create_page(m)
self.stacked_widget.addWidget(page)
@cached_property
def stacked_widget(self):
return QStackedWidget()
@cached_property
def lineedit(self):
le = QLineEdit()
le.setFixedHeight(35)
return le
def create_page(self, map_letters):
page = QWidget()
grid_layout = QGridLayout(page)
for name, pos in map_letters.items():
button = QPushButton(name)
button.setFixedSize(20, 20)
grid_layout.addWidget(button, *pos)
return page
class Menu:
def __init__(self, MainWindow):
super().__init__()
self.view = MainWindow
self.menuBar = QMenuBar()
self.menuBar.setGeometry(QRect(0, 0, 277, 22))
self.view.setMenuBar(self.menuBar)
self.open = QMenu(self.menuBar)
self.open.setTitle("Open")
self.menuBar.addAction(self.open.menuAction())
self.this = QAction(self.menuBar)
self.this.setText("This")
self.this.setCheckable(True)
self.open.addAction(self.this)
self.this.triggered.connect(self.show_new_window)
def show_new_window(self, checked):
self.view.stacked_widget.setCurrentIndex(1 if checked else 0)
def main():
app = QApplication(sys.argv)
w = MainWindow()
m = Menu(w)
w.show()
app.exec()
if __name__ == "__main__":
main()