Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@

autosummary_generate = True

html_theme = "sphinx_rtd_theme"
html_theme = "furo"
html_static_path = ["_static"]

import os
import sys

sys.path.insert(
0, os.path.abspath("../../mytk")
) # or your actual source folder
# mytk must be installed (pip install -e .) for autodoc to find the package.
20 changes: 7 additions & 13 deletions mytk/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
# Re-export tkinter so users can do `from mytk import *` and get a complete toolkit.
from tkinter import *
import tkinter.ttk as ttk
import tkinter.font as tkFont

from functools import partial
import platform
import time
import signal
import subprocess
import sys
import weakref
import json
from enum import StrEnum
import importlib

from .modulesmanager import ModulesManager
from .bindable import Bindable
from .app import App
Expand All @@ -31,7 +21,6 @@
CellEntry,
NumericEntry,
IntEntry,
CellEntry,
LabelledEntry,
)
from .controls import Slider
Expand All @@ -44,4 +33,9 @@
from .figures import Figure, XYPlot, Histogram
from .videoview import VideoView

__version__ = "0.9.12"
from importlib.metadata import version, PackageNotFoundError
try:
__version__ = version("mytk")
except PackageNotFoundError:
__version__ = "unknown"

151 changes: 95 additions & 56 deletions mytk/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,109 @@
import sys
import argparse
import subprocess
from mytk import *
from mytk import Bindable


def printClassHierarchy(aClass):
def printAllChilds(aClass):
for child in aClass.__subclasses__():
print("\"{0}\" -> \"{1}\"".format(aClass.__name__, child.__name__))
print('"{0}" -> "{1}"'.format(aClass.__name__, child.__name__))
printAllChilds(child)

print("# Paste this in the text field of http://www.webgraphviz.com/")
print("digraph G {")
print(" rankdir=\"LR\";")
print(' rankdir="LR";')
printAllChilds(aClass)
print("}")

root = os.path.dirname(__file__)
examples_dir = os.path.join(root, "example_apps")
examples = [ f for f in sorted(os.listdir(examples_dir)) if f.endswith('.py') and not f.startswith('__') ]

ap = argparse.ArgumentParser(prog='python -m mytk')
ap.add_argument("-e", "--examples", required=False, default='all',
help="Specific example numbers, separated by a comma")
ap.add_argument("-c", "--classes", required=False, action='store_const',
const=True, help="Print the class hierarchy in graphviz format")
ap.add_argument("-l", "--list", required=False, action='store_const',
const=True, help="List all the accessible examples")
ap.add_argument("-t", "--tests", required=False, action='store_const',
const=True, help="Run all Unit tests")

args = vars(ap.parse_args())
runExamples = args['examples']
runTests = args['tests']
printClasses = args['classes']
listExamples = args['list']

if runExamples == 'all':
runExamples = range(1, len(examples)+1)
elif runExamples == '':
runExamples = []
else:
runExamples = [int(y) for y in runExamples.split(',')]

if printClasses:
printClassHierarchy(Bindable)

elif runTests:
moduleDir = os.path.dirname(os.path.realpath(__file__))
err = os.system('cd {0}/tests; {1} -m unittest'.format(moduleDir, sys.executable))
elif listExamples:
for i, app in enumerate(sorted(examples)):
print(f"{i+1:2d}. {app}")
elif runExamples:
for i in runExamples:
entry = examples[i-1]

filepath = os.path.join(examples_dir, entry)
title = f"# mytk example file: {filepath}"

print(f"\n\n\n")
print("#"*len(title))
print(title)
print("#"*len(title))
print(f"\n")

with open(filepath, "r") as file:
print(file.read())

subprocess.run([sys.executable, os.path.join(examples_dir, entry)])

def main():
root = os.path.dirname(__file__)
examples_dir = os.path.join(root, "example_apps")
examples = [
f
for f in sorted(os.listdir(examples_dir))
if f.endswith(".py") and not f.startswith("__")
]

ap = argparse.ArgumentParser(prog="python -m mytk")
ap.add_argument(
"-e",
"--examples",
required=False,
default="all",
help="Specific example numbers, separated by a comma",
)
ap.add_argument(
"-c",
"--classes",
required=False,
action="store_const",
const=True,
help="Print the class hierarchy in graphviz format",
)
ap.add_argument(
"-l",
"--list",
required=False,
action="store_const",
const=True,
help="List all the accessible examples",
)
ap.add_argument(
"-t",
"--tests",
required=False,
action="store_const",
const=True,
help="Run all Unit tests",
)

args = vars(ap.parse_args())
runExamples = args["examples"]
runTests = args["tests"]
printClasses = args["classes"]
listExamples = args["list"]

if runExamples == "all":
runExamples = range(1, len(examples) + 1)
elif runExamples == "":
runExamples = []
else:
runExamples = [int(y) for y in runExamples.split(",")]

if printClasses:
printClassHierarchy(Bindable)

elif runTests:
tests_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "tests")
result = subprocess.run(
[sys.executable, "-m", "unittest"],
cwd=tests_dir,
)
sys.exit(result.returncode)

