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

inconsistent elements spacing between windows and linux #1654

Closed
Aboghazala opened this issue Jul 2, 2019 · 30 comments
Closed

inconsistent elements spacing between windows and linux #1654

Aboghazala opened this issue Jul 2, 2019 · 30 comments

Comments

@Aboghazala
Copy link

Aboghazala commented Jul 2, 2019

Type of Issues (Enhancement, Error, Bug, Question)
Enhancement

Operating System
Linux (manjaro-xfce-18.0.4-stable-x86_64),
Windows 10 64bit

Python version
3.7.3 64 bit on linux
3.6 32bit on windows

PySimpleGUI Port and Version
PySimpleGUI 3.39.0, tkinter

I am re-designing my application in PySimpleGUI "former design was wxpython", everything simple and make the design process a task for humans

just a small issue, my design looks as expected in linux "Manjaro" but not ok in windows, attached are 2 snapshots of my application running on both operating systems, the one on windows shows smaller space out and elements doesn't fit correctly in main window frame.

my suggestions is either:
add a size by pixel for every element, which you can see in my sample screenshots the progress bars sizes are the same on both systems because we use pixels instead of character size "i know it's not an easy task, too much mods"

or designing a new element "may inherits from sg.Text" but acts like an auto stretch spacer that can fill the remaining space of the row to match main window width, something like a spacer in wxpython.

for example:
layout = [[sg.spacer(ratio=2), sg.Text('Hello'), sg.spacer(ratio=1)]]
say we have main window size is 100 pixel and "hello" text size is 25 pixels, the remaining pixels are (100-25=75 pixels) should be divided according to the spacer ratios to:
--- 50 pixels --- "Hello" --- 25 pixels ---

Application snapshot on Linux "Manjaro" looks Ok as expected:
linux

Application snapshot on Windows10, spacing is not correct:
windows

my code:
i tried to include only the design and simplified the code as much as i could

import PySimpleGUI as sg

app_title = 'Hanash Download Manager'
themes = list(sg.LOOK_AND_FEEL_TABLE.keys())
sg.ChangeLookAndFeel('Green')
sg.SetOptions(font='any 11', auto_size_buttons=True, progress_meter_border_depth=0, border_width=1)


