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

[WIP] New Qt UI (pyqt6) #756

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
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
37 changes: 35 additions & 2 deletions pelita/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,35 @@
NOISE_RADIUS = 5


class QtViewer:
def __init__(self, *, address, controller, geometry=None, delay=None, stop_after=None):
self.proc = self._run_external_viewer(address, controller, geometry=geometry, delay=delay, stop_after=stop_after)

def _run_external_viewer(self, subscribe_sock, controller, geometry, delay, stop_after):
viewer_args = [ str(subscribe_sock) ]
if controller:
viewer_args += ["--controller-address", str(controller)]
if geometry:
viewer_args += ["--geometry", "{0}x{1}".format(*geometry)]
if delay:
viewer_args += ["--delay", str(delay)]
if stop_after is not None:
viewer_args += ["--stop-after", str(stop_after)]

qtviewer = 'pelita.scripts.pelita_qtviewer'
external_call = [sys.executable,
'-m',
qtviewer] + viewer_args
_logger.debug("Executing: %r", external_call)
# os.setsid will keep the viewer from closing when the main process exits
# a better solution might be to decouple the viewer from the main process
if _mswindows:
p = subprocess.Popen(external_call, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
else:
p = subprocess.Popen(external_call, preexec_fn=os.setsid)
return p


class TkViewer:
def __init__(self, *, address, controller, geometry=None, delay=None, stop_after=None):
self.proc = self._run_external_viewer(address, controller, geometry=geometry, delay=delay, stop_after=stop_after)
Expand Down Expand Up @@ -226,14 +255,18 @@ def setup_viewers(viewers=None, options=None, print_result=True):
viewer_state['viewers'].append(ReplyToViewer(viewer[1]))
elif len(viewer) == 2 and viewer[0] == 'write-replay-to':
viewer_state['viewers'].append(ReplayWriter(open(viewer[1], 'w')))
elif viewer in ('tk', 'tk-no-sync'):
elif viewer in ('tk', 'tk-no-sync', 'qt'):
if not zmq_publisher:
zmq_publisher = ZMQPublisher(address='tcp://127.0.0.1:*')
viewer_state['viewers'].append(zmq_publisher)
if viewer == 'tk':
viewer_state['controller'] = setup_controller()
cls = TkViewer
if viewer == 'qt':
viewer_state['controller'] = setup_controller()
cls = QtViewer
if viewer_state['controller']:
proc = TkViewer(address=zmq_publisher.socket_addr, controller=viewer_state['controller'].socket_addr,
proc = cls(address=zmq_publisher.socket_addr, controller=viewer_state['controller'].socket_addr,
stop_after=options.get('stop_at'),
geometry=options.get('geometry'),
delay=options.get('delay'))
Expand Down
4 changes: 3 additions & 1 deletion pelita/scripts/pelita_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ def long_help(s):
dest='viewer', help='Use the tk viewer (default).')
viewer_opt.add_argument('--tk-no-sync', action='store_const', const='tk-no-sync',
dest='viewer', help=long_help('Uses the tk viewer in an unsynchronized mode.'))
parser.set_defaults(viewer='tk')
viewer_opt.add_argument('--qt', action='store_const', const='qt',
dest='viewer', help='Use the qt viewer (default).')
parser.set_defaults(viewer='qt')

advanced_settings = parser.add_argument_group('Advanced settings')
advanced_settings.add_argument('--reply-to', type=str, metavar='URL', dest='reply_to',
Expand Down
76 changes: 76 additions & 0 deletions pelita/scripts/pelita_qtviewer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python3

import argparse
import os
import sys

from PyQt6.QtWidgets import QApplication

import pelita
from pelita.ui.qt.qt_viewer import QtViewer

from .script_utils import start_logging


def geometry_string(s):
"""Get a X-style geometry definition and return a tuple.

600x400 -> (600,400)
"""
try:
x_string, y_string = s.split('x')
geometry = (int(x_string), int(y_string))
except ValueError:
msg = "%s is not a valid geometry specification" %s
raise argparse.ArgumentTypeError(msg)
return geometry

LOG_QT = os.environ.get("PELITA_LOG_QT", None)

parser = argparse.ArgumentParser(description='Open a Qt viewer')
parser.add_argument('subscribe_sock', metavar="URL", type=str,
help='subscribe socket')
parser.add_argument('--controller-address', metavar="URL", type=str,
help='controller address')
parser.add_argument('--geometry', type=geometry_string,
help='geometry')
parser.add_argument('--delay', type=int,
help='delay')
parser.add_argument('--export', type=str, metavar="FOLDER", help='png export path')
parser.add_argument('--stop-after', type=int, metavar="N",
help='Stop after N rounds.')
parser._optionals = parser.add_argument_group('Options')
parser.add_argument('--version', help='show the version number and exit',
action='store_const', const=True)
parser.add_argument('--log', help='print debugging log information to'
' LOGFILE (default \'stderr\')',
metavar='LOGFILE', const='-', nargs='?')

def main():
args = parser.parse_args()
if args.version:
print("Pelita {}".format(pelita.__version__))
sys.exit(0)

if LOG_QT or args.log:
start_logging(args.log)

viewer_args = {
'address': args.subscribe_sock,
'controller_address': args.controller_address,
'geometry': args.geometry,
'delay': args.delay,
'export': args.export,
'stop_after': args.stop_after
}
app = QApplication(sys.argv)
app.setApplicationName("Pelita")
app.setApplicationDisplayName("Pelita")

mainWindow = QtViewer(**{k: v for k, v in list(viewer_args.items()) if v is not None})
mainWindow.show()
ret = app.exec()
sys.exit(ret)

if __name__ == '__main__':
main()
Loading