Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading image and show it #51

Closed
Athenaplot opened this issue Aug 26, 2018 · 25 comments
Closed

Loading image and show it #51

Athenaplot opened this issue Aug 26, 2018 · 25 comments
Labels
enhancement New feature or request

Comments

@Athenaplot
Copy link

Hey ,buddy,will you plan to write the code to load images and show it with dialog box?
anyway ,i think what you did is an amazing work!!!

@MikeTheWatchGuy MikeTheWatchGuy added the enhancement New feature or request label Aug 26, 2018
@MikeTheWatchGuy
Copy link
Collaborator

Not sure exactly what you're requesting. I have a demo program that has a dialog box to select a folder full of images and display them one by one.

Take a look at it and let me know if it's not what you meant. Happy to add stuff if it makes it a better package.

A new Canvas Element was just added so that you can draw circles, etc, onto your window!

Check out the PNG viewer demo program for how to use the Image Element. Here's that code:

import PySimpleGUI as sg
import os

# Simple Image Browser based on PySimpleGUI

# Get the folder containing the images from the user
rc, folder = sg.GetPathBox('Image Browser', 'Image folder to open', default_path='X:/- EBAY - Gruen/Images - Oct Nov Dec 2017')
if rc is False or folder is '':
    sg.MsgBoxCancel('Cancelling')
    exit(0)

# get list of PNG files in folder
png_files = [folder + '\\' + f for f in os.listdir(folder) if '.png' in f]
filenames_only = [f for f in os.listdir(folder) if '.png' in f]

if len(png_files) == 0:
    sg.MsgBox('No PNG images in folder')
    exit(0)

# create the form that also returns keyboard events
form = sg.FlexForm('Image Browser', return_keyboard_events=True, location=(0,0), use_default_focus=False )

# make these 2 elements outside the layout because want to "update" them later
# initialize to the first PNG file in the list
image_elem = sg.Image(filename=png_files[0])
filename_display_elem = sg.Text(png_files[0], size=(80, 3))
file_num_display_elem = sg.Text('File 1 of {}'.format(len(png_files)), size=(15,1))

# define layout, show and read the form
col = [[filename_display_elem],
          [image_elem],
          [sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2)), file_num_display_elem]]

col_files = [[sg.Listbox(values=filenames_only, size=(60,30), key='listbox')],
             [sg.ReadFormButton('Read')]]
layout = [[sg.Column(col_files), sg.Column(col)]]
button, values = form.LayoutAndRead(layout)          # Shows form on screen

# loop reading the user input and displaying image, filename
i=0
while True:

    # perform button and keyboard operations
    if button is None:
        break
    elif button in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34') and i < len(png_files)-1:
        i += 1
    elif button in ('Prev', 'MouseWheel:Up', 'Up:38', 'Prior:33') and i > 0:
        i -= 1

    if button == 'Read':
        filename = folder + '\\' + values['listbox'][0]
        # print(filename)
    else:
        filename = png_files[i]

    # update window with new image
    image_elem.Update(filename=filename)
    # update window with filename
    filename_display_elem.Update(filename)
    # update page display
    file_num_display_elem.Update('File {} of {}'.format(i+1, len(png_files)))

    # read the form
    button, values = form.Read()

@Athenaplot
Copy link
Author

I am sorry to bother you for the little problem. My English is not good, So i think my expression is not clear. I have run the demo you recommended. Yes, It's my wanted. I have just found the package PysimpleGUI,i think it's pythonic. I just read your docs,and couldn't find the Image viewer. I am too eager to reading your demos in the github. thank your reply!! @MikeTheWatchGuy

@MikeTheWatchGuy
Copy link
Collaborator

Glad to see you're happy with it!

How did you discover PySimpleGUI and what project do you plan on using it for? When you have something running, please post a screenshot.

Let me know how I can help.

@Athenaplot
Copy link
Author

I discover PySimpleGUI by reading an blog introducing it in the WeChat. I have learned something about pyqt5,but it's too hard for me to solve complex project using pyqt5.But,when i use PySimpleGUI,I am confident to realize some ideas using the package.
I will keep contacting with you if there is any problem. @MikeTheWatchGuy

@Athenaplot Athenaplot reopened this Aug 27, 2018
@MikeTheWatchGuy
Copy link
Collaborator

Your situation is exactly the reason I wrote this package.... you want to run a GUI, but Qt is over your head... Qt is currently over mine so you're in good company.

