Skip to content

Commit c14d731

Browse files
Add custom widgets preference option.
1 parent a0469a5 commit c14d731

File tree

5 files changed

+260
-117
lines changed

5 files changed

+260
-117
lines changed

pygubu/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from __future__ import unicode_literals
22

3-
__all__ = ['Builder', 'TkApplication']
3+
__all__ = ['Builder', 'TkApplication', 'BuilderObject', 'register_widget']
44

55
from pygubu.builder import Builder
6+
from pygubu.builder.builderobject import BuilderObject, register_widget
67

78

89
__version__ = '0.9.7.2'

pygubu/builder/__init__.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,20 @@ def _import_class(self, modulename):
326326
if modulename.startswith('ttk.'):
327327
importlib.import_module('pygubu.builder.ttkstdwidgets')
328328
else:
329-
importlib.import_module(modulename)
329+
# Import module as full path
330+
try:
331+
importlib.import_module(modulename)
332+
except ImportError as e:
333+
# A single module can contain various widgets
334+
# try to import the first part of the path
335+
if '.' in modulename:
336+
first, last = modulename.rsplit('.', 1)
337+
try:
338+
importlib.import_module(first)
339+
except ImportError as e:
340+
importlib.import_module(last)
341+
else:
342+
raise e
330343

331344
def _realize(self, master, element):
332345
"""Builds a widget from xml element using master as parent."""

pygubudesigner/main.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
from pygubu.widgets.accordionframe import AccordionFrame
4848
from pygubu.widgets.autoarrangeframe import AutoArrangeFrame
4949
import pygubu.widgets.simpletooltip as tooltip
50-
from pygubudesigner.preferences import PreferencesUI
50+
from pygubudesigner.preferences import PreferencesUI, get_custom_widgets
5151

5252
#translator function
5353
_ = translator
@@ -64,6 +64,15 @@
6464
modulename = "{0}.{1}".format(widgets_pkg, mfile[:-3])
6565
importlib.import_module(modulename)
6666

67+
#initialize custom widgets
68+
for path in get_custom_widgets():
69+
dirname, fname = os.path.split(path)
70+
if fname.endswith('.py'):
71+
if dirname not in sys.path:
72+
sys.path.append(dirname)
73+
modulename = fname[:-3]
74+
importlib.import_module(modulename)
75+
6776
#Initialize images
6877
DESIGNER_DIR = os.path.dirname(os.path.abspath(__file__))
6978
IMAGES_DIR = os.path.join(DESIGNER_DIR, "images")

pygubudesigner/preferences.py

+71-6
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,49 @@
99
import ttk
1010
import tkMessageBox as messagebox
1111
import tkFileDialog as filedialog
12+
try:
13+
import ConfigParser as configparser
14+
except:
15+
import configparser
16+
17+
from appdirs import AppDirs
1218
import pygubu
1319

1420

1521
FILE_PATH = os.path.dirname(os.path.abspath(__file__))
22+
dirs = AppDirs('pygubu-designer')
23+
CONFIG_FILE = os.path.join(dirs.user_data_dir, 'config')
24+
25+
CUSTOM_WIDGETS = 'CUSTOM_WIDGETS'
26+
config = configparser.SafeConfigParser()
27+
config.add_section(CUSTOM_WIDGETS)
28+
29+
30+
def initialize_configfile():
31+
if not os.path.exists(dirs.user_data_dir):
32+
os.makedirs(dirs.user_data_dir)
33+
if not os.path.exists(CONFIG_FILE):
34+
with open(CONFIG_FILE, 'w') as configfile:
35+
config.write(configfile)
36+
37+
def save_configfile():
38+
with open(CONFIG_FILE, 'w') as configfile:
39+
config.write(configfile)
40+
41+
def load_configfile():
42+
if not os.path.exists(CONFIG_FILE):
43+
initialize_configfile()
44+
else:
45+
config.read(CONFIG_FILE)
46+
47+
def get_custom_widgets():
48+
paths = []
49+
for k, p in config.items(CUSTOM_WIDGETS):
50+
paths.append(p)
51+
return paths
52+
53+
# Get user configuration
54+
load_configfile()
1655

1756

1857
class PreferencesUI(object):
@@ -21,8 +60,8 @@ def __init__(self, master, translator=None):
2160
self.master = master
2261
self.translator = translator
2362
self.dialog = None
24-
self.modulestv = None
2563
self._create_preferences_dialog()
64+
self._load_options()
2665

2766
def _create_preferences_dialog(self):
2867
builder = pygubu.Builder(self.translator)
@@ -31,21 +70,47 @@ def _create_preferences_dialog(self):
3170

3271
top = self.master.winfo_toplevel()
3372
self.dialog = dialog = builder.get_object('preferences', top)
34-
self.modulestv = builder.get_object('modules')
35-
73+
self.cwtv = builder.get_object('cwtv')
74+
self.path_remove = builder.get_object('path_remove')
3675
builder.connect_callbacks(self)
76+
77+
def _load_options(self):
78+
for k, p in config.items(CUSTOM_WIDGETS):
79+
self.cwtv.insert('', 'end', text=p)
80+
self._configure_path_remove()
81+
82+
def _save_options(self):
83+
config.remove_section(CUSTOM_WIDGETS)
84+
config.add_section(CUSTOM_WIDGETS)
85+
paths = []
86+
for iid in self.cwtv.get_children():
87+
txt = self.cwtv.item(iid, 'text')
88+
paths.append(txt)
89+
for j, p in enumerate(paths):
90+
config.set(CUSTOM_WIDGETS, 'w{0}'.format(j), p)
91+
save_configfile()
3792

38-
def on_btnclose_clicked(self):
93+
def _configure_path_remove(self):
94+
if len(self.cwtv.get_children()):
95+
self.path_remove.configure(state='normal')
96+
else:
97+
self.path_remove.configure(state='disabled')
98+
99+
def on_dialog_close(self, event=None):
100+
self._save_options()
39101
self.dialog.close()
40102

41103
def on_pathremove_clicked(self):
42-
pass
104+
items = self.cwtv.selection()
105+
self.cwtv.delete(*items)
106+
self._configure_path_remove()
43107

44108
def on_pathadd_clicked(self):
45109
options = {
46110
'defaultextension': '.py',
47111
'filetypes': ((_('Python module'), '*.py'), (_('All'), '*.*'))}
48112
fname = filedialog.askopenfilename(**options)
49113
if fname:
50-
self.modulestv.insert('', tk.END, text=fname)
114+
self.cwtv.insert('', tk.END, text=fname)
115+
self._configure_path_remove()
51116

0 commit comments

Comments
 (0)