簡體   English   中英

在啟動樹莓派時加載 GUI Python 腳本

[英]Loading GUI Python script on boot for raspberry pi

我在 Raspberry Pi 3B+(Raspbian)上,我正在嘗試在啟動時加載 Python 腳本,該腳本將 720p 圖像顯示為全屏模式,然后用戶應該能夠按下按鈕 go 到下一個圖像。

目前,我已經創建了允許圖像顯示和圖像由於按鈕而改變的代碼。

現在我無法將圖像加載到全屏模式並在啟動時啟動。 我遵循了許多關於如何在啟動時加載 GUI Python 腳本的指南和教程,但它們似乎都不適用於我的特定腳本(但它們在啟動時從他們的示例腳本成功加載)這讓我覺得有一個代碼中關於為什么它無法啟動的問題(可能是因為我沒有實現它們以全屏打開)。 這些是我嘗試過的所有指南( https://www.raspberrypi-spy.co.uk/2015/02/how-to-autorun-a-python-script-on-raspberry-pi-boot/raspberry pi:啟動時自動運行 GUIhttps: //raspberrypi.stackexchange.com/questions/4123/running-a-python-script-at-startup,https://www.digikey.ca/en/maker/blogs/ 2018/how-to-run-python-programs-on-a-raspberry-pihttps://www.instructables.com/Raspberry-Pi-Launch-Python-script-on-startup/,https ://bc -robotics.com/tutorials/running-python-program-boot-raspberry-pi/ ),我想專注於本教程中針對我的問題的 GUI 方法( https://learn.sparkfun.com/tutorials/如何運行樹莓派程序啟動/全部

在 GUI 編程方面,我現在是一個初學者(我從網上獲取了原始腳本並對其進行了修改以包含按鈕),我不太確定如何將全屏選項實現到顯示圖像的代碼。

這是我目前擁有的(將圖像加載到 window 中,然后您可以使用按鈕更改為下一個圖像)。 在我的代碼的開頭,我嘗試從后面列出的示例中添加一些函數,這些函數允許切換全屏以及它們在底部的相關根函數以補充這一點

import tkinter as tk
from PIL import Image, ImageTk
import time
import sys
import os
import keyboard
import RPi.GPIO as GPIO
import time

    
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(10, GPIO.FALLING) 

def toggle_fullscreen(event=None):    # I added this in to try full screen

    global root
    global fullscreen

    # Toggle between fullscreen and windowed modes
    fullscreen = not fullscreen
    root.attributes('-fullscreen', fullscreen)
    resize()

# Return to windowed mode
def end_fullscreen(event=None):  # I added this in to try full screen

    global root
    global fullscreen

    # Turn off fullscreen mode
    fullscreen = False
    root.attributes('-fullscreen', False)

root= tk.Tk()  # I added this in to try full screen
class HiddenRoot(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        #hackish way, essentially makes root window
        #as small as possible but still "focused"
        #enabling us to use the binding on <esc>
        self.wm_geometry("0x0+0+0")

        self.window = MySlideShow(self)
        #self.window.changeImage()
        self.window.startSlideShow()


class MySlideShow(tk.Toplevel):
    def __init__(self, *args, **kwargs):
        tk.Toplevel.__init__(self, *args, **kwargs)
        #remove window decorations 
        self.overrideredirect(True)

        #save reference to photo so that garbage collection
        #does not clear image variable in show_image()
        self.persistent_image = None
        self.imageList = []
        self.pixNum = 0

        #used to display as background image
        self.label = tk.Label(self)
        self.label.pack(side="top", fill="both", expand=True)

        self.getImages()
        
        #### Added the GPIO event here
        GPIO.add_event_callback(10, self.changeImage)
        
    def getImages(self):
        '''
        Get image directory from command line or use current directory
        '''
        if len(sys.argv) == 2:
            curr_dir = sys.argv[1]
        else:
            curr_dir = '.'

        for root, dirs, files in os.walk(curr_dir):
            for f in files:
                if f.endswith(".png") or f.endswith(".jpg"):
                    img_path = os.path.join(root, f)
                    print(img_path)
                    self.imageList.append(img_path)

   
    def startSlideShow(self, delay=4):
        myimage = self.imageList[self.pixNum]
        self.pixNum = (self.pixNum + 1) % len(self.imageList)
        self.showImage(myimage)
        #self.after(delay*1000, self.startSlideShow)
     #   while True:
      #      buttonState = GPIO.input(buttonPin)
       #     if buttonState == False:
        #        self.startSlideShow(self, delay=4)
    #@staticmethod
    def changeImage(self, pull_up_down=GPIO.PUD_DOWN):
        prev_input = 0
        while True:
          #take a reading
          input = GPIO.input(10)
          #if the last reading was low and this one high, print
          if ((not prev_input) and input):
            myimage = self.imageList[self.pixNum]
            self.pixNum = (self.pixNum + 1) % len(self.imageList)
            self.showImage(myimage)
          #update previous input
          prev_input = input
          #slight pause to debounce
          time.sleep(0.05)
   #     myimage = self.imageList[self.pixNum]
    #    self.pixNum = (self.pixNum + 1) % len(self.imageList)
     #   self.showImage(myimage)
        

    def showImage(self, filename):
        image = Image.open(filename)  

        img_w, img_h = image.size
        scr_w, scr_h = self.winfo_screenwidth(), self.winfo_screenheight()
        width, height = min(scr_w, img_w), min(scr_h, img_h)
        image.thumbnail((width, height), Image.ANTIALIAS)

        #set window size after scaling the original image up/down to fit screen
        #removes the border on the image
        scaled_w, scaled_h = image.size
        self.wm_geometry("{}x{}+{}+{}".format(scaled_w,scaled_h,0,0))
        
        # create new image 
        self.persistent_image = ImageTk.PhotoImage(image)
        self.label.configure(image=self.persistent_image)


slideShow = HiddenRoot()
slideShow.bind("<Escape>", lambda e: slideShow.destroy())  # exit on esc
slideShow.mainloop()
root.bind('<F11>', toggle_fullscreen)              # I added this in to try full screen
root.bind('<Escape>', end_fullscreen)              # I added this in to try full screen
toggle_fullscreen()                                # I added this in to try full screen
root.mainloop()                                    # I added this in to try full screen
GPIO.cleanup()                 

從我之前說過要注意的那個指南中,這是他們將時鍾加載到全屏模式的代碼(我遵循了他們在啟動時加載腳本的方法)

import tkinter as tk
import tkinter.font as tkFont
import time

###############################################################################
# Parameters and global variables

# Default font size
font_size = -24

# Declare global variables
root = None
dfont = None
frame = None
dtime = None

# Global variable to remember if we are fullscreen or windowed
fullscreen = False

###############################################################################
# Functions

# Toggle fullscreen
def toggle_fullscreen(event=None):

    global root
    global fullscreen

    # Toggle between fullscreen and windowed modes
    fullscreen = not fullscreen
    root.attributes('-fullscreen', fullscreen)
    resize()

# Return to windowed mode
def end_fullscreen(event=None):

    global root
    global fullscreen

    # Turn off fullscreen mode
    fullscreen = False
    root.attributes('-fullscreen', False)
    resize()

# Automatically resize font size based on window size
def resize(event=None):

    global time_dfont
    global button_dfont
    global frame

    # Resize font based on frame height (minimum size of 12)
    # Use negative number for "pixels" instead of "points"
    new_size = -max(12, int((frame.winfo_height() / 2)))
    time_dfont.configure(size=new_size)
    new_size = -max(12, int((frame.winfo_height() / 30)))
    button_dfont.configure(size=new_size)


# Read values from the sensors at regular intervals
def update():

    global root
    global dtime

    # Get local time
    local_time = time.localtime()

    # Convert time to 12 hour clock
    hours = local_time.tm_hour
    if hours > 12:
        hours -= 12

    # Add leading 0s
    shours = str(hours)
    smin = str(local_time.tm_min)
    if hours < 10:
        shours = '0' + shours
    if local_time.tm_min < 10:
        smin = '0' + smin

    # Construct string out of time
    dtime.set(shours + ':' + smin)

    # Schedule the poll() function for another 500 ms from now
    root.after(500, update)

###############################################################################
# Main script

# Create the main window
root = tk.Tk()
root.title("My Clock")

# Create the main container
frame = tk.Frame(root, bg='black')

# Lay out the main container (expand to fit window)
frame.pack(fill=tk.BOTH, expand=1)

# Variables for holding temperature and light data
dtime = tk.StringVar()

# Create dynamic font for text
time_dfont = tkFont.Font(family='Courier New', size=font_size)
button_dfont = tkFont.Font(size=font_size)

# Create widgets
label_time = tk.Label(  frame, 
                        textvariable=dtime, 
                        font=time_dfont, 
                        fg='red', 
                        bg='black')
button_quit = tk.Button(frame, 
                        text="Quit", 
                        font=button_dfont, 
                        command=root.destroy,
                        borderwidth=0,
                        highlightthickness=0, 
                        fg='gray10',
                        bg='black')

# Lay out widgets in a grid in the frame
label_time.grid(row=0, column=0, padx=20, pady=20)
button_quit.grid(row=1, column=0, padx=5, pady=5, sticky=tk.E)

# Make it so that the grid cells expand out to fill window
frame.rowconfigure(0, weight=10)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(0, weight=1)

# Bind F11 to toggle fullscreen and ESC to end fullscreen
root.bind('<F11>', toggle_fullscreen)
root.bind('<Escape>', end_fullscreen)

# Have the resize() function be called every time the window is resized
root.bind('<Configure>', resize)

# Schedule the poll() function to be called periodically
root.after(20, update)

# Start in fullscreen mode and run
toggle_fullscreen()
root.mainloop()

現在我想弄清楚的是如何在我的程序中實現他們進入全屏顯示的方法

謝謝:)!

我不確定我是否真的理解你的問題。

我了解您想將某些事件更改為全屏。 如果是,您只需要更改根的幾何屬性。 比如像

master.geometry("{0}x{1}+0+0".format(master.winfo_screenwidth()-pad, master.winfo_screenheight()-pad))

上面的代碼檢查屏幕大小並減少 w 和 h 上的一些距離以適應屏幕。 看看下面的鏈接。

https://stackoverflow.com/questions/7966119/display-fullscreen-mode-on-tkinter#:~:text=This%20creates%20a%20fullscreen%20window,geometry%20and%20the%20previous%20geometry.&text=You %20can%20use%20wm_attributes%20instead%20of%20attributes%20%2C%20too

您可以使用該調用創建一個 function 並在啟動或按下按鈕時觸發它。

希望我的猜測是正確的,這個答案會有所幫助。

干杯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM