停用 wxpython FilePickerCtrl
Deactivate wxpython FilePickerCtrl
有没有办法 activate/deactivate wxpython 小部件尤其是 FilePickerCtrl 小部件的可编辑性?
就我而言,我正在创建一个桌面应用程序,用户可以从中启动和停止服务器。在启动服务器之前,用户可以通过 FilePickerCtrl 小部件指定一个变量,该变量将从服务器使用。我想让 FilePickerCtrl 在服务器停止时可编辑,在服务器 运行ning 时不可编辑。
到目前为止,我已经尝试了 wxpython Validators 但没有成功。一些可重现的代码:
configuration.py
(需要编辑excel路径)
global SERVER_CONF
SERVER_CONF = {
'XE_EXCEL_PATH': '/absolute/path/to/excel.xlsx'
}
gui_main.py
import wx
from server_tab import Server
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="")
# Create a panel and notebook (tabs holder)
p = wx.Panel(self)
nb = wx.Notebook(p)
# Create the tab windows
tab1 = Server(nb)
# Add the windows to tabs and name them.
nb.AddPage(tab1, tab1.name)
# Set noteboook in a sizer to create the layout
sizer = wx.BoxSizer()
sizer.Add(nb, 1, wx.EXPAND)
p.SetSizer(sizer)
if __name__ == "__main__":
app = wx.App()
MainFrame().Show()
app.MainLoop()
server.py
from flask import request
from flask import Flask
from configuration import SERVER_CONF
app = Flask(__name__)
@app.route('/', methods=['POST'])
def read_html_source():
global SERVER_CONF
print('HEREEE',SERVER_CONF['XE_EXCEL_PATH'])
return ('', 200)
@app.route("/shutdown", methods=['GET'])
def shutdown():
shutdown_func = request.environ.get('werkzeug.server.shutdown')
if shutdown_func is None:
raise RuntimeError('Not running werkzeug')
shutdown_func()
return ("Shutting down...", 200)
def main():
app.run(debug=False, port=5001)
if __name__ == "__main__":
main()
server_tab.py
import os
import requests
import threading
import wx
import server
from configuration import SERVER_CONF
# Define the tab content as classes:
class Server(wx.Panel):
name = "Server"
def __init__(self, parent):
global SERVER_CONF
self.is_server_active = False
wx.Panel.__init__(self, parent)
generic_sizer = wx.BoxSizer(wx.VERTICAL)
title = wx.StaticText(self, 0, "The APE API server")
generic_sizer.Add(title, 0, wx.ALL | wx.EXPAND, 5)
file_sizer = wx.BoxSizer(wx.HORIZONTAL)
excel_label = wx.StaticText(self, 0, "Excel ")
file_sizer.Add(excel_label, 0, wx.ALL | wx.EXPAND, 5)
self. excel_browser = wx.FilePickerCtrl(
self,
wildcard='*.xlsx',
path=SERVER_CONF['XE_EXCEL_PATH'],
validator=ServerValidator(self.is_server_active)
)
file_sizer.Add(self.excel_browser, 0, wx.ALL , 5)
generic_sizer.Add(file_sizer, 0, wx.ALL , 5)
server_btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
start_server_btn = wx.Button(self, label='Run Server')
start_server_btn.Bind(wx.EVT_BUTTON, self.start_server)
server_btn_sizer.Add(start_server_btn, 0, wx.ALL | wx.EXPAND, 5)
stop_server_btn = wx.Button(self, label='Stop Server')
stop_server_btn.Bind(wx.EVT_BUTTON, self.stop_server)
server_btn_sizer.Add(stop_server_btn, 0, wx.ALL | wx.EXPAND, 5)
generic_sizer.Add(server_btn_sizer, 0, wx.ALL | wx.EXPAND, 5)
parent.SetSizer(generic_sizer)
def start_server(self, entry):
SERVER_CONF['XE_EXCEL_PATH'] = self.excel_browser.GetPath()
self.is_server_active = True
self.thread = threading.Thread(target=server.main)
self.thread.start()
def stop_server(self, entry):
resp = requests.get('http://localhost:5001/shutdown')
self.thread.join()
print('Server was stoped')
class ServerValidator(wx.PyValidator):
def __init__(self, is_server_active):
wx.Validator.__init__(self)
self.is_server_active = is_server_active
def Clone(self):
'''Required Validator method'''
return ServerValidator(self.is_server_active)
def Validate(self, win):
window = self.GetWindow()
print("Is running?", self.is_server_active)
return not self.is_server_active
运行 使用 python gui_main.py
并使用 curl http://localhost:5001 -d POST
进行测试。如果您忘记从 GUI 停止服务器 运行 curl http://localhost:5001/shutdown
最简单的方法是启用 和禁用 控件。这通常适用于 wx 控件
import wx
class MainFrame(wx.Frame):
"""Create MainFrame class."""
def __init__(self, *args, **kwargs):
super().__init__(None, *args, **kwargs)
self.size = (400, 1000)
self.title_text = 'Wx App'
self.panel = MainPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel)
self.SetSizer(sizer)
self.Size = (600, 200)
self.Center()
self.Show()
def on_disable(self, event):
self.panel.excel_browser.Disable()
def on_enable(self, event):
self.panel.excel_browser.Enable()
class MainPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.excel_browser = wx.FilePickerCtrl(self)
btn_disable = wx.Button(self, id=wx.ID_CANCEL)
btn_disable.Bind(wx.EVT_BUTTON, parent.on_disable)
btn_enable = wx.Button(self, id=wx.ID_OK)
btn_enable.Bind(wx.EVT_BUTTON, parent.on_enable)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.excel_browser)
sizer.Add(btn_disable)
sizer.Add(btn_enable)
self.SetSizer(sizer)
if __name__ == '__main__':
wx_app = wx.App()
MainFrame()
wx_app.MainLoop()
只是为了证明 Psionman 关于启用和禁用 wx 小部件的观点,并且您还可以测试小部件是否IsEnabled
,这可能是一个有用的工具,特别是对于切换控件。
这里,FilePickerCtrl
和 Lock
按钮在启用和禁用之间切换,按钮标签根据选择器是否 Enabled
切换。
import wx
class MainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='Lockable File Selector', size=(400, 200))
self.panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self.s_box = wx.StaticBox(self.panel, -1, 'Please select the input file')
s_sizer = wx.StaticBoxSizer(self.s_box, wx.VERTICAL)
fp_box = wx.BoxSizer(wx.HORIZONTAL)
self.fp_ctrl = wx.FilePickerCtrl(self.panel, wx.ID_ANY, message="Choose a file")
self.fp_lock = wx.Button(self.panel, wx.ID_ANY, label="Lock")
fp_box.Add(self.fp_ctrl, 1, wx.ALL | wx.CENTER | wx.EXPAND, 5)
fp_box.Add(self.fp_lock, 0, wx.ALL | wx.CENTER, 5)
s_sizer.Add(fp_box, 1, wx.ALL | wx.CENTER | wx.EXPAND, 10)
vbox.Add(s_sizer, 0, wx.ALL | wx.CENTER | wx.EXPAND, 5)
self.panel.SetSizer(vbox)
self.fp_ctrl.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_open_file)
self.fp_lock.Bind(wx.EVT_BUTTON, self.on_lock)
self.panel.Fit()
self.fp_lock.Enable(False)
self.Show()
def on_open_file(self, event):
path = self.fp_ctrl.GetPath()
use_path, x = path.rsplit('/', 1)
self.s_box.SetLabel(use_path)
if path:
self.fp_lock.Enable(True)
def on_lock(self, event):
if self.fp_ctrl.IsEnabled():
self.fp_ctrl.Enable(False)
self.fp_lock.SetLabel('Unlock')
else:
self.fp_ctrl.Enable(True)
self.fp_lock.SetLabel('Lock')
if __name__ == '__main__':
app = wx.App()
frame = MainWindow()
app.MainLoop()
有没有办法 activate/deactivate wxpython 小部件尤其是 FilePickerCtrl 小部件的可编辑性?
就我而言,我正在创建一个桌面应用程序,用户可以从中启动和停止服务器。在启动服务器之前,用户可以通过 FilePickerCtrl 小部件指定一个变量,该变量将从服务器使用。我想让 FilePickerCtrl 在服务器停止时可编辑,在服务器 运行ning 时不可编辑。
到目前为止,我已经尝试了 wxpython Validators 但没有成功。一些可重现的代码:
configuration.py
(需要编辑excel路径)
global SERVER_CONF
SERVER_CONF = {
'XE_EXCEL_PATH': '/absolute/path/to/excel.xlsx'
}
gui_main.py
import wx
from server_tab import Server
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="")
# Create a panel and notebook (tabs holder)
p = wx.Panel(self)
nb = wx.Notebook(p)
# Create the tab windows
tab1 = Server(nb)
# Add the windows to tabs and name them.
nb.AddPage(tab1, tab1.name)
# Set noteboook in a sizer to create the layout
sizer = wx.BoxSizer()
sizer.Add(nb, 1, wx.EXPAND)
p.SetSizer(sizer)
if __name__ == "__main__":
app = wx.App()
MainFrame().Show()
app.MainLoop()
server.py
from flask import request
from flask import Flask
from configuration import SERVER_CONF
app = Flask(__name__)
@app.route('/', methods=['POST'])
def read_html_source():
global SERVER_CONF
print('HEREEE',SERVER_CONF['XE_EXCEL_PATH'])
return ('', 200)
@app.route("/shutdown", methods=['GET'])
def shutdown():
shutdown_func = request.environ.get('werkzeug.server.shutdown')
if shutdown_func is None:
raise RuntimeError('Not running werkzeug')
shutdown_func()
return ("Shutting down...", 200)
def main():
app.run(debug=False, port=5001)
if __name__ == "__main__":
main()
server_tab.py
import os
import requests
import threading
import wx
import server
from configuration import SERVER_CONF
# Define the tab content as classes:
class Server(wx.Panel):
name = "Server"
def __init__(self, parent):
global SERVER_CONF
self.is_server_active = False
wx.Panel.__init__(self, parent)
generic_sizer = wx.BoxSizer(wx.VERTICAL)
title = wx.StaticText(self, 0, "The APE API server")
generic_sizer.Add(title, 0, wx.ALL | wx.EXPAND, 5)
file_sizer = wx.BoxSizer(wx.HORIZONTAL)
excel_label = wx.StaticText(self, 0, "Excel ")
file_sizer.Add(excel_label, 0, wx.ALL | wx.EXPAND, 5)
self. excel_browser = wx.FilePickerCtrl(
self,
wildcard='*.xlsx',
path=SERVER_CONF['XE_EXCEL_PATH'],
validator=ServerValidator(self.is_server_active)
)
file_sizer.Add(self.excel_browser, 0, wx.ALL , 5)
generic_sizer.Add(file_sizer, 0, wx.ALL , 5)
server_btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
start_server_btn = wx.Button(self, label='Run Server')
start_server_btn.Bind(wx.EVT_BUTTON, self.start_server)
server_btn_sizer.Add(start_server_btn, 0, wx.ALL | wx.EXPAND, 5)
stop_server_btn = wx.Button(self, label='Stop Server')
stop_server_btn.Bind(wx.EVT_BUTTON, self.stop_server)
server_btn_sizer.Add(stop_server_btn, 0, wx.ALL | wx.EXPAND, 5)
generic_sizer.Add(server_btn_sizer, 0, wx.ALL | wx.EXPAND, 5)
parent.SetSizer(generic_sizer)
def start_server(self, entry):
SERVER_CONF['XE_EXCEL_PATH'] = self.excel_browser.GetPath()
self.is_server_active = True
self.thread = threading.Thread(target=server.main)
self.thread.start()
def stop_server(self, entry):
resp = requests.get('http://localhost:5001/shutdown')
self.thread.join()
print('Server was stoped')
class ServerValidator(wx.PyValidator):
def __init__(self, is_server_active):
wx.Validator.__init__(self)
self.is_server_active = is_server_active
def Clone(self):
'''Required Validator method'''
return ServerValidator(self.is_server_active)
def Validate(self, win):
window = self.GetWindow()
print("Is running?", self.is_server_active)
return not self.is_server_active
运行 使用 python gui_main.py
并使用 curl http://localhost:5001 -d POST
进行测试。如果您忘记从 GUI 停止服务器 运行 curl http://localhost:5001/shutdown
最简单的方法是启用 和禁用 控件。这通常适用于 wx 控件
import wx
class MainFrame(wx.Frame):
"""Create MainFrame class."""
def __init__(self, *args, **kwargs):
super().__init__(None, *args, **kwargs)
self.size = (400, 1000)
self.title_text = 'Wx App'
self.panel = MainPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel)
self.SetSizer(sizer)
self.Size = (600, 200)
self.Center()
self.Show()
def on_disable(self, event):
self.panel.excel_browser.Disable()
def on_enable(self, event):
self.panel.excel_browser.Enable()
class MainPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.excel_browser = wx.FilePickerCtrl(self)
btn_disable = wx.Button(self, id=wx.ID_CANCEL)
btn_disable.Bind(wx.EVT_BUTTON, parent.on_disable)
btn_enable = wx.Button(self, id=wx.ID_OK)
btn_enable.Bind(wx.EVT_BUTTON, parent.on_enable)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.excel_browser)
sizer.Add(btn_disable)
sizer.Add(btn_enable)
self.SetSizer(sizer)
if __name__ == '__main__':
wx_app = wx.App()
MainFrame()
wx_app.MainLoop()
只是为了证明 Psionman 关于启用和禁用 wx 小部件的观点,并且您还可以测试小部件是否IsEnabled
,这可能是一个有用的工具,特别是对于切换控件。
这里,FilePickerCtrl
和 Lock
按钮在启用和禁用之间切换,按钮标签根据选择器是否 Enabled
切换。
import wx
class MainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='Lockable File Selector', size=(400, 200))
self.panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self.s_box = wx.StaticBox(self.panel, -1, 'Please select the input file')
s_sizer = wx.StaticBoxSizer(self.s_box, wx.VERTICAL)
fp_box = wx.BoxSizer(wx.HORIZONTAL)
self.fp_ctrl = wx.FilePickerCtrl(self.panel, wx.ID_ANY, message="Choose a file")
self.fp_lock = wx.Button(self.panel, wx.ID_ANY, label="Lock")
fp_box.Add(self.fp_ctrl, 1, wx.ALL | wx.CENTER | wx.EXPAND, 5)
fp_box.Add(self.fp_lock, 0, wx.ALL | wx.CENTER, 5)
s_sizer.Add(fp_box, 1, wx.ALL | wx.CENTER | wx.EXPAND, 10)
vbox.Add(s_sizer, 0, wx.ALL | wx.CENTER | wx.EXPAND, 5)
self.panel.SetSizer(vbox)
self.fp_ctrl.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_open_file)
self.fp_lock.Bind(wx.EVT_BUTTON, self.on_lock)
self.panel.Fit()
self.fp_lock.Enable(False)
self.Show()
def on_open_file(self, event):
path = self.fp_ctrl.GetPath()
use_path, x = path.rsplit('/', 1)
self.s_box.SetLabel(use_path)
if path:
self.fp_lock.Enable(True)
def on_lock(self, event):
if self.fp_ctrl.IsEnabled():
self.fp_ctrl.Enable(False)
self.fp_lock.SetLabel('Unlock')
else:
self.fp_ctrl.Enable(True)
self.fp_lock.SetLabel('Lock')
if __name__ == '__main__':
app = wx.App()
frame = MainWindow()
app.MainLoop()