# gui design
def create_window():
    # main tab
    main_layout = [[sg.T('', size=(11, 1)), sg.Text('Hanash Download Manager', font='Any 20'),
                    sg.T(' ' * 16), sg.Button('info', key='about')],

                   # url
                   [sg.Text('URL:')],
                   [sg.Input('', enable_events=True, change_submits=True, key='url', size=(60, 1)),
                    sg.Button('Retry')],
                   [sg.Text('Status:', size=(70, 1), key='status')],

                   # spacer
                   [sg.T('', font='any 1')],

                   # youtube playlist
                   [sg.Frame('Youtube Playlist / videos:', layout=[
                       [sg.Combo(values=['Playlist'], size=(27, 1), key='pl_menu', enable_events=True),
                        sg.Button('v', disabled=True,
                                  tooltip='download this playlist', key='pl_download'),
                        sg.Combo(values=['Quality'], size=(27, 1), key='stream_menu', enable_events=True)],

                       # progress bars
                       [sg.ProgressBar(max_value=100, size=(24, 5), key='m_bar'), sg.T(' ' * 7, font='any 9'),
                        sg.ProgressBar(max_value=100, size=(24, 5), key='s_bar')],

                   ])],

                   # file info
                   [sg.Text('File name:'), sg.Input('', size=(58, 1), key='name', enable_events=True)],
                   [sg.T('File size:'), sg.T(' ' * 30, key='size'), sg.T('Type:'), sg.T(' ' * 35, key='type'),
                    sg.T('Resumable'), sg.T(' ' * 5, key='resumable')],
                   [sg.Text('Save To:'), sg.Input('Downloads', size=(51, 1), key='folder', enable_events=True),
                    sg.FolderBrowse(key='browse')],

                   # download button
                   [sg.T('', size=(25, 1), font='any 11'), sg.Button('Download', font='Any 14', border_width=1)],

                   ]

    # downloads tab
    d_headers = ['i', 'num', 'name', 'progress', 'speed', 'time_left', 'size', 'downloaded', 'status',
                 'resumable', 'folder', 'max_connections', 'live_connections', 'remaining_parts']

    spacing = [' ' * 4, ' ' * 3, ' ' * 30, ' ', ' ' * 8, ' ' * 8, ' ' * 8, ' ' * 8, ' ' * 10, ' ' * 12, ' ', ' ',
               ' ', ' ']  # setup initial column width

    downloads_layout = [[sg.Button('Resume'), sg.Button('Cancel'), sg.Button('Refresh'),
                         sg.Button('Folder'), sg.Button('D.Window'),
                         sg.T(' ' * 5), sg.T('Item:'),
                         sg.T('---', key='selected_row_num', text_color='white', background_color='red')],
                        [sg.Table(values=[spacing], headings=d_headers, size=(70, 13),
                                  vertical_scroll_only=False, key='table', enable_events=True)],
                        [sg.Button('Resume All'), sg.Button('Stop All'),
                         sg.Button('Delete', button_color=('white', 'red')),
                         sg.Button('Delete All', button_color=('white', 'red'))],
                        ]

    # setting tab
    setting_layout = [[sg.T('Setting:')],
                      [sg.Text('Select Theme:'),
                       sg.Combo(values=themes, default_value='Green', size=(15, 1), enable_events=True,
                                key='themes')],
                      [sg.T('Speed Limit:'), sg.Input('', size=(4, 1), key='speed_limit', enable_events=True),
                       sg.T('kb/s')],
                      [sg.Checkbox('Monitor copied urls in clipboard', default=True, key='monitor',enable_events=True)],
                      [sg.Checkbox("Don't show download window", key='hide_download_window',
                                   default=False, enable_events=True)],
                      [sg.Text('Max concurrent downloads:'),
                       sg.Combo(values=[x for x in range(1, 101)], size=(5, 1), enable_events=True,
                                key='max_concurrent_downloads', default_value=3)],
                      [sg.Text('Max connections per download:'),
                       sg.Combo(values=[x for x in range(1, 101)], size=(5, 1), enable_events=True,
                                key='max_connections', default_value=10)],
                      [sg.Text('file part size:'), sg.Input(default_text=1024, size=(6, 1), enable_events=True,
                                                            key='part_size'), sg.Text('KBytes')],
                      ]

    log_layout = [[sg.T('Details events:')], [sg.Multiline(default_text='', size=(70, 16), key='log')],
                  [sg.Button('Clear Log')]]

    layout = [[sg.TabGroup(
        [[sg.Tab('Main', main_layout), sg.Tab('Downloads', downloads_layout), sg.Tab('Setting', setting_layout),
          sg.Tab('Log', log_layout)]],
        key='tab_group')],
        [sg.StatusBar('', size=(75, 1), key='status_bar')]
    ]

    # window
    return sg.Window(title=app_title, layout=layout, size=(700, 450))

window = create_window()

while True:
    event, values = window.Read(timeout=50)

    if event is None:
        window.Close()
        break
    elif event == 'themes':
        sg.ChangeLookAndFeel(values['themes'])
        # restart window to apply new theme
        window.Close()
        window = create_window()
@MikeTheWatchGuy
Copy link
Collaborator

Very nice looking windows you've made!

It looks like the specific problem in the layout that goes too far to the right is the progress bars. They are pushing the right side of the Frame over and that in turn is making the window wider.

The root problem you're facing is the difference in sizes between Linux Characters and Windows Characters. Perhaps changing the progress bar will be all you need to line it all up again, at least to some extent.

