Skip to content

Commit

Permalink
Qt6 (Pyside6) and Qt5 (PyQt5) compatibility. Tty combobox improvement.
Browse files Browse the repository at this point in the history
  • Loading branch information
bug400 committed Jul 29, 2022
1 parent e13c5d5 commit 55e2f74
Show file tree
Hide file tree
Showing 21 changed files with 382 additions and 142 deletions.
11 changes: 4 additions & 7 deletions DESCRIPTION.rst
@@ -1,9 +1,6 @@
pyILPER
=======================
=======

This python application provides virtual HP-IL devices for
the PIL-Box of Jean-Francois Garnier. Code was taken from
ILPER 1.4.5 for Windows (Copyright (c) 2008-2013 J-F Garnier,
Visual C++ version by Christoph Gießelink 2013. The
Terminal emulator widget was taken from pyqterm console
widget by Henning Schroeder.
pyILPER emulates virtual peripheral devices for HP-IL (Hewlett-Packard Interface Loop).

Please visit the project page at https://github.com/bug400/pyilper for further information.
49 changes: 45 additions & 4 deletions INSTALL.md
Expand Up @@ -10,18 +10,18 @@ Index
* [Setup](#setup)
* [Operation](#operation)
* [Installation without the ANACONDA platform](#installation-without-the-anaconda-platform)
* [Installation with Qt6 and PIP](#installation-with-qt6-and-pip)
* [Installation of beta or development versions](#installation-of-beta-or-development-versions)

General
-------

pyILPER requires:

* Python 3.5 or higher (Python 3.10 is only supported for pyILPER 1.8.6 and above)
* QT 5.6 or higher
* PyQt compatible to the Python and Qt version
* Python 3.5 or higher
* Qt 5.9 or higher with the PyQt5 language bindings or Qt 6.3 with the PySide6 language bindings
* The Python bindings for either Qt Webkit or Qt Webengine
* Pyserial 2.7
* Pyserial 2.7 or higher
* [LIFUTILS](https://github.com/bug400/lifutils/releases) (the most recent version)

It is recommended to use the [ANACONDA platform](https://www.continuum.io)
Expand Down Expand Up @@ -165,6 +165,47 @@ directory and type:
in a terminal window.


Installation with Qt6 and PIP
-----------------------------

PySide6 is not available from the ANACONDA platform for now.

Get a Python interpreter for your system first:

* Windows: get it from the Microsoft Store
* macOS: download it from the [www.python.org](https://www.python.org) website
* Linux: install it from your repositories if not already installed on your system

Now create a virtual Python environment for pyILPER. This environment contains
the additional software which is needed to run pyILPER. The virtual environment
is created as a subdirectory in the user's home directory. It can be easily
removed.

To create the virtual environmnent "pyilper" open a terminal windows (or command shell) and type:

python -m venv pyilper

This creates a pyilper subdirectory in your home directory.

Now activate the new environment:

source pyilper/bin/activate (Linux, mac OS)
pyilper\Scripts\acivate (Windows)

Before you run this command, make sure that you’re in the folder that contains the virtual environment you just created. If you can see the name of the environment
in your command prompt, then the environment is active.

Now install additional software and type:

python -m pip install PySide6 pyserial

Install and run the pyILPER software as described in the next section.

You can deactivate the virtual environment with the command:

deactivate


Installation of beta or development versions
--------------------------------------------

Expand Down
7 changes: 7 additions & 0 deletions debian/changelog
@@ -1,3 +1,10 @@
pyilper (1.8.6~beta2) bullseye; urgency=medium

* enabled PySide6 language binding in addition to PyQt5
* tty device selection combo box improved

-- focal <achim@trillian> Fri, 29 Jul 2022 14:09:44 +0200

pyilper (1.8.6~beta1) focal; urgency=medium

* remove deprecated language features which are errors under Python 3.10
Expand Down
4 changes: 3 additions & 1 deletion pyilper/Manual/changelog.html
Expand Up @@ -309,7 +309,9 @@ <h3 class="w3-text-teal">pyILPER 1.8.5</h3>
</ul>
<h3 class="w3-text-teal">pyILPER 1.8.6</h3>
<ul class="w3-ul">
<li>Removed use of deprecated language features which are not supported under Python 3.10</li>
<li>Qt5 (PyQt5 binding) and Qt6 (Pyside6) compatibility.</li>
<li>Python 3.10 compatibility.</li>
<li>Tty device selection combo box improved.</li>
</ul>
<!-- End content -->

Expand Down
4 changes: 3 additions & 1 deletion pyilper/Manual/releasenotes.html
Expand Up @@ -31,7 +31,9 @@
<h2 class="w3-text-teal">Release Notes for <em>pyILPER</em> 1.8.6</h2>

<ul class="w3-ul">
<li>Removed use of deprecated language features which are not supported under Python 3.10</li>
<li>Qt5 (PyQt5 binding) and Qt6 (Pyside6) compatibility.</li>
<li>Python 3.10 compatibility.</li>
<li>Tty device selection combo box improved.</li>
</ul>
<!-- End content -->

Expand Down
73 changes: 40 additions & 33 deletions pyilper/lifexec.py
Expand Up @@ -100,19 +100,26 @@
# - show HP-75 text files optional with or without line numbers
# 04.01.2021 jsi
# - exec_single did not get stderr output of executed program
# 04.04.2022 jsi
# - PySide6 migration
#
import subprocess
import tempfile
import os
import pathlib
from PyQt5 import QtCore, QtGui, QtWidgets
from .lifcore import *
from .pilcharconv import barrconv
from .pilcore import isWINDOWS, FONT, decode_version, PDF_ORIENTATION_PORTRAIT
from .pilpdf import cls_pdfprinter
from .pilconfig import PILCONFIG
if isWINDOWS():
import winreg
from .pilcore import QTBINDINGS
if QTBINDINGS=="PySide6":
from PySide6 import QtCore, QtGui, QtWidgets
if QTBINDINGS=="PyQt5":
from PyQt5 import QtCore, QtGui, QtWidgets


PDF_MARGINS=100
BARCODE_HEIGHT=100
Expand Down Expand Up @@ -281,7 +288,7 @@ def exec_double_import(parent,cmd1,cmd2,inputfile):
# execute second command
#
tmpfile.seek(0)
if not cls_chk_import.exec(tmpfile.fileno(), None):
if not cls_chk_import.execute(tmpfile.fileno(), None):
tmpfile.close()
return
tmpfile.seek(0)
Expand Down Expand Up @@ -359,8 +366,8 @@ def exec_double_export(parent,cmd1,cmd2,outputfile):
class cls_LIF_validator(QtGui.QValidator):

def validate(self,string,pos):
self.regexp = QtCore.QRegExp('[A-Za-z][A-Za-z0-9]*')
self.validator = QtGui.QRegExpValidator(self.regexp)
self.regexp = QtCore.QRegularExpression('[A-Za-z][A-Za-z0-9]*')
self.validator = QtGui.QRegularExpressionValidator(self.regexp)
result=self.validator.validate(string,pos)
return result[0], result[1].upper(), result[2]
#
Expand All @@ -372,7 +379,7 @@ def __init__(self,parent= None):
super().__init__()

@staticmethod
def exec(lifimagefile):
def execute(lifimagefile):
d=cls_lifpack()
reply = QtWidgets.QMessageBox.question(d, 'Message', 'Do you really want to pack the LIF image file', QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
Expand Down Expand Up @@ -475,7 +482,7 @@ def __init__(self):
super().__init__()

@staticmethod
def exec (lifimagefile, liffilename, ft,papersize):
def execute (lifimagefile, liffilename, ft,papersize):
d= cls_lifbarcode()
#
# get output file name
Expand Down Expand Up @@ -533,7 +540,7 @@ def __init__(self,parent= None):
super().__init__()

@staticmethod
def exec(lifimagefile,liffile):
def execute(lifimagefile,liffile):
d=cls_lifpurge()
reply = QtWidgets.QMessageBox.question(d, 'Message', 'Do you really want to purge '+liffile, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
Expand Down Expand Up @@ -594,9 +601,9 @@ def do_cancel(self):
super().reject()

@staticmethod
def exec(lifimagefile,liffile):
def execute(lifimagefile,liffile):
d=cls_lifrename(lifimagefile,liffile)
result= d.exec_()
result= d.exec()
#
# export file dialog
#
Expand Down Expand Up @@ -768,9 +775,9 @@ def do_cancel(self):
super().reject()

@staticmethod
def exec(lifimagefile,liffilename,liffiletype,workdir):
def execute(lifimagefile,liffilename,liffiletype,workdir):
d=cls_lifexport(lifimagefile,liffilename,liffiletype,workdir)
result= d.exec_()
result= d.exec()

#
# label lif image file dialog
Expand Down Expand Up @@ -812,9 +819,9 @@ def do_cancel(self):
super().reject()

@staticmethod
def exec(lifimagefile,oldlabel):
def execute(lifimagefile,oldlabel):
d=cls_liflabel(lifimagefile,oldlabel)
result= d.exec_()
result= d.exec()
#
# import file dialog
#
Expand Down Expand Up @@ -953,7 +960,7 @@ def do_checkenable(self):
def do_ok(self):
if self.inputfile != "":
if self.radioNone.isChecked():
if cls_chk_import.exec(None, self.inputfile):
if cls_chk_import.execute(None, self.inputfile):
exec_single(self,[add_path("lifput"),self.lifimagefile,self.inputfile])
else:
self.liffilename=self.leditFileName.text()
Expand All @@ -980,9 +987,9 @@ def do_cancel(self):
super().reject()

@staticmethod
def exec(lifimagefile,workdir):
def execute(lifimagefile,workdir):
d=cls_lifimport(lifimagefile,workdir)
result= d.exec_()
result= d.exec()
#
# check import dialog, ensure that we import a valid LIF transport file
#
Expand Down Expand Up @@ -1053,8 +1060,8 @@ def __init__(self,fd,inputfile,parent=None):
if self.filetype=="Unknown":
self.lblMessage.setText("Unknown file type")
return
self.regexp = QtCore.QRegExp('[A-Z][A-Z0-9]*')
self.validator = QtGui.QRegExpValidator(self.regexp)
self.regexp = QtCore.QRegularExpression('[A-Z][A-Z0-9]*')
self.validator = QtGui.QRegularExpressionValidator(self.regexp)
result=self.validator.validate(self.filename,0)[0]
if result != QtGui.QValidator.Acceptable:
self.lblMessage.setText("Illegal file name")
Expand All @@ -1077,9 +1084,9 @@ def get_retval(self):


@staticmethod
def exec(fd,inputfile):
def execute(fd,inputfile):
d=cls_chk_import(fd,inputfile)
result= d.exec_()
result= d.exec()
return d.get_retval()
#
# check xroms dialog
Expand Down Expand Up @@ -1163,9 +1170,9 @@ def get_call(self):
return self.call

@staticmethod
def exec():
def execute():
d=cls_chkxrom()
result= d.exec_()
result= d.exec()
return d.get_call()
#
# view file dialog
Expand Down Expand Up @@ -1250,15 +1257,15 @@ def do_exit(self):
# get file and pipe it to filter program, show output in editor window
#
@staticmethod
def exec(lifimagefile, liffilename, liffiletype,workdir,charset):
def execute(lifimagefile, liffilename, liffiletype,workdir,charset):
d=cls_lifview(workdir)
ft=get_finfo_name(liffiletype)
call= get_finfo_type(ft)[1]
#
# decomp41 needs additional parameters (xmoms)
#
if call == "decomp41":
call= cls_chkxrom.exec()
call= cls_chkxrom.execute()
#
# liftext75 has the option to show line numbers
#
Expand All @@ -1279,7 +1286,7 @@ def exec(lifimagefile, liffilename, liffiletype,workdir,charset):
if output is None:
return
d.set_text(barrconv(output,charset))
result= d.exec_()
result= d.exec()
#
# Init LIF image file dialog
#
Expand Down Expand Up @@ -1341,8 +1348,8 @@ def __init__(self,workdir,parent= None):
self.leditDirSize=QtWidgets.QLineEdit(self)
self.leditDirSize.setText("500")
self.leditDirSize.setMaxLength(4)
self.regexpDirSize = QtCore.QRegExp('[1-9][0-9]*')
self.validatorDirSize = QtGui.QRegExpValidator(self.regexpDirSize)
self.regexpDirSize = QtCore.QRegularExpression('[1-9][0-9]*')
self.validatorDirSize = QtGui.QRegularExpressionValidator(self.regexpDirSize)
self.leditDirSize.setValidator(self.validatorDirSize)
self.leditDirSize.textChanged.connect(self.do_checkenable)
self.hbox1.addWidget(self.leditDirSize)
Expand Down Expand Up @@ -1455,9 +1462,9 @@ def do_cancel(self):
super().reject()

@staticmethod
def exec(workdir):
def execute(workdir):
d=cls_lifinit(workdir)
result= d.exec_()
result= d.exec()
#
# fix LIF header dialog
#
Expand Down Expand Up @@ -1593,9 +1600,9 @@ def do_cancel(self):
super().reject()

@staticmethod
def exec(workdir):
def execute(workdir):
d=cls_liffix(workdir)
result= d.exec_()
result= d.exec()
#
# Check installation of LIFUTILS dialog
#
Expand Down Expand Up @@ -1634,6 +1641,6 @@ def do_exit(self):
super().accept()

@staticmethod
def exec():
def execute():
d=cls_installcheck()
result= d.exec_()
result= d.exec()
11 changes: 9 additions & 2 deletions pyilper/penconfig.py
Expand Up @@ -29,9 +29,16 @@
# - cls_PenConfigWindow moved from pilplotter.py
# 12.12.2021 jsi:
# - add configversion parameter to open method
# 04.05.2022 jsi:
# - PySide6 migration
#
import copy
from PyQt5 import QtCore, QtGui, QtWidgets
from .pilcore import QTBINDINGS
if QTBINDINGS=="PySide6":
from PySide6 import QtCore, QtGui, QtWidgets
if QTBINDINGS=="PyQt5":
from PyQt5 import QtCore, QtGui, QtWidgets

from .userconfig import cls_userconfig, ConfigError
#
# Plotter pen table model class --------------------------------------------
Expand Down Expand Up @@ -159,7 +166,7 @@ def do_reset(self):
def getPenConfig():
dialog= cls_PenConfigWindow()
dialog.resize(650,600)
result= dialog.exec_()
result= dialog.exec()
if result== QtWidgets.QDialog.Accepted:
return True
else:
Expand Down

0 comments on commit 55e2f74

Please sign in to comment.