Prevent the absence of PyQt5 to stop lauching cgt.

* Change: In CRL/helpers.io, the ErrorWidget requires PyQt5 to execute but
    is not mandatory to run Coriolis/cgt. In order to be more portable,
    if it is not availble just evert to text display on the console.
      This widget will be directly supplied by Coriolis in the future
    completely removing the need for PyQt.
*Change: In cumulus/plugins/aboutwindow, same as above.
This commit is contained in:
Jean-Paul Chaput 2022-10-26 16:37:16 +02:00
parent 60c8bfe75e
commit 118b28b5a7
2 changed files with 235 additions and 204 deletions

View File

@ -19,6 +19,7 @@ import os
import os.path import os.path
import re import re
import traceback import traceback
pyQtIsEnabled = True
try: try:
from PyQt4.QtCore import Qt from PyQt4.QtCore import Qt
from PyQt4.QtGui import QSizePolicy from PyQt4.QtGui import QSizePolicy
@ -57,8 +58,8 @@ except Exception as e:
from PyQt5.QtWidgets import QAction from PyQt5.QtWidgets import QAction
from PyQt5.QtGui import QKeySequence from PyQt5.QtGui import QKeySequence
except Exception: except Exception:
print( '[ERROR] helpers.io, neither PyQt4 nor PyQt5 is available.' ) print( '[WARNING] helpers.io, neither PyQt4 nor PyQt5 is available, disabling ErrorWidget.' )
sys.exit( 1 ) pyQtIsEnabled = False
import Cfg import Cfg
import helpers import helpers
from Hurricane import UpdateSession from Hurricane import UpdateSession
@ -68,93 +69,105 @@ import Viewer
# ------------------------------------------------------------------- # -------------------------------------------------------------------
# Class : "ErrorWidget". # Class : "ErrorWidget".
class ErrorWidget ( QDialog ): def getErrorWidget ():
def __init__ ( self, e ): if pyQtIsEnabled:
QWidget.__init__ ( self, None )
class ErrorWidget ( QDialog ):
self.setWindowTitle( 'Error' ) def __init__ ( self, e ):
message = QLabel( e.getLinesAsString() ) QWidget.__init__ ( self, None )
message.setAlignment( Qt.AlignLeft )
message.setFont( QFont('Courier',10,QFont.Bold) ) self.setWindowTitle( 'Error' )
error = QLabel( '[ERROR]' ) message = QLabel( e.getLinesAsString() )
error.setAlignment( Qt.AlignLeft ) message.setAlignment( Qt.AlignLeft )
font = error.font() message.setFont( QFont('Courier',10,QFont.Bold) )
font.setWeight( QFont.Bold )
error.setFont( font ) error = QLabel( '[ERROR]' )
error.setAlignment( Qt.AlignLeft )
self._tryCont = QPushButton() font = error.font()
self._tryCont.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed ) font.setWeight( QFont.Bold )
self._tryCont.setText ( 'Try to continue' ) error.setFont( font )
self._abort = QPushButton()
self._abort.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed ) self._tryCont = QPushButton()
self._abort.setText ( 'Abort' ) self._tryCont.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed )
self._abort.setDefault ( True ) self._tryCont.setText ( 'Try to continue' )
self._abort = QPushButton()
traceFont = QFont('Courier',10,QFont.Normal) self._abort.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed )
lineHeight = QFontMetrics( traceFont ).height() self._abort.setText ( 'Abort' )
traceText = helpers.textStackTrace( e.trace, False, e.scriptPath ) self._abort.setDefault ( True )
lineCount = traceText.count( '\n' ) + 2
minimumWidth = 400 traceFont = QFont('Courier',10,QFont.Normal)
if Viewer.Graphics.isHighDpi(): minimumWidth = 2100 lineHeight = QFontMetrics( traceFont ).height()
self._trace = QTextEdit() traceText = helpers.textStackTrace( e.trace, False, e.scriptPath )
self._trace.setReadOnly ( True ); lineCount = traceText.count( '\n' ) + 2
self._trace.setLineWrapMode( QTextEdit.NoWrap ); minimumWidth = 400
self._trace.setMinimumSize ( minimumWidth, lineCount*lineHeight ); if Viewer.Graphics.isHighDpi(): minimumWidth = 2100
self._trace.setFont ( traceFont ) self._trace = QTextEdit()
self._trace.setText ( traceText ) self._trace.setReadOnly ( True );
self._trace.setLineWrapMode( QTextEdit.NoWrap );
buttonLayout = QHBoxLayout() self._trace.setMinimumSize ( minimumWidth, lineCount*lineHeight );
buttonLayout.addStretch( 1 ) self._trace.setFont ( traceFont )
buttonLayout.addWidget ( self._tryCont ) self._trace.setText ( traceText )
buttonLayout.addStretch( 1 )
buttonLayout.addWidget ( self._abort ) buttonLayout = QHBoxLayout()
buttonLayout.addStretch( 1 ) buttonLayout.addStretch( 1 )
buttonLayout.addWidget ( self._tryCont )
vLayout = QVBoxLayout() buttonLayout.addStretch( 1 )
vLayout.addWidget ( error ) buttonLayout.addWidget ( self._abort )
vLayout.addStretch( 1 ) buttonLayout.addStretch( 1 )
vLayout.addWidget ( message )
vLayout.addStretch( 1 ) vLayout = QVBoxLayout()
vLayout.addWidget ( self._trace ) vLayout.addWidget ( error )
vLayout.addStretch( 1 ) vLayout.addStretch( 1 )
vLayout.addLayout ( buttonLayout ) vLayout.addWidget ( message )
vLayout.addStretch( 1 )
pixmapWidth = 150 vLayout.addWidget ( self._trace )
if not Viewer.Graphics.isHighDpi(): pixmapWidth = 70 vLayout.addStretch( 1 )
pixmap = QPixmap( ':/images/angry-birds-red.png' ) vLayout.addLayout ( buttonLayout )
pixmap = pixmap.scaledToWidth( pixmapWidth )
icon = QLabel() pixmapWidth = 150
icon.setPixmap( pixmap ) if not Viewer.Graphics.isHighDpi(): pixmapWidth = 70
pixmap = QPixmap( ':/images/angry-birds-red.png' )
hLayout = QHBoxLayout() pixmap = pixmap.scaledToWidth( pixmapWidth )
hLayout.addWidget( icon ) icon = QLabel()
hLayout.addLayout( vLayout ) icon.setPixmap( pixmap )
self.setLayout( hLayout )
hLayout = QHBoxLayout()
self._tryCont.clicked.connect( self.accept ) hLayout.addWidget( icon )
self._abort .clicked.connect( self.reject ) hLayout.addLayout( vLayout )
self.setLayout( hLayout )
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit Coriolis' ) self._tryCont.clicked.connect( self.accept )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') ) self._abort .clicked.connect( self.reject )
self._exitAction.triggered.connect( self.reject )
self.addAction( self._exitAction ) self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit Coriolis' )
self._closeAction = QAction( '&Close', self ) self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._closeAction.setStatusTip( 'Try to continue' ) self._exitAction.triggered.connect( self.reject )
self._closeAction.setShortcut ( QKeySequence('CTRL+W') ) self.addAction( self._exitAction )
self._closeAction.triggered.connect( self.reject )
self.addAction( self._closeAction ) self._closeAction = QAction( '&Close', self )
self._closeAction.setStatusTip( 'Try to continue' )
return self._closeAction.setShortcut ( QKeySequence('CTRL+W') )
self._closeAction.triggered.connect( self.reject )
def closeEvent ( self, event ): self.addAction( self._closeAction )
self.setResult( QDialog.Rejected )
event.accept() return
return
def closeEvent ( self, event ):
if not pyQtIsEnabled: return
self.setResult( QDialog.Rejected )
event.accept()
return
else:
ErrorWidget = None
return ErrorWidget
# ------------------------------------------------------------------- # -------------------------------------------------------------------
@ -232,11 +245,13 @@ class ErrorMessage ( Exception ):
@staticmethod @staticmethod
def show ( code, *arguments ): def show ( code, *arguments ):
e = ErrorMessage( code, *arguments ) e = ErrorMessage( code, *arguments )
if Viewer.Graphics.get().isEnabled(): if not Viewer.Graphics.get().isEnabled():
tryCont = ErrorWidget( e ).exec_()
if not tryCont: raise e
else:
raise e raise e
classErrorWidget = getErrorWidget()
if not classErrorWidget:
raise e
tryCont = ErrorWidget( e ).exec_()
if not tryCont: raise e
return return
@ -256,7 +271,9 @@ def catch ( errorObject ):
print( em ) print( em )
print( helpers.textStackTrace( em.trace, True, em.scriptPath ) ) print( helpers.textStackTrace( em.trace, True, em.scriptPath ) )
if Viewer.Graphics.get().isEnabled(): if Viewer.Graphics.get().isEnabled():
tryCont = ErrorWidget( em ).exec_() classErrorWidget = getErrorWidget()
if classErrorWidget:
tryCont = classErrorWidget( em ).exec_()
if UpdateSession.getStackSize() > 0: UpdateSession.close() if UpdateSession.getStackSize() > 0: UpdateSession.close()
return return