The default sizing for PySimpleGUI (tkinter) is character based. In the other ports, like PySimpleGUIQt, this is remedied by a new parameter for the Element, size_px which specifies the size in pixels rather than characters. This parameter is not available in tkinter however.

You may want to start by changing your font to a specific set rather than Any. Helvetica is a good one generally speaking.

As far as spacers go, there is a Stretch Element that's available in Qt, but nothing like it is available in tkinter, at least not in the way that layouts are done in PySimpleGUI at the moment.

@MikeTheWatchGuy
Copy link
Collaborator

You can visibly see the difference in character sizes by looking at the heading alone. In the Linux screenshot, the characters take up 335 pixels. In the Windows version they span 310 pixels.

@Aboghazala
Copy link
Author

You may want to start by changing your font to a specific set rather than Any. Helvetica is a good one generally speaking.

Thanks a lot for your reply, your suggestion of using a specific font solved the problem for me, and now the window frame looks fine on both windows and linux

Very nice looking windows you've made!

a great thanks, this is encouraging :)

@MikeTheWatchGuy
Copy link
Collaborator

Can you post a couple of screenshots again showing it working correctly?

Glad you're finding this experience "encouraging". You've arrived at the project at a good time because the documentation is being updated extensively. All of the Elements have docstrings and I'm adding them into the readme in a more consistent manner.

It also means the readme will be up to date more often as it's getting easier and easier to generate a new readme. I'm hoping to be DONE with the primary Readme by end of the week.

You can also use the Python help function as well as your IDE's capabilities. PyCharm does some magical things with doc strings.

@Aboghazala
Copy link
Author

these are the new screenshots after using same font "Helvitica" and playing with sizes to adjust it again

i first adjust it on windows as below:
new_windows

and then view it on linux and it is almost ok except for status bar and info button at the top
new_linux

this is a modified code:

import PySimpleGUI as sg

app_title = 'Hanash Download Manager'
themes = list(sg.LOOK_AND_FEEL_TABLE.keys())
sg.ChangeLookAndFeel('Green')
sg.SetOptions(font='Helvetica 11', auto_size_buttons=True, progress_meter_border_depth=0, border_width=1)