elif listExamples:
for i, app in enumerate(sorted(examples)):
print(f"{i+1:2d}. {app}")

elif runExamples:
for i in runExamples:
entry = examples[i - 1]
filepath = os.path.join(examples_dir, entry)
title = f"# mytk example file: {filepath}"

print(f"\n\n\n")
print("#" * len(title))
print(title)
print("#" * len(title))
print(f"\n")

with open(filepath, "r") as file:
print(file.read())

subprocess.run([sys.executable, os.path.join(examples_dir, entry)])


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion mytk/entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(
self._widget_args["width"] = character_width
self.value = value
self.bind_properties("value", self, "value_variable")
self.value_variable = StringVar()
self.value_variable = StringVar(value=value)

def create_widget(self, master):
self.parent = master
Expand Down
2 changes: 1 addition & 1 deletion mytk/eventcapable.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def after_cancel_all(self):
"""
Cancels all currently scheduled tasks for this object.
"""
self.after_cancel_many(self.scheduled_tasks)
self.after_cancel_many(list(self.scheduled_tasks))

def bind_event(self, event: str, callback: Callable):
"""
Expand Down
12 changes: 0 additions & 12 deletions mytk/tests/envtest.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
import sys
import os

# append module root directory to sys.path
this_dir = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
)
sys.path.insert(0, this_dir)

# print(this_dir)

import pathlib
import unittest
from mytk import App, View


class MyTkTestCase(unittest.TestCase):
def setUp(self):
timeout = 1000
self.app = App()
testcase_id = self.id()
self.app.window.widget.title(testcase_id)
Expand Down
2 changes: 1 addition & 1 deletion mytk/tests/testCustomDialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def populate_widget_body(self):
diag = MyDialog(
title="Test Window",
buttons_labels=[Dialog.Replies.Ok, Dialog.Replies.Cancel],
# auto_click=[Dialog.Replies.Ok, 1000],
auto_click=(Dialog.Replies.Ok, 100),
)
self.assertIsNotNone(diag)
reply = diag.run()
Expand Down
6 changes: 2 additions & 4 deletions mytk/tests/testImages.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ def test_init_empty(self):
self.assertIsNotNone(Image())

def test_resource_directory(self):
resource_directory = pathlib.Path(__file__).parent.parent / "resources"
self.assertEqual(
resource_directory, pathlib.Path("/Users/dccote/GitHub/myTk/mytk/resources")
)
self.assertTrue(self.resource_directory.exists())
self.assertTrue(self.resource_directory.is_dir())

def test_init_with_path(self):
self.assertIsNotNone(Image(filepath=self.resource_directory / "error.png"))
Expand Down
1 change: 1 addition & 0 deletions mytk/tests/testMyApp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import envtest
import unittest
from functools import partial
from mytk import *


Expand Down
5 changes: 4 additions & 1 deletion mytk/videoview.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
from .popupmenu import PopupMenu
import importlib
import signal
import cv2
try:
import cv2
except ImportError:
cv2 = None


class VideoView(Base):
Expand Down
40 changes: 33 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@

[build-system]
requires = ["setuptools<69", "wheel"]
requires = ["setuptools>=70", "wheel"]
build-backend = "setuptools.build_meta"


[project]
name = "mytk"
version="0.9.14"
version="0.9.15"
description = "A wrapper for Tkinter for busy scientists"
readme = "README.md"
license = {file = "LICENSE"}
requires-python = ">=3.11"
dynamic = ["dependencies"]
authors = [
{name = "Daniel Côté", email = "dccote@cervo.ulaval.ca"}
Expand All @@ -20,19 +21,44 @@ maintainers = [

classifiers = [
"Development Status :: 3 - Alpha",

"Topic :: Software Development :: Build Tools",

# Specify the Python versions you support here.
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering",
"Topic :: Software Development :: Libraries :: Python Modules",
"Environment :: MacOS X",
"Environment :: Win32 (MS Windows)",
"Environment :: X11 Applications",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]

# py_modules=["mytk"]
[project.urls]
Homepage = "https://github.com/DCC-Lab/myTk"
Repository = "https://github.com/DCC-Lab/myTk"
"Bug Tracker" = "https://github.com/DCC-Lab/myTk/issues"


[project.optional-dependencies]
video = ["opencv-python"]
optics = ["raytracing"]
docs = ["furo", "sphinx"]
all = ["mytk[video,optics]"]

[tool.setuptools.package-data]
"mytk.resources" = ["*.png"]

[tool.setuptools.dynamic]
dependencies = {file = ["requirements.txt"]}

[tool.ruff]
target-version = "py311"
line-length = 100

[tool.ruff.lint]
select = ["E", "F", "W", "I"]
ignore = ["E501"]

[tool.pytest.ini_options]
testpaths = ["mytk/tests"]
6 changes: 2 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
matplotlib==3.9.2
matplotlib>=3.9
numpy
packaging
pyperclip
Requests
requests
scipy
pandas
openpyxl
raytracing
opencv-python