Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [PySide6] How to have one button toggle ON/OFF functions of LEDs defined in Python file?
QtWS25 Last Chance

[PySide6] How to have one button toggle ON/OFF functions of LEDs defined in Python file?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qtquickpyside6pythonqtcoreqtqml
2 Posts 1 Posters 902 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    I.Mironov
    wrote on 2 Feb 2024, 19:25 last edited by I.Mironov 2 Mar 2024, 21:59
    #1

    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()
    
    1 Reply Last reply
    0
    • I Offline
      I Offline
      I.Mironov
      wrote on 3 Feb 2024, 17:54 last edited by I.Mironov 2 Mar 2024, 21:58
      #2

      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 a ternary 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())
      
      1 Reply Last reply
      1
      • I I.Mironov has marked this topic as solved on 3 Feb 2024, 17:54

      2/2

      3 Feb 2024, 17:54

      • Login

      • Login or register to search.
      2 out of 2
      • First post
        2/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved