Skip to content

Commit 6035ed0

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents be43ef2 + df52c81 commit 6035ed0

File tree

1 file changed

+62
-63
lines changed

1 file changed

+62
-63
lines changed

README.md

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ as well as hosting projects like this, I have a lot to learn moving forward. Yo
2323
# Lets do this!
2424

2525
## Install
26-
NOTE: PySimpleSQL is not yet on PyPi, but will be soon!
26+
NOTE: I will try to keep current progress updated on Pypi so that pip installs the latest version.
27+
However, the single PySimpleSQL.py file can just as well be copied directly into the root folder of your own project.
2728
```
2829
pip install PySimpleGUI
2930
pip install pysimplesql
@@ -35,41 +36,45 @@ pip3 install pysimplesql
3536
### This Code
3637

3738
```python
38-
#!/usr/bin/python3
3939
import PySimpleGUI as sg
40-
import PySimpleSQL as ss # <=== PySimpleSQL lines will be marked like this. There's only a few!
40+
import PySimpleSQL as ss # <=== PySimpleSQL lines will be marked like this. There's only a few!
41+
import logging
42+
logger=logging.getLogger(__name__)
43+
logging.basicConfig(level=logging.DEBUG) # <=== You can set the logging level here (NOTSET,DEBUG,INFO,WARNING,ERROR,CRITICAL)
4144

42-
# Define our layout. We will use the PySimpleSQL.record() convenience function to create the controls
45+
# Define our layout. We will use the ss.record convenience function to create the controls
4346
layout = [
44-
ss.record('Restaurant', 'name'),
45-
ss.record('Restaurant', 'location'),
46-
ss.record('Restaurant', 'fkType', sg.Combo)]
47+
ss.record('Restaurant.name'),
48+
ss.record('Restaurant.location'),
49+
ss.record('Restaurant.fkType', sg.Combo, size=(30,10), auto_size_text=False)]
4750
sub_layout = [
48-
[sg.Listbox(values=(), size=(35, 10), key="SELECTOR.Item", select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,
49-
enable_events=True),
50-
sg.Col(
51-
[ss.record('Item', 'name'),
52-
ss.record('Item', 'fkMenu', sg.Combo),
53-
ss.record('Item', 'price'),
54-
ss.record('Item', 'description', sg.MLine, (30, 7))
55-
])],
56-
ss.record_actions('Item', False)
51+
ss.selector('selector1','Item',size=(35,10))+
52+
[sg.Col([ss.record('Item.name'),
53+
ss.record('Item.fkMenu', sg.Combo, size=(30,10), auto_size_text=False),
54+
ss.record('Item.price'),
55+
ss.record('Item.description', sg.MLine, (30, 7))
56+
])],
57+
ss.actions('actions1','Item', edit_protect=False,navigation=False,save=False, search=False)
5758
]
5859
layout += [[sg.Frame('Items', sub_layout)]]
59-
layout += [ss.actions('Restaurant')]
60+
layout += [ss.actions('actions2','Restaurant')]
6061

6162
# Initialize our window and database, then bind them together
6263
win = sg.Window('places to eat', layout, finalize=True)
63-
db = ss.Database(':memory:', 'example.sql', win) # <=== load the database and bind it to the window
64+
db = ss.Database(':memory:', win,sql_script='example.sql') # <=== load the database and bind it to the window
65+
# NOTE: ":memory:" is a special database URL for in-memory databases
6466