# region gui design
def create_window():
    # main tab
    main_layout = [[sg.T('', size=(14, 1), font='Helvetica 11'), sg.Text('Hanash Download Manager', font='Helvetica 20'),
                        sg.T(' ', size=(8, 1)), sg.Button('info', key='about')],

                       # url
                       [sg.Text('URL:')],
                       [sg.Input('', enable_events=True, change_submits=True, key='url', size=(68, 1)),
                        sg.Button('Retry')],
                       [sg.Text('Status:', size=(70, 1), key='status')],

                   # spacer
                   [sg.T('', font='any 1')],

                   # youtube playlist
                   [sg.Frame('Youtube Playlist / videos:', layout=[
                       [sg.Combo(values=['Playlist'], size=(30, 1), key='pl_menu', enable_events=True),
                        sg.Button('v', tooltip='download this playlist', key='pl_download'),
                        sg.Combo(values=['Quality'], size=(30, 1), key='stream_menu', enable_events=True)],

                       # progress bars
                       [sg.ProgressBar(max_value=100, size=(24, 5), key='m_bar'), sg.T(' ' * 7, font='Helvetica 9'),
                        sg.ProgressBar(max_value=100, size=(24, 5), key='s_bar')],

                   ])],

                   # file info
                   [sg.Text('File name:'), sg.Input('', size=(65, 1), key='name', enable_events=True)],
                   [sg.T('File size:'), sg.T(' ' * 30, key='size'), sg.T('Type:'), sg.T(' ' * 35, key='type'),
                    sg.T('Resumable'), sg.T(' ' * 5, key='resumable')],
                   [sg.Text('Save To:'), sg.Input('Downloads', size=(57, 1), key='folder', enable_events=True),
                    sg.FolderBrowse(key='browse')],

                   # download button
                   [sg.T('', size=(27, 1), font='Helvetica 11'), sg.Button('Download', font='Helvetica 14', border_width=1)],

                   ]

    # downloads tab
    d_headers = ['i', 'num', 'name', 'progress', 'speed', 'time_left', 'size', 'downloaded', 'status',
                 'resumable', 'folder', 'max_connections', 'live_connections', 'remaining_parts']

    spacing = [' ' * 4, ' ' * 3, ' ' * 30, ' ', ' ' * 8, ' ' * 8, ' ' * 8, ' ' * 8, ' ' * 10, ' ' * 12, ' ', ' ',
               ' ', ' ']  # setup initial column width

    downloads_layout = [[sg.Button('Resume'), sg.Button('Cancel'), sg.Button('Refresh'),
                         sg.Button('Folder'), sg.Button('D.Window'),
                         sg.T(' ' * 5), sg.T('Item:'),
                         sg.T('---', key='selected_row_num', text_color='white', background_color='red')],
                        [sg.Table(values=[spacing], headings=d_headers, size=(70, 13),
                                  vertical_scroll_only=False, key='table', enable_events=True)],
                        [sg.Button('Resume All'), sg.Button('Stop All'),
                         sg.Button('Delete', button_color=('white', 'red')),
                         sg.Button('Delete All', button_color=('white', 'red'))],
                        ]

    # setting tab
    setting_layout = [[sg.T('Setting:')],
                      [sg.Text('Select Theme:'),
                       sg.Combo(values=themes, default_value='Green', size=(15, 1), enable_events=True,
                                key='themes')],
                      [sg.T('Speed Limit:'), sg.Input('', size=(4, 1), key='speed_limit', enable_events=True),
                       sg.T('kb/s')],
                      [sg.Checkbox('Monitor copied urls in clipboard', default=True, key='monitor',enable_events=True)],
                      [sg.Checkbox("Don't show download window", key='hide_download_window',
                                   default=False, enable_events=True)],
                      [sg.Text('Max concurrent downloads:'),
                       sg.Combo(values=[x for x in range(1, 101)], size=(5, 1), enable_events=True,
                                key='max_concurrent_downloads', default_value=3)],
                      [sg.Text('Max connections per download:'),
                       sg.Combo(values=[x for x in range(1, 101)], size=(5, 1), enable_events=True,
                                key='max_connections', default_value=10)],
                      [sg.Text('file part size:'), sg.Input(default_text=1024, size=(6, 1), enable_events=True,
                                                            key='part_size'), sg.Text('KBytes')],
                      ]

    log_layout = [[sg.T('Details events:')], [sg.Multiline(default_text='', size=(70, 16), key='log')],
                  [sg.Button('Clear Log')]]

    layout = [[sg.TabGroup(
        [[sg.Tab('Main', main_layout), sg.Tab('Downloads', downloads_layout), sg.Tab('Setting', setting_layout),
          sg.Tab('Log', log_layout)]],
        key='tab_group')],
        [sg.StatusBar('', size=(75, 1), key='status_bar')]
    ]

    # window
    return sg.Window(title=app_title, layout=layout, size=(700, 450))

window = create_window()

while True:
    event, values = window.Read(timeout=50)

    if event is None:
        window.Close()
        break
    elif event == 'themes':
        sg.ChangeLookAndFeel(values['themes'])
        # restart window to apply new theme
        window.Close()
        window = create_window()

@MikeTheWatchGuy
Copy link
Collaborator

I'm surprised you are not able to simply used a fixed width text field that you center the text within and then have your button right after that.

image

As it is, the Text Field is being "Autosized". I think it would work out a lot better to use a fixed size Text field.

I assume you've got a lot of stuff happening inside your event loop than what you've shown here. If not, then there's no reason to have a timeout value on your read which will save you boatloads of CPU time.

@Aboghazala
Copy link
Author

