Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace PySimpleGUI with Tkinter for Python GUI #130

Merged
merged 27 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6daeedb
python: Use tkinter build GUI instead of PySympleGUI
moon-jam Oct 24, 2024
be455f7
python: Fix weird btn color in different OS
moon-jam Nov 6, 2024
c958eaa
python: Split UI into tabs
JohnAZoidberg Nov 18, 2024
c4b52f0
python: Remove styling
JohnAZoidberg Nov 18, 2024
7f3e67c
python: Move device control to the bottom
JohnAZoidberg Nov 18, 2024
4333b1b
python: Add ledris game
JohnAZoidberg Nov 22, 2024
3d5fca9
python/ledris: Draw on led matrix
JohnAZoidberg Nov 22, 2024
f379c85
python/ledris: Allow to be imported
JohnAZoidberg Nov 22, 2024
4219c2a
python: Add ledris in tkinter GUI
JohnAZoidberg Nov 22, 2024
e24c3c9
python: Migrate snake to pygame
JohnAZoidberg Nov 22, 2024
5ddd382
python: Add game of life to tkinter gui
JohnAZoidberg Nov 22, 2024
b028239
gh-actions: Update actions to v4
JohnAZoidberg Nov 25, 2024
766b235
python: Update windows bundle to Python 3.12
JohnAZoidberg Nov 25, 2024
d97884d
python: Move requirements.txt to subfolder
JohnAZoidberg Nov 25, 2024
7fb179f
python: Implement firmware update
JohnAZoidberg Nov 25, 2024
5440e25
python: Rearrange game of life buttons in a grid
JohnAZoidberg Nov 25, 2024
1b17be5
python: Install pygame
JohnAZoidberg Nov 25, 2024
89186a5
python: Fix pyinstaller
JohnAZoidberg Nov 25, 2024
a6c0258
python: fix popup function changed when removing pysimplegui
JohnAZoidberg Nov 25, 2024
5d4128c
python: readd keyget snake
JohnAZoidberg Nov 25, 2024
ca29198
python: Add GUI screenshot
JohnAZoidberg Nov 25, 2024
cce7898
python: Add links to online info
JohnAZoidberg Nov 25, 2024
ca30109
python: Don't import pygame if not needed
JohnAZoidberg Nov 25, 2024
c3d7359
python: Move sleep/wake buttons to advanced tab
JohnAZoidberg Nov 25, 2024
fd0b85c
python: Launch GUI by default
JohnAZoidberg Nov 25, 2024
13d3d02
python: Add windows app icon
JohnAZoidberg Nov 25, 2024
b5b8739
python: Add executable icon
JohnAZoidberg Nov 25, 2024
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
12 changes: 6 additions & 6 deletions .github/workflows/firmware.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
name: Building
runs-on: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
cargo make --cwd ledmatrix bin

- name: Upload ledmatrix files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ledmatrix_fw_${{github.sha}}
path: |
Expand All @@ -79,15 +79,15 @@ jobs:
target/thumbv6m-none-eabi/release/ledmatrix_evt.uf2

- name: Upload b1display files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: b1display_fw_${{github.sha}}
path: |
target/thumbv6m-none-eabi/release/b1display.bin
target/thumbv6m-none-eabi/release/b1display.uf2

- name: Upload c1minimal files
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: c1minimal_fw_${{github.sha}}
path: |
Expand All @@ -98,7 +98,7 @@ jobs:
name: Linting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand Down Expand Up @@ -130,7 +130,7 @@ jobs:
name: Formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand Down
36 changes: 22 additions & 14 deletions .github/workflows/software.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
# name: Cross-Build for FreeBSD
# runs-on: 'ubuntu-22.04'
# steps:
# - uses: actions/checkout@v3
# - uses: actions/checkout@v4

# - name: Setup Rust toolchain
# run: rustup show
Expand All @@ -41,7 +41,7 @@ jobs:
# run: cross build --target=x86_64-unknown-freebsd

