import re
import tkinter
import tkinter.messagebox
import raconverter
import raconverter.tooltip
from raconverter.constants import *
class EntryFields:
"""
A class with general/specific methods to create and handle entry fields.
"""
def __init__(self):
self._frame = tkinter.Frame()
@property
def frame(self):
"""
Get frame.
:return: A frame
"""
return self._frame
@staticmethod
def add_tooltip(parent, tooltip_text):
"""
Add a tooltip.
:param parent: The parent widget
:param tooltip_text: The tooltip text
"""
raconverter.tooltip.CreateToolTip(parent, tooltip_text)
@staticmethod
def entry_standard(parent, label_width, entry_width, label_text, default_value=None):
"""
Create entry frame with entry label and field.
:param parent: The parent widget
:param label_width: The label width
:param entry_width: The entry field width
:param label_text: The label text
:param default_value = None | Default value
:return: Entry field
"""
# Entry frame
entry_frame = tkinter.Frame(parent)
entry_frame.pack(side=SIDE_TOP, padx=ENTRY_FRAME_PADX10, pady=ENTRY_FRAME_PADY5, fill=FILL_X)
# Entry label
entry_label = tkinter.Label(entry_frame, font=FONT, anchor=ANCHOR_EAST, width=label_width, text=label_text)
entry_label.pack(side=SIDE_LEFT)
# Entry field
textvariable = tkinter.StringVar(entry_frame, value=default_value)
entry_field = tkinter.Entry(entry_frame, font=FONT, width=entry_width, textvariable=textvariable)
entry_field.pack(side=SIDE_RIGHT, fill=FILL_X, expand=EXPAND_YES)
return entry_field
def entry_data_file_name(self, parent, label_width, entry_width, label_text, default_value=None):
"""
Create entry frame with a specific entry label and field.
Validation/invalidation methods are included.
:param parent: The parent widget
:param label_width: The label width
:param entry_width: The entry field width
:param label_text: The label text
:param default_value = None | Default value
:return: Data file name field
"""
# Register validate/invalidate methods
validatecommand = (self.frame.register(self.valid_data_file_name), ENTRY_STRING)
invalidcommand = (self.frame.register(self.invalid_name), ENTRY_NAME)
# Entry frame
entry_frame = tkinter.Frame(parent)
entry_frame.pack(side=SIDE_TOP, padx=ENTRY_FRAME_PADX10, pady=ENTRY_FRAME_PADY5, fill=FILL_X)
# Entry label
entry_label = tkinter.Label(entry_frame, font=FONT, anchor=ANCHOR_EAST, width=label_width, text=label_text)
entry_label.pack(side=SIDE_LEFT)
# Entry field
textvariable = tkinter.StringVar(entry_frame, value=default_value)
entry_field = tkinter.Entry(entry_frame, font=FONT, width=entry_width, textvariable=textvariable)
entry_field.config(validate=VALIDATE, validatecommand=validatecommand, invalidcommand=invalidcommand)
entry_field.pack(side=SIDE_RIGHT, fill=FILL_X, expand=EXPAND_YES)
return entry_field
def entry_variable_name(self, parent, label_width, entry_width, label_text, default_value=None):
"""
Create entry frame with a specific entry label and field.
Validation/invalidation methods are included.
:param parent: The parent widget
:param label_width: The label width
:param entry_width: The entry field width
:param label_text: The label text
:param default_value = None | Default value
:return: Variable name field
"""
# Register validate/invalidate methods
validatecommand = (self.frame.register(self.valid_variable_name), ENTRY_STRING)
invalidcommand = (self.frame.register(self.invalid_name), ENTRY_NAME)
# Entry frame
entry_frame = tkinter.Frame(parent)
entry_frame.pack(side=SIDE_TOP, padx=ENTRY_FRAME_PADX10, pady=ENTRY_FRAME_PADY5, fill=FILL_X)
# Entry label
entry_label = tkinter.Label(entry_frame, font=FONT, anchor=ANCHOR_EAST, width=label_width, text=label_text)
entry_label.pack(side=SIDE_LEFT)
# Entry field
textvariable = tkinter.StringVar(entry_frame, value=default_value)
entry_field = tkinter.Entry(entry_frame, font=FONT, width=entry_width, textvariable=textvariable)
entry_field.config(validate=VALIDATE, validatecommand=validatecommand, invalidcommand=invalidcommand)
entry_field.pack(side=SIDE_RIGHT, fill=FILL_X, expand=EXPAND_YES)
return entry_field
def validate_data_file_name(self, entry):
"""
Validate the data file name.
:param entry: The entry field with the data file name
:return: True | False
"""
valid = True
data_file_name = entry.get()
# Validate entry string
if not self.valid_data_file_name(data_file_name):
# Get the full widget name
entry_name = str(entry)
self.invalid_name(entry_name)
valid = False
return valid
def validate_variable_name(self, entry):
"""
Validate the variable name.
:param entry: The entry field with the variable name
:return: True | False
"""
valid = True
variable_name = entry.get()
# Validate entry string
if not self.valid_variable_name(variable_name):
# Get the full widget name
entry_name = str(entry)
self.invalid_name(entry_name)
valid = False
return valid
@staticmethod
def valid_data_file_name(entry_text):
"""
Validation method for data file name.
:param entry_text: entry text
:return: True | False
"""
valid = True
# Accept empty string
if not entry_text:
pass
else:
valid &= not len(entry_text) >= 128
valid &= re.match('^(?!\d)\w+$', entry_text) is not None
return valid
@staticmethod
def valid_variable_name(entry_text):
"""
Validation method for variable name(s).
:param entry_text: entry text
:return: True | False
"""
valid = True
names = entry_text.split()
# Accept empty string
if not entry_text:
pass
else:
for name in names:
valid &= not len(name) >= 128
valid &= re.match('^(?!\d)\w+$', name) is not None
return valid
def invalid_name(self, entry_name):
"""
Action performed if validation of the data file or variable name fails.
The method is called automatically when the validation method returns False.
:param entry_name: The name of the entry
"""
# Get entry
entry = self.frame.nametowidget(entry_name)
# Clear entry and show warning
entry.delete(INDEX_START0, INDEX_END)
tkinter.messagebox.showwarning(INVALID_NAME, INVALID_NAME_MESSAGE)
# Return focus to entry
entry.focus_force()
Leave a Reply