I'm surprised you are not able to simply used a fixed width text field that you center the text within and then have your button right after that.

i think there was no option for center the text "my bad", i just changed this row to:

[sg.Text('Hanash Download Manager', font='Helvetica 20', size=(37, 1), justification='center'),
                        sg.Button('', image_filename=r'icons/info025.png', size=(25, 25), key='about')]

it looks better with less code :)

I assume you've got a lot of stuff happening inside your event loop than what you've shown here. If not, then there's no reason to have a timeout value on your read which will save you boatloads of CPU time.

this application has a lot of threads running in background, it can download multiple files simultaneously with multi-connections / thread for each target file, and each download has its own gui window showing progress info, so sometimes i have 10 small windows running beside the main window,
also the info coming from all threads are collected by queues and showed on the main window in a table in the "downloads" tab

i have to admit, at first i didn't expect that PySimpleGUI design concept will work with a lot of concurrent windows but i am surprised how all theses windows are responsive with no lag with realtime data update.
i decided to continue using PySimpleGUI because i have more control on the gui, i run it inside my own loop and i don't have to run my application inside gui's loop, in other words now gui works for me not the other way around.
i hope you continue work in this module to make it better, it worth it.

@MikeTheWatchGuy
Copy link
Collaborator

Multiple windows are no problem at all as you see :-)

It baffles me, it truly does baffle me, as to why not one of the GUI vendors offers a secondary kind of interface to their objects.... one that looks like PySimpleGUI and is meant to fill this void. It's clear to me there's a void and it's sizable. Why can't tkinter at least do that? Make something that's usable by first week or first month Python students.

Unfortunately there are a few trolls that like to get the word out as to how "horrified" PySimpleGUI is and that it is only good for overly simplistic problems. The last one was it was great at doing 2 "Labels" in a window but nothing more than that.

This architecture has a lot to offer as you're learning. It's not difficult to write a multi-windowed application using PySimpleGUI. You just add more stuff to your event loop is all 😁

Sorry, I digress.....

@MikeTheWatchGuy
Copy link
Collaborator

And I do like your quote, or soon to be a quote, "now gui works for me not the other way around."

That's a great way of putting it. If I WANT to call a function when this button is clicked, I WILL, but maybe I just want to print a bit of text out instead. Or maybe I don't want to have to coordinate between 6 different functions that represent 6 different buttons that need to somehow communicate among themselves.

You're forced into an object model more because they create virtual global variables than because they do a fantastic job of representing something, which they don't. Right?

If you want these functions to share data, well, that data has to be either global data, which is a pain in the ass, or something else like them, which is what a class is. After all a class is a bunch of functions (methods) that access shared data (properties).

Contrast all that with a single interface through which EVERYTHING flows. How simple to deal with. If I want a class, well, great, I can create a class, but I'm not forced to and in fact, it often feels forced if you try to implement too much OO on top of PySimpleGUI. I do sometimes implement stuff as a class, like the debugger. It's more for making it into a single entity that I'm doing it that way. I'm not a big OO fan, clearly. It's because my roots go well before that OO thing happened.


I want to see more of your app as you develop it further!! It's a really advanced looking interface in my opinion. You're getting the most from it. I'm pleasantly surprised that the Linux and Windows versions weren't too far apart. Now if only the Qt and tkinter versions were closer.

Is this a general purpose downloader you're making??? I could see this thing being very popular. Unfortunately drag and drop doesn't work in tkinter, but it does in Qt in case you wanted to try that some day.

@Aboghazala
Copy link
Author

for me programming is a hobby, so you will find my code a lot of mess with a mix of functions and classes works together to get the job done whichever simpler and easier

Is this a general purpose downloader you're making??? I could see this thing being very popular.

yes, it downloads files from internet using pycurl a wrapper a round famous curl, and it can download youtube videos with all available qualities or download a youtube playlist at once
it is useful application especially if connection with the server dropped i can resume downloads later, plus i can bypass the speed throttling from some servers by increasing the connections number.

