Tuesday, 26 November 2024

Learning Python Part 9

First we went over Pep8 standards, you can find them here: https://peps.python.org/pep-0008/

    Note on the upcoming HW, we need to use PyQt5 but Python 3.12 does not support it. We needed to go down to python 3.9 inside of visual studio and visual studio code. I also had to do 'python pip install PyQt5' for vscode to run it. 

    To check over if you have PyQt5 installed correctly, try importing PyQt5 and run the script to see if it runs without errors. We're going to be importing these modules: 

import sys

from PyQt5.QtGui import QWindow

from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton

    You're going to want to create a class to hold your interface. Start by creating a class that inherits the QWidget class.


    Next we need:
app = QApplication(sys.argv)

    Because we are going to be sending arguments from the command line to our window. We're also going to be creating a seperate thread  thats running for our window.
    To run the script and open the window, you need to include
window = MyHBox()
window.show()

app.exec()
    Running this will give you an empty window with the command prompt open. The window is tied to the command prompt, if you close the command prompt it will also close the window (But if you close the python window the command prompt won't close).

    Now we want to specify the type of layout for our window. For a horizontal layout, we can use QHBoxLayout()
    
QHBoxLayout() is like a container node within Houdini, it's going to hold stuff. Running this again will get you another empty window but smaller. But once you start adding buttons, you can see the layout come into play. 

    The QPushButton needs a name, and a reference to itself, so it knows where to attach the button. Now you should get a window with 3 buttons in it. 
horizontal layout with 3 buttons

    If you want a vertical layout, you can change QHBoxLayout() to QVBoxLayout(). There's also a grid layout. With a grid layout, you need to specify an x and a y value for it. 
   
grid layout with 10 buttons

    The above code says we want to make 10 buttons. The x coordinate is x divided by 5, but the // tells python to divide the integer
, but it will not give us a floating point number. Instead it takes the 'floor' of the answer. Meaning 1 divided by 5 is 0. Think of rounding down. The y coordinate is y modulus 5, meaning it takes the remainder of the division. 
    So far we've made buttons, but they don't do anything. 

Slots to handle signals
Assign slot to handle signal 
self.<Signal Name>.connect(<Slot Function Name>)
    The signal can be many things, from push down to release to hover over, etc. You choose the signal you want the button to have. Then once the button gets that signal, it send that signal to everything in the script, so that anything that is listening to that signal with trigger it's function it's connected to it. This is a much more efficient way that callbacks. 
    Inside of your window class, you can add the connect function right after creating a button to assign a function to it. Here we've chosen the signal 'clicked' so that when we click the button it executes the function. You can look at the documentation to see other signals. 

the function that gets called when we press the button
    Notice how we don't have any parenthesis next to the function eatBacon within the connect function, so we can't send arguments to it. We can use a lambda function to help

lambda

    A lambda is a small anonymous function. It can have multiple arguments but only one expression. It's used to call within arguments. 
variable = lambda <arguments>: <expression> 
the print button name function

  Here we have 2 buttons, one named Johnny and one named Joey. In the connect function. we have a lambda function, with a colon and then the function we want to pass through. 

What if we want to create a for loop to create a bunch of buttons like in the grid layout. We can use partials to help with connecting the functions to the buttons (before you had to do it by hand, because if you did it in a for loop python would only remember the last button in the loop). All you have to do is include partial() inside the connect funciton. Then inside of partial, first include the function you want to have, and then a 
the module for partial
    Make sure you also add:
from functools import partial
    So that we can use partial in our function.

    If we want to add icons, add the tiny pngs to the folder you're building the application in. Then you'll want to make a list with tuples with the name you want the buttons as well as the png names.
make sure you also grab the QIcon module from the PyQt5.QtGui
    Add the png with the setIcon function. 



No comments:

Post a Comment

Shader Tool Week 3 - Surface Mapping

 Texture Cubes     Also known as cube maps, its 6 2D texture maps corresponding to the faces of an axis-aligned cube. Used in lighting a sce...