Texas Hold’em Gym ML is a desktop app built with Qt 6 (QML / Qt Quick), running on Qt for Python (PySide6).
The QML UI is the primary surface; the Python backend implements the poker engine, persistence, and Qt object bridges.
- QML UI: lobby, table screens, setup, solver, trainers, stats, hand history.
- Python backend:
PokerGame/NlhHandEngine, SQLite hand log and KV state, training drills (Trainer/TrainingStore), QML context wiring.
| Path | Role |
|---|---|
pyproject.toml |
Python packaging (PySide6 app) |
src/texasholdemgym/ |
App entrypoint + Qt/QML backend |
poker/qml/ |
QML UI, assets, and application.qrc |
Prerequisites:
- Python 3.10+
- Qt 6 with
rcconPATH, or setQT_RCC=/path/to/rcc(PySide6 often ships one under.../PySide6/Qt/libexec/rcc)
From the repo root:
python -m venv .venv
. .venv/bin/activate
python -m pip install -U pip
python -m pip install -e .
texas-holdem-gymGame settings, bankroll, ranges, and related JSON live in the SQLite kv table. By default the app uses ./texas-holdem-gym.sqlite in the process current working directory. Set TEXAS_HOLDEM_GYM_SQLITE to an absolute path to use another file. Completed hands use relational tables hands, actions, players with PRAGMA user_version = 1.
See docs/README.md for the index. Main entries:
docs/improvements.md— test gaps, UI suggestions, timer/HUD behavior, backlogdocs/data-and-sqlite.md— database location, schema,texas-holdem-parquet-export, Parquet layoutnotebooks/hand_history_exploration.ipynb— example exploration on exported data (pip install -e '.[analysis]')
pip install -e . # pytest + Coverage.py (`coverage[toml]`, see `pyproject.toml`)
pip install -e '.[test]' # pandas / pyarrow for Parquet + export testspytest alone does not pass --cov (so it never errors if an older env lacks plugins). For line + branch coverage, a terminal report (missing lines, --skip-covered), and fail_under 80% from pyproject.toml, run the packaged helper (from the repo root, or anywhere if pyproject.toml + src/texasholdemgym are discoverable):
texas-holdem-gym-test # same as: coverage run -m pytest -q && coverage report -m --skip-covered
texas-holdem-gym-test --html # also writes htmlcov/
texas-holdem-gym-test tests/test_foo.py # optional pytest path / kwargsEquivalent manual invocation from the repository root:
coverage run -m pytest -q
coverage report -m --skip-coveredQuick test runs without coverage:
pytest -q
pytest -q tests/test_foo.pyWhat the 80% gate measures: everything under src/texasholdemgym/ except modules that are mostly integration glue or optional CLIs (see [tool.coverage.run] omit in pyproject.toml): app.py (GUI entry), backend/poker_game.py (large Qt/QML bridge), parquet_export.py (optional Parquet CLI, also covered by tests/test_parquet_export.py when pandas/pyarrow are installed). Adjust omit or add tests if you intentionally expand scope.
Optional dead-code scan (requires pip install -e '.[dev]'):
vulture src/texasholdemgym --min-confidence 80CI runs Ruff (pyflakes), byte-compile, texas-holdem-gym-test (coverage + report + gate), and python -m build — see .github/workflows/ci.yml.
pip install -e '.[dev,test]'
ruff check src testspip install -e '.[analysis]'
texas-holdem-parquet-export -o ./parquet_exportSee docs/data-and-sqlite.md for options and the exploration notebook.