I want to see more of your app as you develop it further!! It's a really advanced looking interface in my opinion. You're getting the most from it. I'm pleasantly surprised that the Linux and Windows versions weren't too far apart.

Thanks a lot,
i will try to upload the code on github and send you the link, sorry i am new to github, hope it is not complicated to upload the files

@Aboghazala
Copy link
Author

Aboghazala commented Jul 3, 2019

uploading to github was just drag and drop,
here is the link, i will appreciate if you try this application and tell me your thoughts about it.

https://github.com/Aboghazala/Hanash

@MikeTheWatchGuy
Copy link
Collaborator

Lookin good!

A note on ChangeLookAndFeel....

It does not do anything to a window that already exists.

It does not do anything to a layout that already exists.

If you want a certain look and feel to be applied to a window, you need to set the Look and Feel prior to to the layout= statement or any call that includes an Element.

All it does is set a bunch of default values. That's it. Changes default values so that when you create something, like a button, it'll use the new default values to create that button or the background or an element.

@Aboghazala
Copy link
Author

A note on ChangeLookAndFeel....

yes i understand, i already restart the window creation once a new theme selected from combo box
here is an example

if event == 'themes':
    theme = values['themes']
    sg.ChangeLookAndFeel(theme)
    restart_window()  # a func to close window and recreate the layout and finalize() window

@MikeTheWatchGuy
Copy link
Collaborator

OK, just wanted to make sure you understood why there are generally at the very beginning of the program. You have to call them before defining your layout, creating a window, even calling a popup.

@Aboghazala
Copy link
Author

@MikeTheWatchGuy
Hello Mike, i think you might be interested, below is a snapshot of a running 11 concurrent windows as a show case, working flawlessly

concurrent_windows

some other snapshots of different design tabs of the application
2
3

@MikeTheWatchGuy
Copy link
Collaborator

DAMN!!!!!

These are AWESOME shots.

You did this stuff using straight PySimpleGUI calls? You didn't use tkinter directly?

Are you going to make this available publicly?

You did some really clever things, little tweaks, that had a big impact in the end. I like the progress meters and stats on one tab of a window. I'm not sure what's on the other.

You're the first person I've seen use the status bar element at the bottom of the window.

You've the first person I've seen offer the user the ability to change color schemes.

It's pretty amazing looking coming from a single program.

One thing I noticed was the lack of a MenuBar. It's what I was looking for to find the "main window" of the program. The MenuBar also lends credibly as you "look like" a "real" Windows program that way. I think it really helped the guy that built the chess game look like a Windows app:

image

After I told him about right-click menus, he went crazy and was able to get rid of a bunch of buttons and instead turn them into right clickable items.

Can you take a couple shots of just your download window and its two tabs (the one with main and log)?

When / if you do release it, I highly suggest packing your readme full of screenshots. They look fantastic.

I can't wait to get it and start using it!!

Oh, and you're the first person that I've seen look at doing bother Windows and Linux ports simultaneously.

@Aboghazala
Copy link
Author

wow! thanks a lot for your kind words

You did this stuff using straight PySimpleGUI calls? You didn't use tkinter directly?

yes the whole design is a pure PySimpleGUI, i never tried using tkinter before and i don't know how to use it, my previous designs made by wxpython and pyqt5.

You've the first person I've seen offer the user the ability to change color schemes.

really thanks to you you made it available, a ready made themes, which in my opinion one of the greatest things PySimpleGUI is offering.

regarding a menu bar and right click option i will try it

Can you take a couple shots of just your download window and its two tabs (the one with main and log)?

is this what you mean?

Capture

Capture2

When / if you do release it, I highly suggest packing your readme full of screenshots. They look fantastic.