6567
while True:
6668
event, values = win.read()
67-
if db.process_events(event, values): # <=== let PySimpleSQL process its own events! Simple!
68-
print('PySimpleDB event handler handled the event!')
69+
70+
if db.process_events(event, values): # <=== let PySimpleSQL process its own events! Simple!
71+
logger.info('PySimpleDB event handler handled the event!')
6972
elif event == sg.WIN_CLOSED or event == 'Exit':
73+
db=None # <= ensures proper closing of the sqlite database and runs a database optimization at close
7074
break
7175
else:
72-
print(f'This event ({event}) is not yet handled.')
76+
logger.info(f'This event ({event}) is not yet handled.')
77+
7378
```
7479
along with this sqlite table
7580
```sql
@@ -136,7 +141,7 @@ INSERT INTO "Item" VALUES (9,"Dinner Pizza",3,3,"$16.99","Whatever we did not se
136141

137142
![image](https://user-images.githubusercontent.com/70232210/91227678-e8c73700-e6f4-11ea-83ee-4712e687bfb4.png)
138143

139-
Like PySimpleGUI™, pySimpleSQL supports subscript notation, so your code can access the data easily in the format of db['Table']['field'].
144+
Like PySimpleGUI™, pySimpleSQL supports subscript notation, so your code can access the data easily in the format of db['Table']['column'].
140145
In the example above, you could get the current item selection with the following code:
141146
```python
142147
selected_restaurant=db['Restaurant']['name']
@@ -147,15 +152,15 @@ or via the PySimpleGUI™ control elements with the following:
147152
selected_restaurant=win['Restaurant.name']
148153
selected_item=win['Item.name']
149154
```
150-
### Any Questions? It's that simple.
155+
### It really is that simple. All of the heavy lifting is done in the background!
151156

152157
To get the best possible experience with PySimpleSQL, the magic is in the schema of the database.
153158
The automatic functionality of PySimpleSQL relies on just a couple of things:
154-
- foreign key constraints on the database tables (lets PySimpleSQL know what the relationships are)
159+
- foreign key constraints on the database tables (lets PySimpleSQL know what the relationships are, though manual relationship mapping is also available)
155160
- a CASCADE ON UPDATE constraint on any tables that should automatically refresh child tables when parent tables are
156-
refreshed
161+
changed
157162
- PySimpleGUI™ control keys need to be named {table}.{field} for automatic mapping. Of course, manual mapping is
158-
supported as well. @Database.record() is a convenience function/"custom control" to make adding records quick and easy!
163+
supported as well. @Database.record() is a convenience function/"custom element" to make adding records quick and easy!
159164
- The field 'name', (or the 2nd column of the database in the absence of a 'name' column) is what will display in
160165
comboxes for foreign key relationships. Of course, this can be changed manually if needed, but truly the simplictiy of
161166
PySimpleSQL is in having everything happen automatically!
@@ -184,8 +189,8 @@ CREATE TABLE "Chapter"(
184189

185190
### But wait, there's more!
186191
The above is literally all you have to know for working with simple and even moderate databases. However, there is a
187-
lot of power in learning what is going on under the hood! Starting with the fully automatic example above, we will work
188-
backwards to explain what is available to you for more control at a lower level.
192+
lot of power in learning what is going on under the hood. Starting with the fully automatic example above, we will work
193+
backwards and unravel things to explain what is available to you for more control at a lower level.
189194

190195
#### PySimpleSQL elements:
191196
Referencing the example above, look at the following:
@@ -197,11 +202,11 @@ ss.record('Restaurant', 'name') # Table name, field name parameters
197202
[sg.Text('Name:',size=(15,1)),sg.Input('',key='Restaurant.name',size=(30,1))]
198203
```
199204
As you can see, the @Database.record() convenience function simplifies making record controls that adhere to the
200-
PySimpleSQL naming convention of Table.field. In fact, there is even more you can do with this. The @Database.record()
201-
function can take a PySimpleGUI™ control element as a parameter as well, overriding the defaul Input() element.
205+
PySimpleSQL naming convention of Table.column. In fact, there is even more you can do with this. The @Database.record()
206+
method can take a PySimpleGUI™ control element as a parameter as well, overriding the defaul Input() element.
202207
See this code which creates a combobox instead:
203208
```python
204-
ss.record('Restaurant', 'fkType', sg.Combo)]
209+
ss.record('Restaurant.fkType', sg.Combo)]
205210
```
206211
Furthering that, the functions @Database.set_text_size() and @Database.set_control_size() can be used before calls to
207212
@Database.record() to have custom sizing of the control elements. Even with these defaults set, the size parameter of
@@ -210,29 +215,28 @@ Furthering that, the functions @Database.set_text_size() and @Database.set_contr
210215
Place those two functions just above the layout definition shown in the example above and then run the code again
211216

212217
```python
213-
ss.set_text_size(10, 1) # Set the text/label size for all subsequent calls
214-
ss.set_control_size(50, 1) # set the control size for all subsequent calls
218+
# set the sizing for the Restaurant section
219+
ss.set_text_size(10, 1)
220+
ss.set_control_size(90, 1)
215221
layout = [
216-
ss.record('Restaurant', 'name'),
217-
ss.record('Restaurant', 'location'),
218-
ss.record('Restaurant', 'fkType', sg.Combo)]
222+
ss.record('Restaurant.name'),
223+
ss.record('Restaurant.location'),
224+
ss.record('Restaurant.fkType', sg.Combo, size=(30,10), auto_size_text=False)]
219225
sub_layout = [
220-
[sg.Listbox(values=(), size=(35, 10), key="SELECTOR.Item", select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,
221-
enable_events=True),
222-
sg.Col(
223-
[ss.record('Item', 'name'),
224-
ss.record('Item', 'fkMenu', sg.Combo),
225-
ss.record('Item', 'price'),
226-
ss.record('Item', 'description', sg.MLine, (30, 7)) # Override the default size for this element!
227-
])],
228-
ss.record_actions('Item', False)
226+
ss.selector('selector1','Item',size=(35,10))+
227+
[sg.Col([ss.record('Item.name'),
228+
ss.record('Item.fkMenu', sg.Combo, size=(30,10), auto_size_text=False),
229+
ss.record('Item.price'),
230+
ss.record('Item.description', sg.MLine, (30, 7)) # Override the default size for this element!
231+
])],
232+
ss.actions('actions1','Item', edit_protect=False,navigation=False,save=False, search=False)
229233
]
230234
layout += [[sg.Frame('Items', sub_layout)]]
231-
layout += [ss.actions('Restaurant', protect=True, search=True, save=True)]
235+
layout += [ss.actions('actions2','Restaurant')]
232236
```
233237
![image](https://user-images.githubusercontent.com/70232210/91287363-a71ea680-e75d-11ea-8b2f-d240c1ec2acf.png)
234238
You will see that now, the controls were resized using the new sizing rules. Notice however that the 'Description'
235-
field isn't as wide as the others. That is because we overridden the control size for just that single control.
239+
field isn't as wide as the others. That is because we overridden the control size for just that single control (see code above).
236240

237241
Lets see one more example. This time we will fix the oddly sized 'Description' field, as well as make the 'Restaurant'
238242
and 'Items' sections with their own sizing
@@ -242,25 +246,20 @@ and 'Items' sections with their own sizing
242246
ss.set_text_size(10, 1)
243247
ss.set_control_size(90, 1)
244248
layout = [
245-
ss.record('Restaurant', 'name'),
246-
ss.record('Restaurant', 'location'),
247-
ss.record('Restaurant', 'fkType', sg.Combo)]
248-
# set the sizing for the Items section
249-
ss.set_text_size(10, 1)
250-
ss.set_control_size(50, 1)
249+
ss.record('Restaurant.name'),
250+
ss.record('Restaurant.location'),
251+
ss.record('Restaurant.fkType', sg.Combo, size=(30,10), auto_size_text=False)]
251252
sub_layout = [
252-
[sg.Listbox(values=(), size=(35, 10), key="SELECTOR.Item", select_mode=sg.LISTBOX_SELECT_MODE_SINGLE,
253-
enable_events=True),
254-
sg.Col(
255-
[ss.record('Item', 'name'),
256-
ss.record('Item', 'fkMenu', sg.Combo),
257-
ss.record('Item', 'price'),
258-
ss.record('Item', 'description', sg.MLine, (50, 10)) # Override the default size for this element
259-
])],
260-
ss.record_actions('Item', False)
253+
ss.selector('selector1','Item',size=(35,10))+
254+
[sg.Col([ss.record('Item.name'),
255+
ss.record('Item.fkMenu', sg.Combo, size=(30,10), auto_size_text=False),
256+
ss.record('Item.price'),
257+
ss.record('Item.description', sg.MLine, (50,10)) # Override the default size for this element!
258+
])],
259+
ss.actions('actions1','Item', edit_protect=False,navigation=False,save=False, search=False)
261260
]
262261
layout += [[sg.Frame('Items', sub_layout)]]
263-
layout += [ss.actions('Restaurant', protect=True, search=True, save=True)]
262+
layout += [ss.actions('actions2','Restaurant')]
264263
```
265264
![image](https://user-images.githubusercontent.com/70232210/91288080-8e62c080-e75e-11ea-8438-86035d4d6609.png)
266265

0 commit comments

Comments
 (0)