The whole idea is to be up and running with your GUI within a few minutes of you starting on it. If it's taking longer than 10 minutes to get something visible on the screen, then something's not right.

You should be confident that it'll work for you because it will!

@MikeTheWatchGuy
Copy link
Collaborator

I'm going to close this issue since it sounds like the demo application does what you need it to do. If there are things it's not doing that you would like to see, open another issue.

@Cynwell
Copy link

Cynwell commented Aug 8, 2019

Here's an example written by me to load image and show it in the dialog.

By clicking "Previous" and "Next", images in the message box will also be updated in the same window instead of opening another pop-up. It could be used as a photo gallery, or labeling data (that's my purpose haha) which could be a solution to your question.

image

Codes and more descriptions could be found in my repos:
https://github.com/Cynwell/Image-Labeling-Helper

Feel free to use if you need it :)

@MikeTheWatchGuy
Copy link
Collaborator

It's also possible to display images inside a Graph Element by using the DrawImage method.

Thanks very much for sharing @Cynwell ! A tip for you.... include an image of your application, just as you did above, in your readme. If you have other screens your app makes, include those too! It's super easy if you use GitHub to store your images.

Just copy and paste your image into a GitHub Issue, then copy and paste the text that represents the image in the Issue into your readme. You get the text by "editing" the issue you created or copying it prior to clicking the "Comment" button.

People that have done this have reported a noticeable increase in the number of people showing interest in their project. Looking at your readme now, it's easy to skip over trying it out. But seeing your images above makes me definitely want to try it!

@mcgregor94086
Copy link

I just tried this code and I noticed it did not work with the current PySimpleGui release. I sure would like to see a working code example that works with the current library calls.

@PySimpleGUI
Copy link
Owner

If "this code" means the code at the top of this Issue, then I'm afraid it will not run.

The code was posted over a year ago. A LOT has changed. At the time, PySimpleGUI was about 6 weeks old. Some of the calls have been deprecated and a number of them have been renamed. Much of the time I've maintained backwards compatibility, but it goes back only so far.

The Demo Programs on GitHub are maintained and should all work. There may be a few that needs to be updated, but for the most part they're all good examples of how to work with the package. I just tried the Demo_PNG_Viewer for example and it worked fine.

@Cynwell
Copy link

Cynwell commented Sep 21, 2019

I just tried this code and I noticed it did not work with the current PySimpleGui release. I sure would like to see a working code example that works with the current library calls.

I updated codes. It's working now at the version of PySimpleGUI 4.4.1.

@PySimpleGUI
Copy link
Owner

What was the problem? Was there a change to PySimpleGUI that broke the code?

@Cynwell
Copy link

Cynwell commented Sep 22, 2019

The code was written in PySimpleGUI v4.0.0 but now it has evolved to v4.4.1. I created a layout template and keep re-using throughout my program. It was allowed in v4.0.0 but now raises error in v4.4.1.

The error message was:

