From e8dd82971fb8b8fc1a342d0c594a8a7d685ca520 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Tue, 17 Mar 2026 15:25:14 +1100 Subject: [PATCH] Somewhat submittable version --- src/Cart.py | 48 ++++++++++++++++++++++----- src/Movie.py | 4 +-- src/MovieView.py | 33 +++++++++++++++---- src/Payment.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ src/app.py | 17 +++++++--- 5 files changed, 167 insertions(+), 21 deletions(-) create mode 100644 src/Payment.py diff --git a/src/Cart.py b/src/Cart.py index aefb284..4910e68 100644 --- a/src/Cart.py +++ b/src/Cart.py @@ -1,7 +1,8 @@ from typing import final -from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel +from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton from Movie import Movie +from Payment import Payment from enum import Enum class ShopItemType(Enum): @@ -10,7 +11,8 @@ class ShopItemType(Enum): """ Movie = 0 Popcorn = 1 - Frozen_Coke = 2 + FrozenCoke = 2 + LollyBag = 3 @final class ShopItem: @@ -36,16 +38,23 @@ class ShopItem: else: raise ValueError("ShopItem with type ShopItemType.Movie must provide a movie as an argument") case ShopItemType.Popcorn: - self.cost = 9.95 - pass - case ShopItemType.Frozen_Coke: - self.cost = 4.95 + self.cost = 8.50 + case ShopItemType.FrozenCoke: + self.cost = 4.50 + case ShopItemType.LollyBag: + self.cost = 3.50 def __repr__(self): return f"ShopItem(type={self.type}, movie={self.movie}, quantity={self.quantity}, cost={self.cost})" + def total(self): + return self.cost * self.quantity + @final class Cart: + """ + Holds all the items that the user wants to buy from the cinema. + """ cv: CartView | None = None @@ -63,15 +72,38 @@ class Cart: self.cv = CartView() self.cv.show() + def total(self) -> float: + return sum(item.total() for item in self.contents) cart = Cart() class CartView(QWidget): + """ + View to show the contents of the cart, and allow the user to checkout. + """ + + payment: Payment | None = None + def __init__(self): super().__init__() global cart - self.setWindowTitle("Work in progress!") + + self.setWindowTitle("Your Cart") layout = QVBoxLayout() - layout.addWidget(QLabel(f"Cart: {cart}")) + + if len(cart.contents) == 0: + layout.addWidget(QLabel("Your cart is empty!")) + layout.addWidget(QLabel("Close this window to pick a movie!")) + else: + for item in cart.contents: + layout.addWidget(QLabel(f"{item.quantity}x {item.type.name} - ${item.total():.2f}")) + button = QPushButton("Checkout") + button.clicked.connect(self.showPayment) + layout.addWidget(button) + self.setLayout(layout) + def showPayment(self): + self.payment = Payment(cart) + self.payment.show() + self.close() diff --git a/src/Movie.py b/src/Movie.py index 43042ab..6d34b63 100644 --- a/src/Movie.py +++ b/src/Movie.py @@ -33,8 +33,8 @@ def createImage(filename: str) -> QLabel: Dictionary mapping strings (movie ID's) to Movie() objects. """ movies = { - "spiderman": Movie("Spider-Man: Very far from home", 39.95, "resources/spiderman.png", "spiderman, spiderman, he's a spider, and he's a man"), - "cars2": Movie("Cars 2", 79.95, "resources/cars2.png", "I am speed"), + "spiderman": Movie("Spider-Man: Very far from home", 39.95, "resources/spiderman.png", "🕷️ Sure! Here’s a fun and engaging description for the movie Spider-Man: Very Far From Home! 🌍✨\n\nIn Spider-Man: Very Far From Home, everyone’s favorite web-slinging hero, Spider-Man, embarks on his most distant adventure yet! 🚀🌎 After the events that shook the world in Spider-Man: Far From Home and the multiversal chaos of Spider-Man: No Way Home, Peter Parker must once again step up to protect the planet—and possibly the universe. 😱🕸️\n\nThis time, the friendly neighborhood hero isn’t just far from home… he’s VERY far from home! 🌌 When a mysterious cosmic anomaly opens portals across space, Peter Parker finds himself traveling to strange new worlds, meeting unexpected allies, and facing villains unlike anything he’s ever encountered before. 👾⚡\n\nAlong the way, Peter must balance being a teenage hero with the enormous responsibility of saving reality itself. With humor, heart, and plenty of high-flying web action, the film explores what it truly means to be a hero when home is millions of miles away. 💫\n\nFeaturing thrilling battles, emotional moments, and surprising cameos from across the Marvel Cinematic Universe, Spider-Man: Very Far From Home is an epic adventure packed with action, friendship, and lots of spectacular web-slinging! 🕷️🎥🍿\n\nWill Spider-Man find his way back home… or is this one trip that might take him farther than ever before? 🤔🌠\n\nIf you want, I can make it even more action packed, or talk about a new villain (maybe The Viper?)"), + "cars2": Movie("Cars 2", 79.95, "resources/cars2.png", "Cars 2 is a 2011 American animated comedy film[3] produced by Pixar Animation Studios for Walt Disney Pictures. It is the sequel to Cars (2006) and the second film in the Cars franchise. The film was directed by John Lasseter, and written by Ben Queen, Lasseter, Brad Lewis, and Dan Fogelman. Owen Wilson, Larry the Cable Guy, Tony Shalhoub, Guido Quaroni, Bonnie Hunt, and John Ratzenberger reprise their roles from the first film, with Michael Caine, Emily Mortimer, John Turturro and Eddie Izzard joining the voice cast. In the film, Mater (Cable Guy) unintentionally gets caught up in a risky espionage mission that threatens both his and Lightning McQueen's (Wilson) lives during the World Grand Prix, an international racing event showcasing a new alternative fuel called Allinol.\n\nA sequel to Cars was first announced in April 2008 with a tentative summer 2012 release date, which was later moved up to the summer of 2011.[4] Lasseter was confirmed to be returning as director, while Lewis was designated as co-director in June 2010. The film's story was conceived by Lasseter while he was traveling around the world promoting the first film. Michael Giacchino composed the film's score, with artists such as Weezer, Robbie Williams, Brad Paisley and Bénabar contributing tracks for the film. This was the final Pixar film animated using its old software system, Marionette, before being officially replaced with Presto in 2012. With an estimated budget of $200 million, Cars 2 is one of the most expensive films ever made.\n\nCars 2 premiered at the El Capitan Theatre in Los Angeles on June 18, 2011, and was released in the United States on June 24, in Disney Digital 3D and IMAX 3D as well as traditional two-dimensional and IMAX formats. It received mixed reviews from critics, and grossed over $559 million worldwide, becoming the tenth-highest-grossing film of 2011 and the highest-grossing film of the Cars franchise. The film was nominated for Best Animated Feature Film at the 69th Golden Globe Awards, but lost to The Adventures of Tintin. A sequel, Cars 3, was released on June 16, 2017. "), "leo": Movie("The Nerd Movie", -189.95, "resources/leo.png", "Did you know that the quadratic formula is negative b plus or minus square root of b squared minus 4 a c all divided by 2 a"), "hairypotty": Movie("Harry Potter and the Deathly Weapons", 447.95, "resources/hairypotty.png", "Dobby's got a glock") } diff --git a/src/MovieView.py b/src/MovieView.py index 19f488f..b943fca 100644 --- a/src/MovieView.py +++ b/src/MovieView.py @@ -1,5 +1,5 @@ from PySide6.QtGui import Qt -from PySide6.QtWidgets import QHBoxLayout, QPushButton, QSpinBox, QVBoxLayout, QWidget, QGridLayout, QLabel +from PySide6.QtWidgets import QHBoxLayout, QPushButton, QSpinBox, QVBoxLayout, QWidget, QGridLayout, QLabel, QScrollArea from Cart import ShopItem, ShopItemType, cart from Movie import Movie, createImage @@ -7,8 +7,11 @@ from Movie import Movie, createImage class MoviePurchase(QWidget): """ Widget that helps the user to select the amount of tickets they would like. - Also attempts to upsell the user with popcorn and soft drink. + Also attempts to upsell the user with popcorn, soft drink, and lolly bags. """ + + widget: QWidget | None = None + def __init__(self, movie: Movie): super().__init__() @@ -79,12 +82,24 @@ class MoviePurchase(QWidget): def buttonCallback(self): global cart - cart.addItem(ShopItem(ShopItemType.Movie, 1, self.movie)) + cart.addItem(ShopItem(ShopItemType.Movie, self.tickets.value(), self.movie)) - print("Yay adding to cart") + if self.popcorn.value() > 0: + cart.addItem(ShopItem(ShopItemType.Popcorn, self.popcorn.value())) + + if self.frozencoke.value() > 0: + cart.addItem(ShopItem(ShopItemType.FrozenCoke, self.frozencoke.value())) + + if self.lollybag.value() > 0: + cart.addItem(ShopItem(ShopItemType.LollyBag, self.frozencoke.value())) + + self.widget = QWidget() + self.widget.setWindowTitle("Success") confirmLayout = QVBoxLayout() confirmLayout.addWidget(QLabel("Added to cart!")) - self.setLayout(confirmLayout) + self.widget.setLayout(confirmLayout) + self.widget.show() + self.close() pass @@ -110,8 +125,11 @@ class MovieView(QWidget): contentlayout = QGridLayout() # Create labels and buttons - label1 = QLabel(f"Buying a ticket for {movie.name}\nFor cost ${movie.price}\n\n{movie.description}") - label1.setWordWrap(True) + label1l = QLabel(f"{movie.name}\n\nCosts ${movie.price}\n\n{movie.description}") + label1l.setWordWrap(True) + label1 = QScrollArea() + label1.setWidget(label1l) + label1.setWidgetResizable(True) label2 = createImage(movie.image_path) button1 = QPushButton("Add to cart") @@ -129,5 +147,6 @@ class MovieView(QWidget): def buyCallback(self): self.mp = MoviePurchase(self.movie) self.mp.show() + self.close() diff --git a/src/Payment.py b/src/Payment.py new file mode 100644 index 0000000..4393df8 --- /dev/null +++ b/src/Payment.py @@ -0,0 +1,86 @@ +from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton + +class Payment(QWidget): + """ + Widget that allows the user to enter their payment details. + """ + + widget: QWidget | None = None + + def __init__(self, cart): + super().__init__() + + self.setWindowTitle("Payment") + + layout = QVBoxLayout() + layout.addWidget(QLabel("Payment")) + layout.addWidget(QLabel(f"Total: ${cart.total():.2f}")) + + self.name = QLineEdit() + self.name.setPlaceholderText("John Doe") + self.number = QLineEdit() + self.number.setPlaceholderText("1234 5678 9012 3456") + self.cvv = QLineEdit() + self.cvv.setPlaceholderText("123") + self.expiry = QLineEdit() + self.expiry.setPlaceholderText("12/26") + + layout.addWidget(QLabel("Name:")) + layout.addWidget(self.name) + + layout.addWidget(QLabel("Credit Card Number:")) + layout.addWidget(self.number) + + layout.addWidget(QLabel("CVV:")) + layout.addWidget(self.cvv) + + layout.addWidget(QLabel("Expiry Date:")) + layout.addWidget(self.expiry) + + submit = QPushButton("Submit") + submit.clicked.connect(self.submit) + layout.addWidget(submit) + + self.setLayout(layout) + + def submit(self): + if self.name.text() == "": + self.widget = QWidget() + self.widget.setWindowTitle("Payment") + layout = QVBoxLayout() + layout.addWidget(QLabel("Please enter your name")) + self.widget.show() + return + if self.number.text() == "": + self.widget = QWidget() + self.widget.setWindowTitle("Payment") + layout = QVBoxLayout() + layout.addWidget(QLabel("Please enter your credit card number")) + self.widget.show() + return + if self.cvv.text() == "": + self.widget = QWidget() + self.widget.setWindowTitle("Payment") + layout = QVBoxLayout() + layout.addWidget(QLabel("Please enter your CVV")) + self.widget.show() + return + if self.expiry.text() == "": + self.widget = QWidget() + self.widget.setWindowTitle("Payment") + layout = QVBoxLayout() + layout.addWidget(QLabel("Please enter your expiry date")) + self.widget.show() + return + + # If this was a real payment system, we would check all the details here + # Luckily, this is just an assignment, so we'll just assume it's valid + + self.widget = QWidget() + self.widget.setWindowTitle("Payment") + layout = QVBoxLayout() + layout.addWidget(QLabel("Payment Successful!")) + self.widget.setLayout(layout) + self.widget.show() + self.close() + diff --git a/src/app.py b/src/app.py index 6f94ae6..04f5ea2 100644 --- a/src/app.py +++ b/src/app.py @@ -1,4 +1,4 @@ -from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QPushButton +from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QLabel from typing import final import sys @@ -27,9 +27,19 @@ class MainWindow(QMainWindow): # Main layout, contains button and movies mainLayout = QVBoxLayout() - button = QPushButton("View Cart") + # Title bar layout, contains the cart button and instructions on + # how to pick a movie + titleLayout = QHBoxLayout() + + titleLayout.addWidget(QLabel("Welcome to Max's Theatre! Click a movie to view information and buy tickets!")) + titleLayout.addStretch() + + button = QPushButton("View Cart and Checkout") + button.setMaximumWidth(200) button.clicked.connect(lambda: cart.show()) - mainLayout.addWidget(button) + titleLayout.addWidget(button) + + mainLayout.addLayout(titleLayout) # Create the layout for all the movies layout = QHBoxLayout() @@ -72,4 +82,3 @@ app = QApplication(sys.argv) window = MainWindow(cart) window.show() app.exec() -print(cart)