PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.

Home Page:https://www.PySimpleGUI.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question – Datepicker vs Demo Calendar and button location in design

gk1701 opened this issue · comments

Question – Datepicker vs Demo Calendar and button location in design


Operating System

WIN10 64

PySimpleGUI Port (tkinter, Qt, Wx, Web)

PySimpleGUI


Versions

Python version: 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) [MSC v.1929 64 bit (AMD64)]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.57.0
PySimpleGUI filename: C:\Users\LDS\AppData\Local\Programs\Python\Python310\lib\site-packages\PySimpleGUI\PySimpleGUI.py

Python version (sg.sys.version)

PySimpleGUI Version (sg.__version__)

60

GUI Version (tkinter (sg.tclversion_detailed), PySide2, WxPython, Remi)


Your Experience In Months or Years (optional)

Years Python programming experience

Years Programming experience overall

Have used another Python GUI Framework? (tkinter, Qt, etc) (yes/no is fine)

Anything else you think would be helpful?


Troubleshooting

These items may solve your problem. Please check those you've done by changing - [ ] to - [X]

  • [ x] Searched main docs for your problem www.PySimpleGUI.org
  • [x ] Looked for Demo Programs that are similar to your goal Demos.PySimpleGUI.org
  • If not tkinter - looked for Demo Programs for specific port
  • For non tkinter - Looked at readme for your specific port if not PySimpleGUI (Qt, WX, Remi)
  • Run your program outside of your debugger (from a command line)
  • Searched through Issues (open and closed) to see if already reported Issues.PySimpleGUI.org
  • Tried using the PySimpleGUI.py file on GitHub. Your problem may have already been fixed but not released

Detailed Description

Hi,

As part of my first sqlite integration using pysimplesql I would like to pick the date as input for a field

the datepicker does not have a cancel button like the demo calendar. How would I need to change this line

[sg.In(key='-CAL-', enable_events=True, visible=True), sg.CalendarButton('Calendar', target='-CAL-', pad=None, font=('MS Sans Serif', 10, 'bold'),
button_color=('red', 'white'), key='CALENDAR', format=('%d/%m/%y'))],

to use the calendar instead? Furthermore I dont seem to be able to show the button to the right of the the input element and just for cosmetics could the depth of the button to be slightly adjusted to be the same height as the input?
Appreciate your time and help.

Code To Duplicate

A short program that isolates and demonstrates the problem (Do not paste your massive program, but instead 10-20 lines that clearly show the problem)

This pre-formatted code block is all set for you to paste in your bit of code:

#redesign layout