UserWarning: *** YOU ARE ATTEMPTING TO RESUSE A LAYOUT! You must not attempt this kind of re-use ***
warnings.warn('
* YOU ARE ATTEMPTING TO RESUSE A LAYOUT! You must not attempt this kind of re-use *', UserWarning)

The way to solve the problem is to change the pre-defined element to a function returning an element.

Example:
prevBtn = sg.Button("Previous")
This raises a re-use layout error.

Solution:

def prevBtn():
    return sg.Button("Previous")

By changing the element into a function, each time the function is called, a new element is created and returned. Therefore, re-use layout problem solved.

@PySimpleGUI
Copy link
Owner

Ah, got it!

I'm glad it caught the error, even though this time it wasn't causing problems for this program.

What I'm attempting to do more of is "error checking" that is another level deep. I've warned in the documentation that re-using it bad, but it's easy to have a bug where you're not doing it on purpose. When this happens things don't work right, produce mysterious results or crashes. This way the error is caught up front and stopped before it can do further damage 😁

It turned the "Golden Rule of Layouts" into the "Golden Law of Layouts".

@deajan
Copy link

deajan commented Jan 4, 2020

@MikeTheWatchGuy Hi,

I also moved an earlier program from PySimpleGUI 3.xy to 4.14 and got into that error.
I struggled to find what layout I reused until I found this thread, and indeed I used a spacer element multiple times, which was easy to fix.

My point is that the error message isn't really clear, my program uses 3 different windows with different layouts, so "YOU ARE ATTEMPTING TO RESUSE A LAYOUT" was quite confusing to me.
Would you mind rewording to "YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN A LAYOUT" or so ?

Best regards.

@PySimpleGUI
Copy link
Owner

Sure, I can change the error to be more descriptive. I thought I output info on the offending element, but I suppose not. I'll make it clearer.

@PySimpleGUI
Copy link
Owner

@deajan

You should have seen not just the warning, but a popup window with a LOT of information.

The current code does this when the re-used element is detected:

                warnings.warn('*** YOU ARE ATTEMPTING TO RESUSE A LAYOUT! You must not attempt this kind of re-use ***', UserWarning)
                PopupError('Error creating layout',
                           'The layout specified has already been used',
                           'You MUST start witha "clean", unused layout every time you create a window',
                           'The offensive Element = ',
                           element,
                           'and has a key = ', element.Key,
                           'This item will be stripped from your layout')

It tells you not just that there's a problem with the layout, but it tells you the element and its key as well as a message that it is being stripped from your layout. You didn't mention the popup window so it makes me wonder if this is from an older release or something,

@PySimpleGUI
Copy link
Owner

This is what you should have seen in addition to the error message

image

@deajan
Copy link

deajan commented Jan 5, 2020

Actually I got that window, but without any info I could use:

image

I don't know what to do with the address of the text object.
As for the text key, it's empty because in my case I reused a spacer like this one:

my_spacer = sg.Text(' ' * 10, font=('Helvetica', 1)))

Indeed I changed my spacer to a function:

    @staticmethod
    def spacer_tweak_fn(pixels=10):
        return sg.T(' ' * pixels, font=('Helvetica', 1))

I use 3 different layouts in my app, so the initial layout reuse error message made me search for a real reuse of my layout variables instead of a reused element in a layout.
Hence, I think changing the message would be beneficial.

@PySimpleGUI
Copy link
Owner

The ID isn't the important part of the error as much as the Text element itself being identified as the offensive element. If you printed your layout you would see the id and can match it up even if your element doesn't have a key.

Point taken on the console error message. It's been changed to match the popup, stressing an element is reused versus a layout.

@deajan
Copy link

deajan commented Jan 5, 2020

Sorry, I don't understand the sentence "If you printed your layout you would see the id and can match it up even if your element doesn't have a key."
Would you mind explain that part please ?

@PySimpleGUI
Copy link
Owner

The error message, the popup, tells you the type of the element, the specific element, and it also tells you that it will be stripped from your layout. You likely saw your window despite having the element removed.

Here's what I mean about printing. This code:

layout = [  [sg.Text('My Window')],
            [sg.Input(key='-IN-'), sg.Text(size=(12,1), key='-OUT-')],
            [sg.Button('Go'), sg.Button('Exit')]  ]

print(layout)

Produces this printout, which shows you the same info about the element as what is shown in the popup.

[[<PySimpleGUI.Text object at 0x000001F9F39D1710>], [<PySimpleGUI.InputText object at 0x000001F9F3758A20>, <PySimpleGUI.Text object at 0x000001F9F3758A58>], [<PySimpleGUI.Button object at 0x000001F9F3758A90>, <PySimpleGUI.Button object at 0x000001F9F377B128>]]

@deajan
Copy link

deajan commented Jan 5, 2020

Ohhh... I didn't understand the "If you printed your layout" in that way... Thanks, and sorry for the noise ;)

Even though it might sound very basic to you, maybe adding 'To find the address of the offending object, use print(layout)' text will help. I surely didn't think of doing so, and wondered why the hell you'd give a memory address of the offending element.

@PySimpleGUI
Copy link
Owner

Sure thing! Anything to help make it easier to figure out what's wrong. The idea of the error message / popup was to make it easier for someone to find this problem. Having it go undetected can cause some really ugly bugs to show up in your code.

@Prismacolor
Copy link

This is an interesting thread, I want to use this to make my own image in a display. I have begun playing around with it, but I think I've not done it quite right. I wondered, though is it possible for the user to interact with the image? For example if I found a way to display an image or preview of a file my customer dropped (a text file). I see above, someone created a Captcha using the tool. We'd essentially be wanting to spit back a mock up of a text file that the user could scroll through. Could the user then highlight part of that mockup and save it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants