I'm trying to create the below piece of code for video and subtitle sync.
I need the first window to get the videos and the second window to get the subtitles upon drag and drop.
However as per the code now whenever i drag and drop onto one of the "windows/boxes" it shows in the other one as if they are functioning as one box even though i have separate key for them.
appreciate your guidance on how to separate them.
thank you
import PySimpleGUIQt as sg
class Listbox(sg.Listbox):
def dragEnterEvent(self, e):
e.accept()
def dragMoveEvent(self, e):
e.accept()
def dropEvent(self, e):
data1 = window['-VIDEOLIST-'].get_list_values()
data2 = window['-SUBTITLESLIST-'].get_list_values()
items = [str(v) for v in e.mimeData().text().strip().split('\n')]
print(items)
data1.extend(items)
data2.extend(items)
window['-VIDEOLIST-'].update(data1)
window['-SUBTITLESLIST-'].update(data2)
window.refresh()
def enable_drop(self):
# Called after window finalized
self.Widget.setAcceptDrops(True)
self.Widget.dragEnterEvent = self.dragEnterEvent
self.Widget.dragMoveEvent = self.dragMoveEvent
self.Widget.dropEvent = self.dropEvent
layout = [
[sg.Text("Choose a Video: "), sg.Input(), sg.FileBrowse(key="-VID-"),sg.Text("Choose a Subtitle: "), sg.Input(), sg.FileBrowse(key="-SUB-")],
[Listbox([], size=(50, 10), enable_events=True, key='-VIDEOLIST-'),Listbox([], size=(50, 10), enable_events=True, key='-SUBTITLESLIST-')],
[sg.Button('Auto Sync', key='-AutoSync-')]
]
window = sg.Window("Title", layout, finalize=True)
window['-VIDEOLIST-'].enable_drop()
window['-SUBTITLESLIST-'].enable_drop()
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
window.close()
Related
I am trying to get the content in the listbox able to be dragged into the workspace as a block. Like scratch. I used OpenAi to give me ideas of how to do it, and it gave me that there is a draggable option I can put into the code as you can see, but when I try to drag the items in the listbox it wont let me.
import PySimpleGUI as sg
from PIL import ImageGrab
# Create a list of Python code to display in the scroller
code_lines = [
"variable",
"loops",
"types of variables"
]
# Create the window layout
layout = [ [sg.Column([[sg.Listbox(values=code_lines, size=(20, 10), key='Python Code', draggable = True)]]),
sg.Column([[sg.Text('Workspace:', size=(20, 1)), sg.Multiline(size=(50, 30), key='workspace', background_color='dark gray')]])],
[sg.Button('Close')] ]
# Create the window
window = sg.Window('PyDrop', layout)
# Event loop to process events
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Close': # if user closes window or clicks close button
break
elif event == 'Python Code': # if user clicks on an item in the listbox
# stores the value of the clicked item in a variable
dragged_item = values['Python Code'][0]
elif event == sg.DRAG: # if user moves the mouse while holding down the button
# updates the value of the drop target
print('Drag event triggered')
window['drop_target'].update(dragged_item)
# Close the window
window.close()
Good day, I'm trying to create a simple GUI in python using the module "PySimpleGUI", I would like the GUI to monitor the clipboard and add the text string into a listbox, any help is much appreciated, I add the minimal example, please advise if its possible to use this clipboard listener function [Clipboard listener in python using win32apiClipboard listener in python using win32api
Code:
import PySimpleGUI as sg
sg.theme('SystemDefaultForReal')
listcontents = ['Roberta', 'Kylie']
inputtext = sg.Text('Listbox with search')
inputfield = sg.Input(default_text='', enable_events=True, size=(80, 1), key='-INPUT-')
col2 = [
[sg.Multiline(default_text="", size=(500, 19), key='MULTILINEAREA')],
]
mylistbox = sg.Listbox(values=listcontents, select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, enable_events=True, key='-LISTBOXNAME-', size=(80,18)), sg.Column(col2)
layout1 = [
[ sg.VPush() ],
[sg.Push(), inputfield, sg.Push() ],
[ mylistbox ],
]
window = sg.Window('Window Title', layout1,size=(1200, 400), resizable=True, relative_location = (0, 250))
# Event Loop # taken from the module's documentation example
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'): # always check for closed window
break
if values['-INPUT-'] != '': # if a keystroke entered in search field
search = values['-INPUT-']
new_values = [x for x in listcontents if search in x] # do the filtering
window['-LISTBOXNAME-'].update(new_values) # display in the listbox
else:
# display original unfiltered list
window['-LISTBOXNAME-'].update(listcontents)
# if a list item is chosen
if event == '-LISTBOXNAME-' and len(values['-LISTBOXNAME-']):
# sg.popup('Selected ', values['-LISTBOXNAME-']) # shows dialog showing selected item
print(values['-LISTBOXNAME-'])
#pass
window.close()
I've been working on an application for blind people, so I decided to python and wxPython for the GUI. The problem is that I cannot navigate the wx.toolbar using tabs. This is my actual code.
menuToolBar = self.CreateToolBar(style=wx.TB_FLAT)
menuToolBar.AddSeparator()
menuToolBar.AddTool(ID_NUEVO, "Nuevo Archivo", wx.Bitmap(
os.path.join(self.__rutaPrincipal, "img/nueva pagina.png")), "Nuevo Archivo")
menuToolBar.AddSeparator()
menuToolBar.AddTool(ID_GUARDAR_ARCHIVO, "Guardar Archivo", wx.Bitmap(
os.path.join(self.__rutaPrincipal, "img/guardar pagina.png")), "Guardar Archivo")
menuToolBar.AddTool(ID_ABRIR_ARCHIVO, "Abrir Página", wx.Bitmap(
os.path.join(self.__rutaPrincipal, "img/abrir pagina.png")), "Abrir Página")
menuToolBar.AddSeparator()
menuToolBar.AddTool(ID_FOCUS_PANEL_ESCRITURA, "Foco Escritura", wx.Bitmap(
os.path.join(self.__rutaPrincipal, "img/panel escritura.png")), "Foco Escritura")
menuToolBar.AddTool(ID_FOCUS_PANEL_RESULTADO, "Foco Resultado", wx.Bitmap(
os.path.join(self.__rutaPrincipal, "img/panel resultado.png")), "Foco Resultado")
menuToolBar.AddSeparator()
menuToolBar.AddTool(ID_CERRAR_PAGINA, "Cerrar Página", wx.Bitmap(
os.path.join(self.__rutaPrincipal, "img/cerrar pagina.png")), "Cerrar Página")
menuToolBar.AddSeparator()
menuToolBar.Realize()
is there any configuration to achieve it? or maybe is there another component that help me?.
P.D. I am new to python development and Stackoverflow
Rather than delete the existing anwser, which in fact answers a different question, I'm leaving it in place because I personally believe it's useful, in a related way.
Here is an example of what I was referring to in my comment, about making your own toolbar, which you can navigate using Tab, Left and Right Arrow keys.
It should be enough to get you started.
It uses a normal button and some Generic bitmap buttons, both will work, as we need to illustrate which button currently has focus, which is achieved by using at least 2 different bitmaps for each button. One Normal and one for Focus.
import wx
import wx.lib.buttons as buttons
Valid_keys = [wx.WXK_F1,wx.WXK_RETURN,wx.WXK_TAB,wx.WXK_LEFT,wx.WXK_RIGHT]
class MainFrame(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
self.funcs={"Button1":self.OnButton1,
"Button2":self.OnButton2,
"Button3":self.OnButton3,
"Button4":self.OnButton4}
wx.Frame.__init__(self, None, title="Self defined Toolbar", size=(400,400))
tool_panel = wx.Panel(self,-1,name="tool_panel")
tool_panel.SetBackgroundColour("lightgreen")
tool_panel.SetToolTip("Press F1 or Tab to Access Toolbar")
panel = wx.Panel(self,-1,size=(400,300), name="Main_panel")
panel.SetBackgroundColour("lightblue")
bmp = wx.Bitmap("Discord.png", wx.BITMAP_TYPE_ANY)
bmp1 = wx.Bitmap("Discord1.png", wx.BITMAP_TYPE_ANY)
bmp2 = wx.Bitmap("Discord2.png", wx.BITMAP_TYPE_ANY)
self.Button1 = buttons.GenBitmapButton(tool_panel,bitmap=bmp,size=(40,40),name="Button1")
self.Button2 = buttons.GenBitmapButton(tool_panel,bitmap=bmp,size=(40,40),name="Button2")
self.Button3 = buttons.GenBitmapButton(tool_panel,bitmap=bmp,size=(40,40),name="Button3")
self.Button4 = wx.Button(tool_panel,-1, label="",size=(40,40),name="Button4")
self.Button4.SetBitmap(wx.Bitmap('test.png'))
self.Button4.SetBitmapFocus(wx.Bitmap('testfocus.png'))
self.Text = wx.TextCtrl(panel, -1, size=(400,300), style=wx.TE_MULTILINE)
self.Button1.SetToolTip("Function1")
self.Button2.SetToolTip("Function2")
self.Button3.SetToolTip("Function3")
self.Button4.SetToolTip("Function4")
self.BitmapButtons = [self.Button1,self.Button2,self.Button3]
for i in range(0,len(self.BitmapButtons)):
self.BitmapButtons[i].SetBitmapLabel(bmp)
self.BitmapButtons[i].SetBitmapFocus(bmp2)
self.BitmapButtons[i].SetBitmapSelected(bmp1)
self.Bind(wx.EVT_BUTTON, self.OnButton)
self.Bind(wx.EVT_CHAR_HOOK, self.OnKey)
tool_sizer=wx.BoxSizer(wx.HORIZONTAL)
main_sizer=wx.BoxSizer(wx.VERTICAL)
tool_sizer.Add(self.Button1)
tool_sizer.Add(self.Button2)
tool_sizer.Add(self.Button3)
tool_sizer.Add(self.Button4)
tool_panel.SetSizer(tool_sizer)
main_sizer.Add(tool_panel,0,wx.EXPAND)
main_sizer.Add(panel,0,wx.EXPAND,0)
self.SetSizer(main_sizer)
self.Text.SetFocus()
self.Show()
def OnButton(self, event):
Id = event.GetId()
btn = event.GetEventObject()
x = self.funcs[btn.GetName()]
x()
self.Text.SetFocus()
def OnButton1(self):
print("Button 1")
def OnButton2(self):
print("Button 2")
def OnButton3(self):
print("Button 3")
def OnButton4(self):
print("Button 4")
def OnKey(self, event):
key = event.GetKeyCode()
if key not in Valid_keys: #Ignore all keys except F1, Enter and Navigation keys
event.Skip()
return
if key not in [wx.WXK_F1,wx.WXK_RETURN]:
event.Skip()
return
if key == wx.WXK_F1: #F1 focuses on the First Toolbar button
self.Button1.SetFocus()
return
i = self.get_focus()
if i == 1:
id="Button1"
elif i == 2:
id="Button2"
elif i == 3:
id="Button3"
elif i == 4:
id="Button4"
if i > 0: #Focus was a toolbar button, execute button function
x = self.funcs[id]
x()
self.Text.SetFocus()
event.Skip()
def get_focus(self):
focused = wx.Window.FindFocus()
if focused == self.Button1:
return 1
elif focused == self.Button2:
return 2
elif focused == self.Button3:
return 3
elif focused == self.Button4:
return 4
else:#Something other than the toolbar buttons has focus return Fail
return -1
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App()
frame = MainFrame()
app.MainLoop()
You need to implement Accelerators in your MenuBar and possibly your MenuItem's.
An accelerator table allows the application to specify a table of keyboard shortcuts for menu or button commands.
Often, these are set up using the text in the menu item, by-passing the wx.AcceleratorTable.
p1 = wx.MenuItem(playm, wx.NewIdRef(), '&Play\tCtrl+P')
Here the &Play sets P to be the Menu accelerator, and Ctrl+P to be the hotkey for the function represented by the menu item.
Put another way, when navigating the menus, pressing P will select the Play menu item. When not navigating the menus, just pressing Ctrl+P will run that function.
N.B.
You do not have to setup both.
Do not place the & ampersand character before the same letter more than once in a single menu or the menubar, as only the first one will function.
e.g. "&Save" and "Sa&ve as" would work, using S for "Save" and V for "Save as"
To access the Menu shortcuts Press the Alt button and then any of the underlined letters.
Some minimal code with Menu accelerators but no assigned hotkeys:
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(200, 100))
self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE)
# A Statusbar in the bottom of the window
self.CreateStatusBar()
# Setting up the menus
'''Define main items'''
filemenu = wx.Menu()
editmenu = wx.Menu()
infomenu = wx.Menu()
'''Items'''
# file menu
menu_open = filemenu.Append(wx.ID_OPEN, "Open")
filemenu.Append(wx.ID_NEW, "New")
filemenu.Append(wx.ID_SAVE, "Save")
filemenu.Append(wx.ID_SAVEAS, "Save as")
filemenu.Append(wx.ID_EXIT, '&Quit', 'Quit application')
filemenu.AppendSeparator()
filemenu.Append(wx.ID_PRINT, "&Print")
filemenu.Append(wx.ID_PRINT_SETUP, "Print setup")
filemenu.Append(wx.ID_PREVIEW, "Preview")
# edit menu
editmenu.Append(wx.ID_COPY, "Copy")
editmenu.Append(wx.ID_CUT, "Cut")
editmenu.Append(wx.ID_PASTE, "Paste")
editmenu.AppendSeparator()
editmenu.Append(wx.ID_UNDO, "Undo")
editmenu.Append(wx.ID_REDO, "Re-do it")
# info menu
infomenu.Append(wx.ID_ABOUT, "About")
'''Bind items for activation'''
# bind file menu
self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
self.Bind(wx.EVT_MENU, self.OnOpen)
# Creating the menubar.
menuBar = wx.MenuBar()
# Add menus
menuBar.Append(filemenu, "&File")
menuBar.Append(editmenu, "&Edit")
menuBar.Append(infomenu, "&Help")
# Adding the MenuBar to the Frame content.
self.SetMenuBar(menuBar)
self.Show(True)
def OnOpen(self, event):
print ("Menu item selected")
# event skip as we want to continue checking events in case Quit was chosen
event.Skip()
def OnExit(self, event):
self.Destroy()
app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()
Run this code and Press the Alt key, press one of the undelined letters F, E or H and navigate the menus using the arrow keys or any underlined letters.
N.B. Certain functions are automatically assigned Hotkeys e.g. Ctrl+Q is Quit.
I'm currently trying to create a custom button in python using PySimpleGUI that allows me to browse for files. I am able to do this successfully for a button that submits my entries and one that cancels the process, but am unable to figure out how to do so without having to use sg.FilesBrowse(), which doesn't allow me to customize the button.
I have the current code for my window.
#select theme for GUI
sg.theme('Light Blue 2')
#create custom buttons
submit_button = sg.Button('', image_data=submit_base64,button_color=(sg.theme_background_color(),sg.theme_background_color()),border_width=0, key='Sumbit')
cancel_button = sg.Button('', image_data=cancel_base64,button_color=(sg.theme_background_color(),sg.theme_background_color()),border_width=0, key='Cancel')
#create GUI layout
layout = [[sg.Text('Please select the following files:', font = ('bold', 14))],
[sg.Text('Page Names', size=(15, 1)), sg.Input(),sg.FileBrowse()],
[sg.Text('Files to Replicate', size=(15, 1)), sg.Input(), sg.FilesBrowse()],
[submit_button, cancel_button]]
In place of sg.FileBrowse() and sg.FilesBrowse() I would like to have my custom buttons similarly to how I created submit_button and cancel_button. I tried to follow the same format but am unsure what key I would have to use to have the button behave just like sg.FileBrowse() and sg.FilesBrowse().
Thanks.
Try this.
Create a button
When button pressed call popup_get_file
Take results from popup and fill in the Input element
import PySimpleGUI as sg
def main():
layout = [ [sg.Text('My Window')],
[sg.Input(key='-IN-'), sg.Button('MyBrowse', key='-BROWSE-')],
[sg.Button('Go'), sg.Button('Exit')] ]
window = sg.Window('Window Title', layout)
while True: # Event Loop
event, values = window.read()
print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == '-BROWSE-':
file = sg.popup_get_file('', no_window=True)
window['-IN-'].update(file)
window.close()
if __name__ == '__main__':
main()
When I use keyboard for dropdown selection, scroll doesn't move up and down,so I am not able to see which one is selected right now. How to move scroll up and down when keyboard is pressed up and down. My sample code is as following:
import PySimpleGUI as sg
class GUI():
def __init__(self):
self.data = [(10), (20), (30), (40), (50), (60), (70), (80), (90), (100)]
self.work_order_currrent_selection_index = 0
def run(self):
layout = [[sg.Listbox(values=self.data, size=(35, 3), enable_events=True, key='selected_key')]]
# Create the Window
self.testWindow = sg.Window('Test', return_keyboard_events=True).Layout(layout).Finalize()
self.testWindow.Maximize()
self.testWindow.Element('selected_key').Update(set_to_index=0)
# Event Loop to process "events"
while True:
event, values = self.testWindow.Read()
if event in('Up:111', '16777235'):
if(hasattr(self, 'testWindow')):
self.work_order_currrent_selection_index = (self.work_order_currrent_selection_index - 1) % len(self.data)
self.testWindow.Element('selected_key').Update(set_to_index=self.work_order_currrent_selection_index)
elif event in ('Down:116',' 16777237'):
if(hasattr(self, 'testWindow')):
self.work_order_currrent_selection_index = (self.work_order_currrent_selection_index + 1) % len(self.data)
self.testWindow.Element('selected_key').Update(set_to_index=self.work_order_currrent_selection_index)
self.testWindow.Close()
if __name__ == '__main__':
app = GUI()
app.run()
When application launch first time I just able to see three dropdown as,
I pressed down arrow key then selection go down one by one like that,
But after selection of 30, on the down key press selection move to next one like 40, 50.. except scrolling, so I am not able to see which one is selected now.
Is there any way to move selection along with scrolling?
See the fourth image, here selection moved to 40 but scroll not moved down. Same issue with up key pressed.
Maybe this will get you a little closer to what you're looking for
import PySimpleGUI as sg
class GUI():
def __init__(self):
self.data = [(10), (20), (30), (40), (50), (60), (70), (80), (90), (100)]
self.work_order_currrent_selection_index = 0
def run(self):
layout = [[sg.Listbox(values=self.data, size=(35, 3), enable_events=True, key='selected_key')]]
# Create the Window
self.testWindow = sg.Window('Test', layout, return_keyboard_events=True, finalize=True)
# self.testWindow.Maximize()
self.testWindow.Element('selected_key').Update(set_to_index=0)
# Event Loop to process "events"
while True:
event, values = self.testWindow.Read()
if event is None:
break
if event.startswith('Up'):
self.work_order_currrent_selection_index = (self.work_order_currrent_selection_index - 1) % len(self.data)
self.testWindow['selected_key'].Update(set_to_index=self.work_order_currrent_selection_index,scroll_to_index=self.work_order_currrent_selection_index )
elif event.startswith('Down'):
self.work_order_currrent_selection_index = (self.work_order_currrent_selection_index + 1) % len(self.data)
self.testWindow['selected_key'].Update(set_to_index=self.work_order_currrent_selection_index, scroll_to_index=self.work_order_currrent_selection_index)
self.testWindow.Close()
if __name__ == '__main__':
app = GUI()
app.run()