i took your advice and put the screenshots in readme file, it do look better with screenshots :)
the source "just one file" and a windows executable "cx_Freeze build" at:
https://github.com/Aboghazala/Hanash

@JAK0723
Copy link

JAK0723 commented Jul 31, 2019

I ran into a similar issue, but the inconsistency is between two windows PCs and involves the slider.
Here is my desktop running the below code.

desktop
And here is my laptop.
laptop

While it may be difficult to compare with pixels due to resolution differences, the laptop slider is clearly shorter than the desktop slider.

On a somewhat related note, are there any monospaced fonts available for use in PySimpleGUI?

Operating System: Windows 10 64-bit
Python version: 3.7.3
PySimpleGUI Port and Version: Tk 4.0.0
Code:

import PySimpleGUI as pSG

pSG.SetOptions(font=("Helvetica", 10))
layout = [
    [pSG.Text("=" * 162)],
    [pSG.Slider(range=(0, 1000), default_value=0, size=(100, 15), orientation="h")]
]
window = pSG.Window("test", layout)
window.Finalize()

while True:
    event, values = window.Read()

@MikeTheWatchGuy
Copy link
Collaborator

Yes, Courier New is the obvious choice, but there are others. There is a font viewer demo application that will show you.

Or.....

Google tkinter font names

@JAK0723
Copy link

JAK0723 commented Aug 1, 2019

Thanks for letting me know. I never used tkinter before, so I'm pretty unfamilar with its features.

I just re-tested that code with the slider on my laptop, it's output is now identical to the output on my desktop. I don't think I changed anything, so I'm not sure why the output would have changed.

Also I'm not sure if this is intentional or not, but I just noticed that the font set with SetOptions doesn't appear to affect the text within a graph. Wouldn't it be more convenient for SetOption to apply to graph text as well?

import PySimpleGUI as pSG

pSG.SetOptions(font=("Courier New", 20))
size = 50
layout = [
    [pSG.Text("Testing")],
    [pSG.Graph((size, size), (0, 0), (size, size), key="graph")]
]
window = pSG.Window("test", layout)
window.Finalize().Element("graph").DrawText("testing", (25, 25))

while True:
    event, values = window.Read()

@MikeTheWatchGuy
Copy link
Collaborator

The reason they're not the same is that SetOptions sets options for the Elements and Windows. The Graph element uses a DrawText method/primitive that has a different font set (subset) of the fonts available for elements. That's my understanding at least.

@MikeTheWatchGuy
Copy link
Collaborator

You likely changed to using a fixed with font if they work together now. It would be great to get a screenshot.

@JAK0723
Copy link

JAK0723 commented Aug 2, 2019

OK, so I guess the best way to set fonts for both graphs and non-graph elements would be to do something like this?

myfont = ("Courier New", 20)
pSG.SetOptions(font=myfont)
...
graph.DrawText("testing", (25, 25), font=myfont)

@JAK0723
Copy link

JAK0723 commented Aug 2, 2019

Here's a screenshot of how it currently looks like on my laptop.
laptop

The code for this is the exact same I used for the previous laptop screenshot. Though I should note that I recently transitioned from installing packages to the system environment to using pipenv virtual environments. I actually checked the timestamp of the screenshot and it appears as though it was on the same day that I cleaned out the system packages and started using pipenv on my laptop. It's possible then when I took the screenshot my laptop was in a weird state due to the pipenv transition and rebooting it fixed it.

The only other stuff I think could have changed is stuff like updates to my OS (Windows 10), my IDE (PyCharm), or Python packages.

Also I just noticed while running that code on my laptop. Is the code supposed to stop executing when the window closes when it is run via the command line? I have to manually CTRL-C to get it to stop running, though this issue could be specific to pipenv.

@MikeTheWatchGuy
Copy link
Collaborator

As I said before, I'm not sure about the font lists being the same for both the DrawText and normal window. I suggest looking at the tkinter docs about this. The tkinter call is Canvas.create_text. Take a peek and see if the font lists to choose from are the same. I assume it's a much smaller subset for the creatre_text.