# - name: Upload FreeBSD App
# uses: actions/upload-artifact@v3
# uses: actions/upload-artifact@v4
# with:
# name: qmk_hid_freebsd
# path: target/x86_64-unknown-freebsd/debug/qmk_hid
Expand All @@ -50,7 +50,7 @@ jobs:
name: Build Linux
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install dependencies
run: |
Expand All @@ -69,7 +69,7 @@ jobs:
run: cargo make --cwd inputmodule-control run -- --help | grep 'RAW HID and VIA commandline'

- name: Upload Linux tool
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: inputmodule-control
path: target/x86_64-unknown-linux-gnu/release/inputmodule-control
Expand All @@ -78,7 +78,7 @@ jobs:
name: Build Windows
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand All @@ -92,7 +92,7 @@ jobs:
run: cargo make --cwd inputmodule-control run -- --help | grep 'RAW HID and VIA commandline'

- name: Upload Windows App
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: inputmodule-control.exe
path: target/x86_64-pc-windows-msvc/release/inputmodule-control.exe
Expand All @@ -103,22 +103,30 @@ jobs:
name: Build GUI
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Download releases to bundle
run: |
mkdir releases
mkdir releases\0.2.0
Invoke-WebRequest -Uri https://github.com/FrameworkComputer/inputmodule-rs/releases/download/v0.2.0/ledmatrix.uf2 -OutFile releases\0.2.0\ledmatrix.uf2

# To run locally, need to make sure to include the pywin32 DLL
# pyinstaller --onefile, --name "python/inputmodule/cli.py", --windowed, --add-data "releases;releases" --icon=res\framework_startmenuicon.ico --path C:\users\skype\appdata\local\packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\localcache\local-packages\Python312\site-packages\pywin32_system32 --add-data 'res;res' -p python/inputmodule python/inputmodule/cli.py
- name: Create Executable
uses: Martin005/pyinstaller-action@main
uses: JohnAZoidberg/pyinstaller-action@dont-clean
with:
python_ver: '3.11'
python_ver: '3.12'
spec: python/inputmodule/cli.py #'src/build.spec'
requirements: 'requirements.txt'
upload_exe_with_name: 'ledmatrixgui'
options: --onefile, --windowed, --add-data 'res;res'
requirements: 'python/requirements.txt'
upload_exe_with_name: 'ledmatrixgui.exe'
options: --onefile, --name "ledmatrixgui", --windowed, --add-data "releases;releases" --icon=res/framework_startmenuicon.ico --add-data 'res;res' -p python/inputmodule