import logging
logging.basicConfig(filename='mlog.log', encoding='utf-8', level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')


import PySimpleGUI as sg
import pysimplesql as ss

# --------------------------
# CREATE OUR DATABASE SCHEMA
# --------------------------
# Note that databases can be created from files as well instead of just embedded commands, as well as existing databases.
sql="""
CREATE TABLE Journal(
    "id"            INTEGER NOT NULL PRIMARY KEY,
    "entry_date"    INTEGER DEFAULT (date('now')),
    "mood_id"       INTEGER,
    "title"         TEXT DEFAULT "New Entry",
    "entry"         TEXT,
    FOREIGN KEY (mood_id) REFERENCES Mood(id) --This line is important to the automatic functionality of pysimplesql~
);
CREATE TABLE Mood(
    "id"            INTEGER NOT NULL PRIMARY KEY,
    "name"          TEXT
);

-- Lets pre-populate some moods into our database
-- The list doesn't need to be overdone, as the user will be able to add their own too!
INSERT INTO Mood VALUES (1,"Happy");
INSERT INTO Mood VALUES (2,"Sad");
INSERT INTO Mood VALUES (3,"Angry");
INSERT INTO Mood VALUES (4,"Emotional");
INSERT INTO Mood VALUES (5,"Content");
INSERT INTO Mood VALUES (6,"Curious");
"""

# -------------------------
# CREATE PYSIMPLEGUI LAYOUT
# -------------------------
# Define the columns for the table selector
headings=['id','Date:              ','Mood:      ','Title:        ','Entry:                          '] # The width of the headings defines column width!
visible=[0,1,1,1,1] # Hide the id column

layout=[
    ss.selector('sel_journal','Journal',sg.Table,num_rows=10,headings=headings,visible_column_map=visible),
    ss.actions('act_journal','Journal', edit_protect=False), # These are your database controls (Previous, Next, Save, Insert, etc!)
    ss.record('Journal.entry_date')],[sg.In(key='-CAL-', enable_events=True, visible=False), sg.CalendarButton('Calendar', target='Journal.entry_date', pad=None, font=('MS Sans Serif', 10, 'bold'),
                button_color=('red', 'white'), key='_CALENDAR_', format=('%Y-%m-%d')),
    ss.record('Journal.mood_id', sg.Combo, label='My mood:', size=(30,10), auto_size_text=False),
    ss.record('Journal.title', size=(71)),
    ss.record('Journal.entry', size=(71)),  
    [sg.Button('Help',button_color='green'),sg.Button('Reports',button_color='blue'),sg.Button('Charts',button_color='grey'),sg.Button('Exit',button_color='red')]
]

win=sg.Window('Statistics for utiities', layout, finalize=True)
db=ss.Database('journalR.db', win, sql_commands=sql) #<=== ONE SIMPLE CHANGE!!!
# Now we just give the new databasase a name - "journal.db" in this case.  If journal.db is not present
# when this code is run, then a new one is created using the commands supplied to the sql_commands keyword argument.
# If journal.db does exist, then it is used and the sql_commands are not run at all.

# Reverse the default sort order so new journal entries appear at the top
db['Journal'].set_order_clause('ORDER BY entry_date DESC')
# Set the column order for search operations.  By default, only the column designated as the description column is searched
db['Journal'].set_search_order(['entry_date','title','entry'])



# ---------------
# DATA VALIDATION
# ---------------
def cb_validate():
    date=win['Journal.entry_date'].Get()
    if date[4] == '-' and date[7]=='-' and len(date)==10:   # Make sure the date is 10 digits and has two dashes in the right place
        if str.isdigit(date[:4]):                           # Make sure the first 4 digits represent a year
            if str.isdigit(date[5:7]):                      # Make sure the month are digits
                if str.isdigit(date[-2:]):                  # Make sure the days are digits
                    return True                             # If so, we can save!

    # Validation failed!  Deny saving of changes!
    sg.popup('Invalid date specified! Please try again')
    return False

#  Set the callback to run before save
db['Journal'].set_callback('before_save',cb_validate)

# ---------
# MAIN LOOP
# ---------

while True:
    event, values = win.read()
        
    if db.process_events(event, values):  # <=== let pysimplesql process its own events! Simple!
        print(f'PySimpleDB event handler handled the event {event}!')
    elif event == sg.WIN_CLOSED or event == 'Exit':
        active = False
        win.close()
        db=None              # <= ensures proper closing of the sqlite database and runs a database optimization at close
        break
    elif event == 'Help':
        sg.popup('works sometimes')
    elif event == 'Reports':
        sg.popup('Open reports window')
    elif event == 'Charts':
        sg.popup('Open Charts window')            
    else:
        print(f'This event ({event}) is not yet handled.')

Screenshot, Sketch, or Drawing


Screen Shot 05-18-22 at 10 17 AM

Watcha Makin?

If you care to share something about your project, it would be awesome to hear what you're building.

Refer Pre-Defined Buttons (use in your layout)

Set option close_when_date_chosen=False in CalendarButton

import PySimpleGUI as sg

options = {
    'font': ('MS Sans Serif', 10, 'bold'),
    'button_color': ('red', 'white'),
    'format': '%Y-%m-%d',
    'close_when_date_chosen': False,
}
layout = [
    [sg.Input(key='-CAL-', enable_events=True),
     sg.CalendarButton('Calendar', target='-CAL-', key='CALENDAR', **options)],
]
window = sg.Window('Title', layout, finalize=True)

while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED:
        break
window.close()

image

Thank you, thank you! Thats one solved, the main problem however still persists because the line

ss.record('Journal.entry_date')],[sg.In(key='-CAL-', enable_events=True, visible=False), sg.CalendarButton('Calendar', target='Journal.entry_date', pad=None, font=('MS Sans Serif', 10, 'bold'),
button_color=('red', 'white'), key='CALENDAR', format=('%Y-%m-%d')),

consists of three elements, the first two the label and the field being combined in the ss.record('Journal.entry_date') bit belonging to PySimpleSQL which runs some functions in the background like mapping the input to a database field,

Using the new code I now have this -

Screen Shot 05-18-22 at 08 40 PM

instead of this

Screen Shot 05-18-22 at 08 42 PM

Now I wonder if a workaround might be to place the invisible field and the button into a separate column right next to the input element or if that will cause more problems?

layout=[
    ss.selector('sel_journal','Journal',sg.Table,num_rows=10,headings=headings,visible_column_map=visible),
    ss.actions('act_journal','Journal', edit_protect=False), # These are your database controls (Previous, Next, Save, Insert, etc!)
    ss.record('Journal.entry_date')],[sg.In(key='-CAL-', enable_events=True, visible=False), sg.CalendarButton('Calendar', target='Journal.entry_date', pad=None, font=('MS Sans Serif', 10, 'bold'),
                button_color=('red', 'white'), key='_CALENDAR_', format=('%Y-%m-%d')),
    ss.record('Journal.mood_id', sg.Combo, label='My mood:', size=(30,10), auto_size_text=False),
    ss.record('Journal.title', size=(71)),
    ss.record('Journal.entry', size=(71)),  
    [sg.Button('Help',button_color='green'),sg.Button('Reports',button_color='blue'),sg.Button('Charts',button_color='grey'),sg.Button('Exit',button_color='red')]
]

image

Not sure what the layout you have now, but it looks you set wrong format for the layout in original post.

layout=[
    ss.selector('sel_journal','Journal',sg.Table,num_rows=10,headings=headings,visible_column_map=visible),
    ss.actions('act_journal','Journal', edit_protect=False), # These are your database controls (Previous, Next, Save, Insert, etc!)
    ss.record('Journal.entry_date'),
    [sg.In(key='-CAL-', enable_events=True, visible=False),
     sg.CalendarButton('Calendar', target='Journal.entry_date', pad=None, font=('MS Sans Serif', 10, 'bold'), button_color=('red', 'white'), key='_CALENDAR_', format=('%Y-%m-%d'))],
    ss.record('Journal.mood_id', sg.Combo, label='My mood:', size=(30,10), auto_size_text=False),
    ss.record('Journal.title', size=(71)),
    ss.record('Journal.entry', size=(71)),
    [sg.Button('Help',button_color='green'),
     sg.Button('Reports',button_color='blue'),
     sg.Button('Charts',button_color='grey'),
     sg.Button('Exit',button_color='red')]
]

image

Hello Jason, the layout was derived from a sample of PySimpleSQL. I simply changed the order of the bottom part and changed the Entry field from multiline to text.
The first screen capture above is my current design and all I need is the Calendar button to the right side of the Entry Date field.
I suspect that some code of PySimpleSQL somehow interferes with PySimpleGUY as mapping and events are no longer
handled by PSG

Hello Jason, the layout was derived from a sample of PySimpleSQL. I simply changed the order of the bottom part and changed the Entry field from multiline to text.

It looks the function call from PySimplesql, like ss.selector, that it return a list of elements. It still keep the format, List[List[Element]] | Tuple[Tuple[Element]].

layout = [
    ss.record('Restaurant.name'),
    ss.record('Restaurant.location'),
    ss.record('Restaurant.fkType', sg.Combo, size=(30,10), auto_size_text=False),
]

Reformat the layout In your code as following, layout is a 2-tuple of two lists, the first one is list of list of elements, and the second one is a list which with two elements and two lists of elements, it's not correct format.

layout= \
    [
        ss.selector('sel_journal','Journal',sg.Table,num_rows=10,headings=headings,visible_column_map=visible),
        ss.actions('act_journal','Journal', edit_protect=False), # These are your database controls (Previous, Next, Save, Insert, etc!)
        ss.record('Journal.entry_date')
    ],  \
    [
        sg.In(key='-CAL-', enable_events=True, visible=False),
        sg.CalendarButton('Calendar', target='Journal.entry_date', pad=None, font=('MS Sans Serif', 10, 'bold'),button_color=('red', 'white'), key='_CALENDAR_', format=('%Y-%m-%d')),
        ss.record('Journal.mood_id', sg.Combo, label='My mood:', size=(30,10), auto_size_text=False),
        ss.record('Journal.title', size=(71)),
        ss.record('Journal.entry', size=(71)),
        [
            sg.Button('Help',button_color='green'),
            sg.Button('Reports',button_color='blue'),
            sg.Button('Charts',button_color='grey'),
            sg.Button('Exit',button_color='red')
        ]
    ]

all I need is the Calendar button to the right side of the Entry Date field.

After you understand what format the layout should be, then following code will work for you.

layout=[
    ss.selector('sel_journal','Journal',sg.Table,num_rows=10,headings=headings,visible_column_map=visible),
    ss.actions('act_journal','Journal', edit_protect=False), # These are your database controls (Previous, Next, Save, Insert, etc!)
    ss.record('Journal.entry_date') + [
        sg.In(key='-CAL-', enable_events=True, visible=False),
        sg.CalendarButton('Calendar', target='Journal.entry_date', pad=None, font=('MS Sans Serif', 10, 'bold'), button_color=('red', 'white'), key='_CALENDAR_', format=('%Y-%m-%d'))],
    ss.record('Journal.mood_id', sg.Combo, label='My mood:', size=(30,10), auto_size_text=False),
    ss.record('Journal.title', size=(71)),
    ss.record('Journal.entry', size=(71)),
    [
        sg.Button('Help',button_color='green'),
        sg.Button('Reports',button_color='blue'),
        sg.Button('Charts',button_color='grey'),
        sg.Button('Exit',button_color='red')]
]

image

Perfecto! and yep I really got myself thoroughly confused with the bracketing and indents.
Thanks for your help.