As I mentioned in the docs, I don't recommend virtual environments as well as running on the bleeding edge of everything (Python 3.7.latest, latest matplotlib, etc). Keep it simple. Run 3.6 unless you have a specific purpose for 3.7.

Do you close your window when you exit?

There are HUGE WARNINGS all over the docs, the cookbook and in every single demo program about "giving your user a way to exit your program".

If this is your event loop, how is it ever going to stop?

while True:
    event, values = window.Read()

Where does your program "exit".

READ THE DOCS, Follow the patterns. Don't skip by not wanting to type in code. There's a reason for pretty much everything. If you don't understand it, read the docs again. If after checking in all 3 places and still don't understand, then post here :-)

@JAK0723
Copy link

JAK0723 commented Aug 2, 2019

Sorry, I should give the documentation a more thorough read. Having everything on single page is a bit intimidating so I've only skimmed through it so far.

In regards to virtual environments, I only recently made the switch to using pipenv. Previously, I had used pip as though it were apt, installing everything to the system environment. If I needed a package I simply did pip install package. I was informed that this was frowned upon as doing so can lead to dependency conflicts. I then decided to learn about and follow the 'best practices' when it comes to python package management, everything I read recommended the use of virtual environments. I found that there was a lot of different virtual environment tools, as demonstrated here. I ended up picking pipenv as it seemed the easiest to use and is recommended by python-guide.org.

I can understand how you may discourage using the latest version of python. Though I'm unaware of the downsides to using virtual environments, besides the added complexity. In the documentation, I saw a line about how virtual environments can be quite confusing. Despite the complexity, isn't it worth learning about how to properly use virtual environments, provided that there is already a firm understanding on the basics of python?

@MikeTheWatchGuy
Copy link
Collaborator

One things at a time. There are people here that have 2 weeks experience. I'm having a difficult enough time helping with the most basic of problems. The latest Python doesn't show table colors. I don't know what else they broke. There's zero reason these beginners should be on the bleeding edge. Two or 3 of us spent several days debugging 3.7.4. If someone can tell me the 3.7 feature they need, then I'll endorse. So far, it's 0 for 20 when I ask the question. Speaking of which, if you're running 3.7, what feature are you using?

@JAK0723
Copy link

JAK0723 commented Aug 2, 2019

Right now I'm just using type hints, specifically forward-referenced annotations which are only able to be used in python 3.7, according to this. I like using type hints. I'm aware that I can use strings for type hints in earlier versions of python, but it feels weird to see quotation marks outside of literal strings within the body of my code.

@MikeTheWatchGuy
Copy link
Collaborator

OK, that's better, your 1 out of 21 has a use for 3.7.

I'll further explain in the docs that if you really know what you're doing, then sure, go nuts, but even then, stay off the absolutely latest and greatest.

I use type hints too, but because of the backwards compatibility I use the comments based type hints. They work extremely well with PySimpleGUI in particular. They're for my use, not the PySimpleGUI user's use. Enables code completion basically.

I also like them because I never forget the format:
# type: object

@MikeTheWatchGuy
Copy link
Collaborator

MikeTheWatchGuy commented Aug 2, 2019

Sorry, I should give the documentation a more thorough read. Having everything on single page is a bit intimidating so I've only skimmed through it so far.

You must use the documentation and demo programs to find the quickest answers or to find your answers period. You will NOT be successful guessing your way through this package and posting an issue when you run into each problem. Not saying you're doing that... it's a caution is all as some people do try this.

Use the version with a table of contents:

http://www.PySimpleGUI.org

Press Control+F and search. This is what I do. You are not going to get 1000's of hits back.

It's something to be embraced. Each element is not THAT much documentation.,

If the document is too much, then use the python help system as the doc strings are really close to finishing.

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

No branches or pull requests

3 participants