When you execute and use a program written in Python, do you ever think that ** "It would be convenient if you could input and output with GUI ..." **?
Even if you distribute a program to someone, the CUI (command line input / output) is not very kind. CUI can also cause rejection, especially for people with low IT skills.
** If you can easily create a GUI with Python ... **
In that case, why not try using ** PySimpleGui **? PySimpleGui is characterized by ** anyone can easily implement GUI **, and according to PySimpleGui Official Document, PySimpleGui is easy to learn and can be learned quickly. The amount of code is about 1/2 to 1/10 of other GUI libraries (Tkinter, Qt, WxPython, etc.).
Seeing is believing, so first take a look at the code and execution results below.
import PySimpleGUI as sg
sg.theme('DarkAmber') #Design theme setting
#Components to place in the window
layout = [ [sg.Text('This is the first line')],
[sg.Text('This is the second line: Please enter characters appropriately'), sg.InputText()],
[sg.Button('OK'), sg.Button('Cancel')] ]
#Window generation
window = sg.Window('Sample program', layout)
#Event loop
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel':
break
elif event == 'OK':
print('Value you entered:', values[0])
window.close()
Execution result
It ’s easy, is n’t it?
The code consists of five main steps. The details of each step will be described later, so let's take a quick look at the overall flow.
PySimpleGui is not a standard library, so you need to install it first. Let's install it quickly with the pip command below.
pip install pysimplegui
Import the PySimple GUI. At this time, it is standard to give an alias of sg
, so this article will follow that convention.
import PySimpleGUI as sg
Set the GUI design with sg.theme ()
.
We have set the theme'Dark Amber'here, but there are 140 other design themes available.
sg.theme('DarkAmber')
This is the heart of the GUI, but we will set the parts (components) to be placed in the window and the layout.
layout = [ [sg.Text('This is the first line')],
[sg.Text('This is the second line: Please enter characters appropriately'), sg.InputText()],
[sg.Button('OK'), sg.Button('Cancel')] ]
How to arrange the components
layout = [ [First line component],
[Second line component],
[Component on line 3] ]
Set the parts you want to place in each line by separating them with commas. It's intuitive and easy to understand.
When arranging multiple parts in a line, separate them with commas as follows.
layout = [ [Component 1 on the first line,Component 2 on the first line],
[Component 1 on the second line],
[Component 1 on line 3,Component 2 on line 3,Component 3 on line 3,] ]
Create a window by specifying the layout created in step 3 in sg.Window ()
.
At this time, you can specify the window title as the first argument.
window = sg.Window('Sample program', layout)
Wait for the event to occur in the event loop.
Receive the event with window.read ()
. When the event is received, the action to be performed by the event is selected and executed.
In the sample code,
--The X button of the window was pressed (sg.WIN_CLOSED
) → exit the loop and close the window (window.close ()
)
--The'Cancel'button was pressed → Exit the loop and close the window (window.close ()
)
--The'OK'button was pressed → The value entered in the text box is displayed in the print statement.
Event processing is being executed.
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel':
break
elif event == 'OK':
print('Value you entered:', values[0])
window.close()
Let's explain while actually making things.
The code introduced in the article "[Automation] Extract tables in PDF with Python" was slightly modified, and ** "Specified page of PDF file" Let's create a program that extracts the table inside and converts it to csv "** with GUI.
The part that extracts the table in the specified page of the PDF file with DataFrame is made into a function. This time it is not important, so I will omit the explanation. For details, see "[Automation] Extracting tables in PDF with Python".
import pandas as pd
import tabula
def readTableFromPDF(filePath, isLattice, targetPages):
'''
Reads a table from a PDF file with the specified filePath and converts it to DataFramle
'''
dfs = tabula.read_pdf(filePath, lattice=isLattice, pages=targetPages)
#Display the converted DataFrame
for index, df in enumerate(dfs):
print("----------table"+str(index+1)+"----------")
print(df.head())
return dfs
First, decide what kind of GUI you want to design. It can be paper or electronic, so I'll write the design.
I thought of such a GUI.
Import the PySimple GUI with the name sg
.
import PySimpleGUI as sg
Set the GUI design theme with sg.theme ()
.
There are various themes available, but you can see the theme list by calling the function sg.theme_previewer ()
.
sg.theme_previewer() #View a list of design themes
Please also refer to the official website when choosing. Look and Feel Theme Explosion
Here, I will make it with the theme of Dark Teal7.
sg.theme('DarkTeal7')
Consider a GUI design proposal line by line.
There are 6 lines in total, so the code looks like this:
layout = [ [First line component],
[Second line component],
[Component on line 3],
[Component on line 4],
[Component on line 5],
[Component on line 6] ]
Let's look at each line in turn.
The first line just displays the text.
Place the text as sg.Text ("text you want to display ")
.
[sg.Text('Please specify the file and page to read')]
The second line places the three components.
■ First component (text)
The text is the same as the first line and is placed with sg.Text ()
.
Depending on the layout, you may want to specify the size of the component.
In that case, specify it in the form of sg.Text ('text you want to display', size = (" width "," height "))
.
■ Second and third components (file browser button)
A button for selecting a file in the browser. Place it with sg.FileBrowse ('text you want to display on the button')
.
The path of the selected file is displayed in the box placed by sg.Input ()
.
Each component can be given a name to identify that ** component in the form key ='name'
. ** **
When an event such as "button pressed" occurs, you need to identify which button was pressed.
Be sure to give the component you want to handle the event a name, as you will need it at that time.
You'll need to get the file path later, so give it a name for sg.FileBrowse ()
.
[sg.Text('File', size=(15, 1)), sg.Input(), sg.FileBrowse('Fileを選択', key='inputFilePath')]
The third line also places three components.
■ First component (text)
Place it with sg.Text ()
.
■ Second component (text box)
The box for entering text is sg.InputText ()
.
Give this component a name as well.
■ Third component (text)
Place it with sg.Text ()
.
Since the number of characters is a little large, specify 2 for "vertical width" of `size = ("width", "vertical width")) to display it as two lines of text.
sg.Text ('Specify as \ n3-10 for multiple pages', size = (30, 2))
[sg.Text('page', size=(15, 1)), sg.InputText('', size=(10, 1), key='pages'), sg.Text('複数pageのときは\n3-Please specify as 10', size=(30, 2))]
The fourth line places the two components.
■ First component (text)
Place it with sg.Text ()
.
■ Second component (pull-down menu)
The pull-down menu is sg.Combo (("value 1 "," value 2 ", ...), default_value =" value n ")
.
Give this component a name as well.
[sg.Text('Table border', size=(15, 1)),sg.Combo(('Yes', 'None'), default_value="Yes",size=(10, 1), key='lattice')]
The fifth line places the two components.
■ First and second components (buttons)
Place the button with sg.Button ('text you want to display on the button')
.
I want to handle the event when the button is pressed, so I also name them with key ='name'
.
[sg.Button('reading', key='read'), sg.Button('Save to csv', key='save')]
There is only one component in this line. The table read from the PDF file is output here for confirmation.
Use sg.Output (size = ("width "," height "))
to output the text.
[sg.Output(size=(80,20))]
Write the components from lines 1 to 6 together.
layout = [
[sg.Text('Please specify the file and page to read')],
[sg.Text('File', size=(10, 1)), sg.Input(), sg.FileBrowse('Fileを選択', key='inputFilePath')],
[sg.Text('page', size=(10, 1)), sg.InputText('', size=(10, 1), key='pages'), sg.Text('複数pageのときは\n3-Please specify as 10', size=(30, 2))],
[sg.Text('Table border', size=(10, 1)),sg.Combo(('Yes', 'None'), default_value="Yes",size=(10, 1), key='lattice')],
[sg.Button('reading', key='read'), sg.Button('Save to csv', key='save')],
[sg.Output(size=(80,20))]
]
Create a window with the layout created in step 3. The title of the window should be "Tool for extracting PDF table".
window = sg.Window('Tool to extract PDF table', layout)
This is the last step. This is also a very important step.
Wait for the event to occur in the event loop.
Receive the event with window.read ()
. When the event is received, the action to be performed by the event is selected and executed.
while True:
event, values = window.read()
if event == sg.WIN_CLOSED: #What happens when you press the X button on the window
break
if event == 'Event name 1':
#Processing when event name 1 occurs
if event == 'Event name 2':
#Processing when event name 2 occurs
window.close()
The return value of window.read (), event, contains the name given to each component with key ='name'
.
For example, the "read" button is named'read', so if this button is pressed, the event will have the name'read'.
values contains the values that each component has, which can also be retrieved by specifying the name given to each component with key ='name'
.
For example, the value of the pull-down menu ('Yes' or'No') on the 4th line can be obtained with values ['lattice'].
There are two types of event handling this time.
Event | Event名 | What to do |
---|---|---|
The "read" button was pressed | 'read' | readTableFromPDF()To run |
"Save to csv" button was pressed | 'save' | readTableFromPDF()And save the DataFrame obtained as the return value as csv |
while True:
event, values = window.read()
if event == sg.WIN_CLOSED: #What happens when you press the X button on the window
break
if event == 'read': #What to do when the "read" button is pressed
if values['lattice'] == 'Yes':
isLattice = True
else:
isLattice = False
readTableFromPDF(values['inputFilePath'], isLattice, values['pages'])
if event == 'save': #Processing when the "Save to csv" button is pressed
if values['lattice'] == 'Yes':
isLattice = True
else:
isLattice = False
dfs = readTableFromPDF(values['inputFilePath'], isLattice, values['pages'])
for index, df in enumerate(dfs):
basename_without_ext = os.path.splitext(os.path.basename(values['inputFilePath']))[0] #Extract PDF file name
filename = basename_without_ext + "_" + str(index+1) +".csv"
df.to_csv(filename, index=None)
print("Saved to csv file:", filename)
print("All csv files have been saved")
window.close()
The result of the print statement here is displayed in the box of sg.Output ()
which is the component on the 6th line.
Put together all the code from steps 1-5.
#step 1.import
import PySimpleGUI as sg
import os
#Step 2.Design theme setting
sg.theme('DarkTeal7')
#Step 3.Window parts and layout
layout = [
[sg.Text('Please specify the file and page to read')],
[sg.Text('File', size=(10, 1)), sg.Input(), sg.FileBrowse('Fileを選択', key='inputFilePath')],
[sg.Text('page', size=(10, 1)), sg.InputText('', size=(10, 1), key='pages'), sg.Text('複数pageのときは\n3-Please specify as 10', size=(30, 2))],
[sg.Text('Table border', size=(10, 1)),sg.Combo(('Yes', 'None'), default_value="Yes",size=(10, 1), key='lattice')],
[sg.Button('reading', key='read'), sg.Button('Save to csv', key='save')],
[sg.Output(size=(80,20))]
]
#Step 4.Window generation
window = sg.Window('Tool to extract PDF table', layout)
#Step 5.Event loop
while True:
event, values = window.read()
if event == sg.WIN_CLOSED: #What happens when you press the X button on the window
break
if event == 'read': #What to do when the "read" button is pressed
if values['lattice'] == 'Yes':
isLattice = True
else:
isLattice = False
readTableFromPDF(values['inputFilePath'], isLattice, values['pages'])
if event == 'save': #Processing when the "Save to csv" button is pressed
if values['lattice'] == 'Yes':
isLattice = True
else:
isLattice = False
dfs = readTableFromPDF(values['inputFilePath'], isLattice, values['pages'])
for index, df in enumerate(dfs):
basename_without_ext = os.path.splitext(os.path.basename(values['inputFilePath']))[0] #Extract PDF file name
filename = basename_without_ext + "_" + str(index+1) +".csv"
df.to_csv(filename, index=None)
print("Saved to csv file:", filename)
print("All csv files have been saved")
window.close()
When you execute the above code, the following GUI will be displayed. It's almost as designed.
Specify the PDF file and page, and try "reading".
You can read the pages in the PDF file properly!
As the name suggests, PySimpleGui allows you to write GUIs simply, so I was able to ** enjoy creating GUIs. The components introduced here are very basic, but you can easily create various other components. Unfortunately, there are few Japanese documents for PySimpleGui, but I hope you will enjoy creating a GUI while referring to the following site.
PySimpleGui Official This is the official website of PySimpleGui.
Basic usage of PySimple GUI I think the text linked in the article is currently one of the few PySimple Gui Japanese texts. I also used it as a reference.