View File

@ -13,126 +13,138 @@
# +-----------------------------------------------------------------+ # +-----------------------------------------------------------------+
import sys
import traceback
pyQtIsEnabled = True
try: try:
import sys from PyQt4.QtCore import Qt
import traceback from PyQt4.QtCore import QEventLoop
from PyQt4.QtGui import QDialog
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QFrame
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
from PyQt4.QtGui import QApplication
except:
try: try:
from PyQt4.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt4.QtCore import QEventLoop from PyQt5.QtCore import QEventLoop
from PyQt4.QtGui import QDialog from PyQt5.QtWidgets import QDialog
from PyQt4.QtGui import QPalette from PyQt5.QtGui import QPalette
from PyQt4.QtGui import QColor from PyQt5.QtGui import QColor
from PyQt4.QtGui import QFont from PyQt5.QtGui import QFont
from PyQt4.QtGui import QWidget from PyQt5.QtWidgets import QWidget
from PyQt4.QtGui import QFrame from PyQt5.QtWidgets import QFrame
from PyQt4.QtGui import QLabel from PyQt5.QtWidgets import QLabel
from PyQt4.QtGui import QVBoxLayout from PyQt5.QtWidgets import QVBoxLayout
from PyQt4.QtGui import QAction from PyQt5.QtWidgets import QAction
from PyQt4.QtGui import QKeySequence from PyQt5.QtGui import QKeySequence
from PyQt4.QtGui import QApplication from PyQt5.QtWidgets import QApplication
except: except:
try: print( '[WARNING] AboutWindow: Neither PyQt4 nor PyQt5 is available, disabling AboutWidget.' )
from PyQt5.QtCore import Qt pyQtIsEnabled = False
from PyQt5.QtCore import QEventLoop import Viewer
from PyQt5.QtWidgets import QDialog import helpers
from PyQt5.QtGui import QPalette from helpers.io import ErrorMessage
from PyQt5.QtGui import QColor from helpers.io import WarningMessage
from PyQt5.QtGui import QFont import plugins
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QFrame
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QAction
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QApplication
except:
print( '[ERROR] AboutWindow: Neither PyQt4 nor PyQt5 is available.' )
sys.exit( 1 )
import Viewer
import helpers
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
except Exception as e:
helpers.io.catch( e )
sys.exit(2)
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Class : "AboutWidget". # Class : "AboutWidget".
class AboutWidget ( QDialog ): def getAboutWidget ():
aboutText = 'Coriolis CAD System 1.0 . . . . . . . . . . . . . . ccb 1.0\n' \
'Copyright (c) 2008-2022 . . . . . . . . Sorbonne Université\n' \
'Authors . . . . . . . . . . . . . . . . Christophe Alexandre\n' \
' . . . . . . . . . . . . . . . . . . Sophie Belloeil\n' \
' . . . . . . . . . . . . . . . . . . Jean-Paul Chaput\n' \
' . . . . . . . . . . . . . . . . . . . Damien Dupuis\n' \
' . . . . . . . . . . . . . . . . . . . Remy Escassut\n' \
' . . . . . . . . . . . . . . . . . . Christian Masson\n' \
'E-Mail . . . . . . . . . . . . . . Jean-Paul.Chaput@lip6.fr'
def __init__ ( self, parent=None ): if pyQtIsEnabled:
QWidget.__init__ ( self, parent )
#self.setFixedSize( 500, 400 ) class AboutWidget ( QDialog ):
#self.setStyleSheet( 'background-color: #ffffdd;' )
topLine = QFrame()
topLine.setFrameShape( QFrame.HLine )
topLine.setLineWidth ( 2 )
botLine = QFrame()
botLine.setFrameShape( QFrame.HLine )
botLine.setLineWidth ( 2 )
title = QLabel( 'CCB' )
title.setAlignment( Qt.AlignCenter )
font = title.font()
font.setPointSize( 72 )
font.setWeight ( QFont.Bold )
title.setFont( font )
subTitle = QLabel( 'Coriolis & Chams Builder for the Dummies' )
subTitle.setAlignment( Qt.AlignCenter )
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
authors = QLabel( 'Coriolis CAD System 1.0 . . . . . . . . ccb 1.0\n'
'Copyright (c) 2008-2016 . . . . . . . . . . UPMC\n'
'Authors . . . . . . . . . . . . . Damien Dupuis\n'
' . . . . . . . . . . . . Jean-Paul Chaput\n'
'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
)
authors.setAlignment( Qt.AlignCenter )
authors.setFont( QFont('Courier',10,QFont.Bold) )
vLayout = QVBoxLayout()
vLayout.addStretch(10)
vLayout.addWidget( topLine )
vLayout.addWidget( title )
vLayout.addStretch(1)
vLayout.addWidget( subTitle )
vLayout.addWidget( authors )
vLayout.addStretch(1)
vLayout.addWidget( botLine )
vLayout.addStretch(10)
frame = QFrame()
frame.setFrameShape ( QFrame.Box )
frame.setFrameShadow( QFrame.Sunken )
frame.setLayout ( vLayout )
frame.setLineWidth ( 1 )
vLayout = QVBoxLayout()
vLayout.addWidget( frame )
self.setLayout( vLayout ) def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
self._exitAction = QAction( '&Exit', self ) #self.setFixedSize( 500, 400 )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' ) #self.setStyleSheet( 'background-color: #ffffdd;' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
#self._exitAction.triggered.connect( QApplication.closeAllWindows ) topLine = QFrame()
self._exitAction.triggered.connect( self.reject ) topLine.setFrameShape( QFrame.HLine )
self.addAction( self._exitAction ) topLine.setLineWidth ( 2 )
botLine = QFrame()
self._closeAction = QAction( '&Close', self ) botLine.setFrameShape( QFrame.HLine )
self._closeAction.setStatusTip( 'Close the About Window' ) botLine.setLineWidth ( 2 )
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
#self._closeAction.triggered.connect( self.close ) title = QLabel( 'CGT' )
self._closeAction.triggered.connect( self.accept ) title.setAlignment( Qt.AlignCenter )
self.addAction( self._closeAction ) font = title.font()
font.setPointSize( 72 )
return font.setWeight ( QFont.Bold )
title.setFont( font )
subTitle = QLabel( 'Coriolis Graphical Interface' )
subTitle.setAlignment( Qt.AlignCenter )
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
authors = QLabel( aboutText )
authors.setAlignment( Qt.AlignCenter )
authors.setFont( QFont('Courier',10,QFont.Bold) )
vLayout = QVBoxLayout()
vLayout.addStretch(10)
vLayout.addWidget( topLine )
vLayout.addWidget( title )
vLayout.addStretch(1)
vLayout.addWidget( subTitle )
vLayout.addWidget( authors )
vLayout.addStretch(1)
vLayout.addWidget( botLine )
vLayout.addStretch(10)
frame = QFrame()
frame.setFrameShape ( QFrame.Box )
frame.setFrameShadow( QFrame.Sunken )
frame.setLayout ( vLayout )
frame.setLineWidth ( 1 )
vLayout = QVBoxLayout()
vLayout.addWidget( frame )
self.setLayout( vLayout )
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
#self._exitAction.triggered.connect( QApplication.closeAllWindows )
self._exitAction.triggered.connect( self.reject )
self.addAction( self._exitAction )
self._closeAction = QAction( '&Close', self )
self._closeAction.setStatusTip( 'Close the About Window' )
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
#self._closeAction.triggered.connect( self.close )
self._closeAction.triggered.connect( self.accept )
self.addAction( self._closeAction )
else:
class AboutWidget ( object ):
def __init__ ( self ):
self.aboutText = aboutText
return AboutWidget
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -149,10 +161,12 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ): def scriptMain ( **kw ):
rvalue = True
try: try:
#helpers.setTraceLevel( 550 ) #helpers.setTraceLevel( 550 )
aboutWidget = AboutWidget() aboutWidget = getAboutWidget()()
if not pyQtIsEnabled:
print( aboutWidget.aboutText )
return True
answer = aboutWidget.exec_() answer = aboutWidget.exec_()
print( 'answer:', answer ) print( 'answer:', answer )
if not answer: return True if not answer: return True
@ -160,4 +174,4 @@ def scriptMain ( **kw ):
helpers.io.catch( e ) helpers.io.catch( e )
sys.stdout.flush() sys.stdout.flush()
sys.stderr.flush() sys.stderr.flush()
return rvalue return True