0

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()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
JA23Z
  • 25
  • 5

1 Answers1

2

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()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thank you for this! I successfully was able to make a functioning "switch" from basic to the scientific calculator and vice versa. However, it seems that by using stacked widgets the size of the main window is fixed to the minimum size of the largest "page", the scientific calculator has more buttons than the basic calculator, right now the basic calculator's buttons are so spaced in a large window. What can I do to remedy this? Thank you! – JA23Z Jun 28 '21 at 18:52
  • @JA23Z If you have another problem then create another new post showing images of what you indicate in addition to an outline of what you want to obtain to understand yourself better. Please read [ask] and review the [tour] – eyllanesc Jun 28 '21 at 18:58