[PYTHON] A memo that reproduces the slide show (gadget) of Windows 7 on Windows 10.

What I aimed for

In the past, Windows 7 had a feature called a gadget, and one of them was called a slide show. I will make something close to this. The following are the minimum functions you want to meet when creating.

--Randomly project the images in the folder --The image is displayed in the foreground --No window frame --You can freely set the number of seconds and size

Why i decided to make

In the Win7 era, I was looking at the pictures of cats in the slide show when I was feeling down or when I wanted to calm down ... When I became Win10 and the gadget function disappeared, I was a little depressed, but the disappearance did not cause a big problem, and I completely forgot its existence.

One day when I was very upset, "Oh, if there is something that calms me down ..." At that time, I suddenly remembered this gadget. "I want to put a picture of a cat in the foreground !!! I want to be healed !!!" And now it is.

environment

VScode Python3.7

I made

スライドショー00.pngスライドショー01.png

It moved like that ...!

Chord (from the code at the end of the text)

Randomly project the images in the folder

def random_pic():
    # ~~~abridgement~~~
    while True:
        img_list = glob.glob(pict_dir + '\\*')
        pict = random.choice(img_list)
        if pict.lower().endswith(img_types):
            return pict

Of the paths stored in pict_dir (set outside the function in the above code to make it easier to see where it is) Randomly select the one that matches the extension in img_types.

Image is brought to the foreground & no window border

class Slideshow_window:
    def __init__(self):
        # ~~~abridgement~~~
        self.window = sg.Window('', self.layout, finalize=True, no_titlebar=True, location=(self.winsize.width-360, 0), 
                    keep_on_top=True, grab_anywhere=True, element_padding=((0,0),(0,0)), margins=(0,0), alpha_channel=1)

Thank you very much for this site.

Being able to freely set the number of seconds and size

class ConfigDisplay:
    # ~~~abridgement~~~

The setting screen can be displayed in the second class. Various settings can be applied by pressing the Set button. I try to get all the events with if so that I don't get an error when I leave it blank, but I want to be able to write it well because it's not beautiful.

Where you want to improve

  1. Folder name on the setting screen If it is a short path, it will be displayed, but if it is placed deep in the hierarchy, the path will be long and will only be displayed halfway. I want to be able to see at a glance which folder I chose. スライドショー02.pngスライドショー03.png

  2. Processing when a folder without images is selected I haven't processed the error because it's for my own use, but I want to be able to display "No image" when selecting a folder that does not have an image file.

  3. Save the folder settings for displaying images When I select a different folder on the setting screen, I want to select that folder the next time I start it. Is it necessary to save the path in a text file when straddling the start/end of the program? I have no idea.

  4. Window position after resizing Currently, the position of the image display is set to the upper right of the display, but since it depends on the initial image size, if you change the size from the setting ... Slideshow 04.png

It will be like this. I want to be able to take the upper right as the base point regardless of the size.

at the end

I think I have created a function that meets my needs. I would like to continue making improvements in the future. I also want to learn beautiful coding.

Small words

I wonder if this gadget function was in demand at that time ...

code

Slideshow.py
#!python3.7

import glob
import io
import random
import time

import PySimpleGUI as sg
import pyautogui
from PIL import Image, ImageTk

pict_dir = "Folder you want to display in the slide show"
img_types = (".jpg ",".jpeg ",".jfif")

# img_A function that randomly takes one image that matches the extension of types
def random_pic():
    global pict_dir
    global img_types
    while True:
        img_list = glob.glob(pict_dir + '\\*')
        pict = random.choice(img_list)
        if pict.lower().endswith(img_types):
            return pict


#A function that opens image data and takes information
"""
Referenced site
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Img_Viewer.py
"""
def get_img_data(f, maxsize, first=False):
    im = Image.open(f)
    im.thumbnail(maxsize)
    if first:                     # tkinter is inactive the first time
        bio = io.BytesIO()
        im.save(bio, format="PNG")
        del im
        return bio.getvalue()
    return ImageTk.PhotoImage(im)


#Take the size of the window
def get_window_size():
    window_size = pyautogui.size()
    return window_size


#Main window
"""
Referenced site
https://qiita.com/melka-blue/items/33c89a62c2392bbbd450
"""
class Slideshow_window:
    def __init__(self):
        self.tout = 90000                       #Random interval of images (milliseconds)
        self.maxw = 360                         #Maximum width of display image
        self.maxh = 240                         #Maximum height of the displayed image
        self.winsize = get_window_size()        #Window size for adjusting image display position
        self.pfile = random_pic()
        # sg.theme('Change Theme to your liking')

        # ------Window layout------ 
        self.image_col = [[sg.Image(data=get_img_data(self.pfile, (self.maxw, self.maxh), first=True), key='-IMAGE-')]]
        self.layout = [[sg.Column(self.image_col, element_justification='c')]]
        self.window = sg.Window('', self.layout, finalize=True, no_titlebar=True, location=(self.winsize.width-360, 0), 
                    keep_on_top=True, grab_anywhere=True, element_padding=((0,0),(0,0)), margins=(0,0), alpha_channel=1)

    def next_picture(self, previousfile='NONE'):
        self.pfile = random_pic()
        #Processing to avoid the case where the same image as the previously displayed image is randomly selected
        while self.pfile == previousfile:
            self.pfile = random_pic()
        self.window['-IMAGE-'].Update(data=get_img_data(self.pfile, (self.maxw, self.maxh)))

    def open_config(self):
        disp2 = ConfigDisplay()
        disp2.main()
        del disp2
        self.next_picture(previousfile=self.pfile)

    def main(self):
        #Set key bindings → Escape: Exit, s: Settings, n: Show next photo
        self.window.bind('<Escape>', 'esc') 
        self.window.bind('<s>', 'setting') 
        self.window.bind('<n>', 'next')

        while True:
            # timeout(millisecond)Set to timeout over time_key='-TIMEOUT-'Raise an event
            event, _ = self.window.read(timeout=self.tout, timeout_key='-TIMEOUT-')
            if event in (None, 'esc'):
                break
            elif event == 'setting':
                self.open_config()
            elif event == 'next' or event == '-TIMEOUT-':
                self.next_picture(previousfile=self.pfile)
        self.window.close()


