[PySide6] How to have one button toggle ON/OFF functions of LEDs defined in Python file?
-
Once again, I'm coming to the community for help, as I'm having a hard time finding an answer. Looking over Connections QML Type wasn't much help, as I found the "examples" given weren't really good examples; not for novices, anyway. (The Qt documentation does come across as more catered towards those with an already solid background in understanding different programming languages rather than those of us still getting our feet wet.) Because of that, it confuses me on where to start looking (
Slots
,Signals
,onClicked handlers
,Connections
, etc.). Searching online also doesn't give any results that relate exactly to what I'm looking for.I'm trying to figure out how to have one button turn my LEDs both on and off. (My button is actually an
Image
with button properties.) I know how to set the button to execute one of the functions, but not how to have it execute both. I'd also like the button's two images to reflect the function that's being executed; power_on.svg when LEDs are on, power_on.svg when LEDs are off, but I'll worry about that once I figure this out, first..
↓ main.qml ↓
import QtQuick import QtQuick.Controls ApplicationWindow { width: 800 height: 800 visible: true Image { id: allLights source: 'images/power_' + allLights.buttonState + '.svg' anchors.centerIn: parent property string buttonState: "off" states: [ State { name: 'off' }, State { name: 'on' } ] MouseArea { anchors.fill: parent onClicked: { allLights.buttonState = (allLights.buttonState === 'on') ? 'off' : 'on'; controlPanel.buttonClicked(); } } } }
.
↓ main,py ↓
import sys from pathlib import Path from led import grid, all_lights_on, all_lights_off from PySide6.QtCore import QObject, Slot, Signal from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine class ControlPanel(QObject): buttonClicked = Signal() def __init__(self): super().__init__() @Slot() def buttonClicked(self): all_lights_on(grid) if __name__ == '__main__': app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() controlPanel = ControlPanel() engine.rootContext().setContextProperty("controlPanel", controlPanel) qml_file = Path(__file__).parent / 'main.qml' engine.load(qml_file) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec())
.
↓ led,py ↓
from rpi_ws281x import PixelStrip, Color ### Global LED grid (PixelStrip) configuration ### LED_COUNT = 256 LED_PIN = 18 LED_FREQ_HZ = 800000 LED_DMA = 10 LED_BRIGHTNESS = 25 LED_CHANNEL = 0 LED_INVERT = False """ Initialize the LEDs """ grid = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL) grid.begin() """ Function to retrieve the LED index based on row and column """ def get_led_index(row, col): # Converting 2D coordinates into a 1D LED index # lookup_table = [ [0, 15, 16, 31, 32, 47, 48, 63, 64, 79, 80, 95, 96, 111, 112, 127, 128, 143, 144, 159, 160, 175, 176, 191, 192, 207, 208, 223, 224, 239, 240, 255], [1, 14, 17, 30, 33, 46, 49, 62, 65, 78, 81, 94, 97, 110, 113, 126, 129, 142, 145, 158, 161, 174, 177, 190, 193, 206, 209, 222, 225, 238, 241, 254], [2, 13, 18, 29, 34, 45, 50, 61, 66, 77, 82, 93, 98, 109, 114, 125, 130, 141, 146, 157, 162, 173, 178, 189, 194, 205, 210, 221, 226, 237, 242, 253], [3, 12, 19, 28, 35, 44, 51, 60, 67, 76, 83, 92, 99, 108, 115, 124, 131, 140, 147, 156, 163, 172, 179, 188, 195, 204, 211, 220, 227, 236, 243, 252], [4, 11, 20, 27, 36, 43, 52, 59, 68, 75, 84, 91, 100, 107, 116, 123, 132, 139, 148, 155, 164, 171, 180, 187, 196, 203, 212, 219, 228, 235, 244, 251], [5, 10, 21, 26, 37, 42, 53, 58, 69, 74, 85, 90, 101, 106, 117, 122, 133, 138, 149, 154, 165, 170, 181, 186, 197, 202, 213, 218, 229, 234, 245, 250], [6, 9, 22, 25, 38, 41, 54, 57, 70, 73, 86, 89, 102, 105, 118, 121, 134, 137, 150, 153, 166, 169, 182, 185, 198, 201, 214, 217, 230, 233, 246, 249], [7, 8, 23, 24, 39, 40, 55, 56, 71, 72, 87, 88, 103, 104, 119, 120, 135, 136, 151, 152, 167, 168, 183, 184, 199, 200, 215, 216, 231, 232, 247, 248] ] return lookup_table[row][col] """ Function to set the parameters of a specific region on the LED grid and the color for it """ def set_pixel_color(top_pixel, bottom_pixel, color): for row in range(top_pixel[0], bottom_pixel[0] + 1): for col in range(top_pixel[1], bottom_pixel[1] + 1): index = get_led_index(row, col) grid.setPixelColor(index, color) """ Function to turn off all LEDs """ def clear_grid(): for row in range(8): for col in range(32): index = get_led_index(row, col) grid.setPixelColor(index, Color(0, 0, 0)) """ Function to set the brightness of the LEDs """ def set_brightness(value): grid.setBrightness(value) # ===================================================== # ### All lights ### def all_lights_on(grid): set_brightness(10) pixel_color = Color(255, 0, 0) set_pixel_color((0, 0), (7, 31), pixel_color) grid.show() def all_lights_off(grid): clear_grid() grid.show()
-
I've found a solution, albeit with a small bit of help from ChatGPT as a last resort. I used an
if/else
statement (in the form of aternary operator
) for my main.qml and added an additional@Slot()
decorator for the LED off function in my main,py.
.
.
↓ main.qml ↓import QtQuick import QtQuick.Controls ApplicationWindow { width: 1920 height: 1080 visible: true // Bool property to hold the button state property bool buttonState: false // Function to toggle the LEDs function toggleLEDs() { buttonState ? controlPanel.buttonOff() : controlPanel.buttonOn(); buttonState = !buttonState; } Image { id: allLights source: "images/power_" + (buttonState ? "on" : "off") + ".png" anchors.centerIn: parent MouseArea { anchors.fill: parent onClicked: { toggleLEDs(); } } } }
.
.
↓ main,py ↓import sys from pathlib import Path from led import grid, all_lights_on, all_lights_off from PySide6.QtCore import QObject, Slot from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine class ControlPanel(QObject): def __init__(self): super().__init__() @Slot() def buttonOn(self): all_lights_on(grid) @Slot() def buttonOff(self): all_lights_off(grid) if __name__ == '__main__': app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() controlPanel = ControlPanel() engine.rootContext().setContextProperty("controlPanel", controlPanel) qml_file = Path(__file__).parent / 'main.qml' engine.load(qml_file) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec())
-