package-python:
name: Package Python
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- run: |
cd python
Expand All @@ -131,7 +139,7 @@ jobs:
name: Lints
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install dependencies
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/traditional-cargo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
name: Build firmware
runs-on: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand All @@ -41,7 +41,7 @@ jobs:
name: Build Linux
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install dependencies
run: |
Expand All @@ -61,7 +61,7 @@ jobs:
name: Build Windows
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup Rust toolchain
run: rustup show
Expand All @@ -78,7 +78,7 @@ jobs:
name: Lint and format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install dependencies
run: |
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ To build your own application see the: [API command documentation](commands.md)
Or use our `inputmodule-control` app, which you can download from the latest
[GH Actions](https://github.com/FrameworkComputer/inputmodule-rs/actions) run or
the [release page](https://github.com/FrameworkComputer/inputmodule-rs/releases).
Optionally there are is also a [Python script](python/README.md).

For device specific commands, see their individual documentation pages.

### GUI and Python
There are also a python library and GUI tool. See their [README](python/README.md).

![](res/ledmatrixgui-home.png)

###### Permissions on Linux
To ensure that the input module's port is accessible, install the `udev` rule and trigger a reload:

Expand Down
19 changes: 8 additions & 11 deletions python/inputmodule/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
brightness,
get_brightness,
CommandVals,
bootloader,
bootloader_jump,
GameOfLifeStartParam,
GameControlVal,
)
from inputmodule.gui.games import (
from inputmodule.games import (
snake,
snake_embedded,
pong_embedded,
Expand Down Expand Up @@ -62,10 +62,6 @@
RGB_COLORS,
)

# Optional dependencies:
# from PIL import Image
# import PySimpleGUI as sg


def main_cli():
parser = argparse.ArgumentParser()
Expand Down Expand Up @@ -237,7 +233,7 @@ def main_cli():

if not ports:
print("No device found")
gui.popup(args.gui, "No device found")
gui.popup("No device found", gui=args.gui)
sys.exit(1)
elif args.serial_dev is not None:
filtered_devs = [
Expand All @@ -250,10 +246,10 @@ def main_cli():
dev = ports[0]
elif len(ports) >= 1 and not args.gui:
gui.popup(
args.gui,
"More than 1 compatibles devices found. Please choose from the commandline with --serial-dev COMX.\nConnected ports:\n- {}".format(
"\n- ".join([port.device for port in ports])
),
gui=args.gui,
)
print(
"More than 1 compatible device found. Please choose with --serial-dev ..."
Expand All @@ -268,11 +264,11 @@ def main_cli():

if not args.gui and dev is None:
print("No device selected")
gui.popup(args.gui, "No device selected")
gui.popup("No device selected", gui=args.gui)
sys.exit(1)

if args.bootloader:
bootloader(dev)
bootloader_jump(dev)
elif args.sleep is not None:
send_command(dev, CommandVals.Sleep, [args.sleep])
elif args.is_sleeping:
Expand Down Expand Up @@ -394,6 +390,7 @@ def find_devs():
def print_devs(ports):
for port in ports:
print(f"{port.device}")
print(f" {port.name}")
print(f" VID: 0x{port.vid:04X}")
print(f" PID: 0x{port.pid:04X}")
print(f" SN: {port.serial_number}")
Expand All @@ -407,4 +404,4 @@ def main_gui():


if __name__ == "__main__":
main_cli()
main_gui()
80 changes: 80 additions & 0 deletions python/inputmodule/firmware_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import os
import time

from inputmodule.inputmodule import bootloader_jump
from inputmodule import uf2conv

def dev_to_str(dev):
return dev.name

def flash_firmware(dev, fw_path):
print(f"Flashing {fw_path} onto {dev_to_str(dev)}")

# First jump to bootloader
drives = uf2conv.list_drives()
if not drives:
print("Jump to bootloader")
bootloader_jump(dev)

timeout = 10 # 5s
while not drives:
if timeout == 0:
print("Failed to find device in bootloader")
# TODO: Handle return value
return False
# Wait for it to appear
time.sleep(0.5)
timeout -= 1
drives = uf2conv.get_drives()


if len(drives) == 0:
print("No drive to deploy.")
return False

# Firmware is pretty small, can just fit it all into memory
with open(fw_path, 'rb') as f:
fw_buf = f.read()

for d in drives:
print("Flashing {} ({})".format(d, uf2conv.board_id(d)))
uf2conv.write_file(d + "/NEW.UF2", fw_buf)

print("Flashing finished")

# Example return value
# {
# '0.1.7': {
# 'ansi': 'framework_ansi_default_v0.1.7.uf2',
# 'gridpad': 'framework_gridpad_default_v0.1.7.uf2'
# },
# '0.1.8': {
# 'ansi': 'framework_ansi_default.uf2',
# 'gridpad': 'framework_gridpad_default.uf2',
# }
# }
def find_releases(res_path, filename_format):
from os import listdir
from os.path import isfile, join
import re

releases = {}
try:
versions = listdir(os.path.join(res_path, "releases"))
except FileNotFoundError:
return releases

for version in versions:
path = join(res_path, "releases", version)
releases[version] = {}
for filename in listdir(path):
if not isfile(join(path, filename)):
continue
type_search = re.search(filename_format, filename)
if not type_search:
print(f"Filename '{filename}' not matching patten!")
sys.exit(1)
continue
fw_type = type_search.group(1)
releases[version][fw_type] = os.path.join(res_path, "releases", version, filename)
return releases
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def opposite_direction(direction):
return direction



def snake_keyscan():
global direction
global body
Expand Down
Loading
Loading