#Settings screen window
class ConfigDisplay:
    def __init__(self):
        sg.theme('GreenMono')
        self.layout2 = [
                    [sg.Text('Display destination',size=(5,1)), sg.Input(default_text=pict_dir, key="-PICDIR-",size=(40, 1)), sg.FolderBrowse(size=(5,1),initial_folder=pict_dir[:pict_dir.rfind("\\")])],
                    [sg.Text("The number of seconds",size=(5,1)),  sg.InputText(default_text=int(disp1.tout/1000) ,key="-INTIME-",size=(5,1))],
                    [sg.Text("Maximum width",size=(5,1)),  sg.InputText(default_text=disp1.maxw ,key="-SIZEW-",size=(5,1)), 
                     sg.Text("Maximum height",size=(5,1)),  sg.InputText(default_text=disp1.maxh, key="-SIZEH-",size=(5,1))],
                    [sg.Button("Set",key="-SETOK-",size=(10,1))]]
        self.window = sg.Window("ConfigDisplay", self.layout2, no_titlebar=True, keep_on_top=True, location=(disp1.winsize.width-450, 100))

    def main(self):
        global pict_dir
        while True:
            event, value = self.window.read()
            #What to do when the Set button is pressed
            if event == "-SETOK-":
                if value['-PICDIR-'] != '':
                    pict_dir = value['-PICDIR-']
                if value['-INTIME-'] != '':
                    #In the input window, input in seconds, so return to milliseconds
                    disp1.tout = int(value['-INTIME-']) * 1000
                if value['-SIZEW-'] != '':
                    disp1.maxw = int(value['-SIZEW-'])
                if value['-SIZEH-'] != '':
                    disp1.maxh = int(value['-SIZEH-'])
                break
        self.window.close()


if __name__ == "__main__":
    disp1 = Slideshow_window()
    disp1.main()

Recommended Posts

A memo that reproduces the slide show (gadget) of Windows 7 on Windows 10.
A memo of installing Chainer 1.5 for GPU on Windows
A memo explaining the axis specification of axis
The story of making a tool that runs on Mac and Windows at the game development site
A memo of a tutorial on running python on heroku
Calculate the probability of outliers on a boxplot
A story that reduces the effort of operation / maintenance
[Python] A program that counts the number of valleys
A memo to visually understand the axis of pandas.Panel
Make a BOT that shortens the URL of Discord
A memo that implements the job of loading a GCS file into BigQuery in Python
# Function that returns the character code of a string
Building a TensorFlow environment that uses GPU on Windows 10
Generate that shape of the bottom of a PET bottle
A memo that I touched the Datastore with python
A memo on how to overcome the difficult problem of capturing FX with AI
A story that analyzed the delivery of Nico Nama.
A Study on Visualization of the Scope of Prediction Models
[Python] A program that compares the positions of kangaroos.
Create a shape on the trajectory of an object
Create a bot that only returns the result of morphological analysis with MeCab on Discord
A tool that automatically turns the gacha of a social game
A note on the default behavior of collate_fn in PyTorch
Follow the mystery of orthographic-pedant that suddenly appeared on GitHub !!
A memo about the behavior of bowtie2 during multiple hits
Until the start of the django tutorial with pycharm on Windows
A rough summary of the differences between Windows and Linux
Memo of Linux environment construction using VirtualBox + Vagrant on Windows 10
A memo that solves the knapsack problem by the greedy algorithm
Construction of a neural network that reproduces XOR by Z3
A Python script that compares the contents of two directories
Yield in a class that inherits unittest.TestCase didn't work with nose (depending on the version of nose?)
I tried to create a server environment that runs on Windows 10
When incrementing the value of a key that does not exist
When a Windows fatal exception: access violation occurs on the tensorboard
pandas Fetch the name of a column that contains a specific character
A formula that simply calculates the age from the date of birth
A story that struggled to handle the Python package of PocketSphinx
On Linux, the time stamp of a file is a little past.
A function that measures the processing time of a method in python
The story of creating a site that lists the release dates of books
Find the rank of a matrix in the XOR world (rank of a matrix on F2)
A command to easily check the speed of the network on the console
I made a slack bot that notifies me of the temperature
[Windows] A story of a beginner who stumbles on Anaconda's PATH setting.
[python] A note that started to understand the behavior of matplotlib.pyplot
The story of making a module that skips mail with python
[Python] A program that rotates the contents of the list to the left
Get the number of readers of a treatise on Mendeley in Python
I did a preliminary survey of the API that receives Zoom meeting entry / exit webhooks on Lambda (1)
Python environment construction memo on Windows 10
Create a Linux environment on Windows 10
Location of pip.ini (pip.conf) on Windows 10
The story of writing a program
Approximation of distance between two points on the surface of a spheroid (on the surface of the earth)
A story that visualizes the present of Qiita with Qiita API + Elasticsearch + Kibana
[Python] A program that calculates the number of chocolate segments that meet the conditions
Randomly play the movie on ChromeCast for a certain period of time
I made a calendar that automatically updates the distribution schedule of Vtuber
Introducing a library that was not included in pip on Python / Windows
A memo for utilizing the unit test mechanism KUnit of the Linux kernel