"""
CBMPy: CBQt4 module
===================
Constraint Based Modelling in Python (http://pysces.sourceforge.net/getNewReaction)
Copyright (C) 2009-2017 Brett G. Olivier, VU University Amsterdam, Amsterdam, The Netherlands
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Author: Brett G. Olivier
Contact email: bgoli@users.sourceforge.net
Last edit: $Author: bgoli $ ($Id: CBQt4.py 575 2017-04-13 12:18:44Z bgoli $)
"""
# preparing for Python 3 port
from __future__ import division, print_function
from __future__ import absolute_import
#from __future__ import unicode_literals
import os, time, random, math, re, webbrowser, urllib2
from .CBCommon import pp_chemicalFormula
from .CBModel import Reaction as CBMReaction
HAVE_QT4 = False
try:
import PyQt4
from PyQt4 import QtCore, QtGui, QtSvg
from PyQt4.QtWebKit import QGraphicsWebView
HAVE_QT4 = True
print('Qt4 GUI tools available')
except ImportError as ex:
print('\nQt4 GUI tools not available.')
print(ex)
class ReactionCreator(QtGui.QWidget):
#_fba = None
_mlist = None
_rlist = None
_flist = None
_newSubs = None
_newProds = None
_fixColour = None
_errColour = None
_goodColour = None
_cfdict = None
_cndict = None
_ccdict = None
IGNORECHECK = False
ISBALANCED = True
NewReaction = None
_Blower = '-inf'
_Bupper = 'inf'
def __init__(self, rlist, mlist, flist, cfdict, cndict, ccdict):
super(ReactionCreator, self).__init__()
self.mousePos = self.cursor().pos()
rlist.sort()
mlist.sort()
flist.sort()
self._rlist = rlist
self._mlist = mlist
self._flist = flist
self._cfdict = cfdict
self._cndict = cndict
self._ccdict = ccdict
self._newSubs = []
self._newProds = []
self._fixColour = QtGui.QColor(0,0,153,alpha=255)
self._errColour = QtGui.QColor(255,0,0,alpha=255)
self._goodColour = QtGui.QColor(0,100,0,alpha=255)
self.initUI()
def addSubstrate(self, coeff, sid):
self.tblSub.insertRow(self.tblSubRow)
self.tblSub.setItem(self.tblSubRow, 0, QtGui.QTableWidgetItem('{}'.format(coeff)))
self.tblSub.setItem(self.tblSubRow, 1, QtGui.QTableWidgetItem('{}'.format(sid)))
CF = 'None'
if sid in self._cfdict:
CF = self._cfdict[sid]
self.tblSub.item(self.tblSubRow, 1).setToolTip(CF)
if sid in self._flist:
self.tblSub.item(self.tblSubRow, 1).setForeground(self._fixColour)
self.tblSub.item(self.tblSubRow, 0).setTextAlignment(QtCore.Qt.AlignCenter)
self.tblSubRow += 1
def addSelectedSubstrates(self):
self.IGNORECHECK = True
items = [str(it_.text()) for it_ in self.lstSub.selectedItems()]
self.setFocus(PyQt4.QtCore.Qt.OtherFocusReason)
#print(items)
for i_ in items:
if i_ not in self._newSubs:
self.addSubstrate(1, i_)
self._newSubs.append(i_)
self.IGNORECHECK = False
self.statusBar.showMessage('Substrates(s) added')
self.checkBalance()
def addProduct(self, coeff, sid):
self.tblProd.insertRow(self.tblProdRow)
self.tblProd.setItem(self.tblProdRow, 0, QtGui.QTableWidgetItem('{}'.format(coeff)))
self.tblProd.setItem(self.tblProdRow, 1, QtGui.QTableWidgetItem('{}'.format(sid)))
CF = 'None'
if sid in self._cfdict:
CF = self._cfdict[sid]
self.tblProd.item(self.tblProdRow, 1).setToolTip(CF)
if sid in self._flist:
self.tblProd.item(self.tblProdRow, 1).setForeground(self._fixColour)
self.tblProd.item(self.tblProdRow, 0).setTextAlignment(QtCore.Qt.AlignCenter)
self.tblProdRow += 1
def addSelectedProducts(self):
self.IGNORECHECK = True
items = [str(it_.text()) for it_ in self.lstProd.selectedItems()]
self.setFocus(PyQt4.QtCore.Qt.OtherFocusReason)
#print(items)
for i_ in items:
if i_ not in self._newProds:
self.addProduct(1, i_)
self._newProds.append(i_)
self.IGNORECHECK = False
self.statusBar.showMessage('Product(s) added')
self.checkBalance()
#def keyPressEvent(self, event):
#print('KeyPress key: {}'.format(str(event.key())))
#if event.key() == 16777223:
#print('You pressed the delete key')
def deleteSubstrates(self):
self.deleteReagents('substrate')
def deleteProducts(self):
self.deleteReagents('product')
def deleteAllSubstrates(self):
self.tblSub.clear()
for r_ in range(self.tblSubRow-1,-1,-1):
self.tblSub.removeRow(r_)
self.tblSubRow = 0
self.checkBalance()
def deleteAllProducts(self):
self.tblProd.clear()
for r_ in range(self.tblProdRow-1,-1,-1):
self.tblProd.removeRow(r_)
self.tblProdRow = 0
self.checkBalance()
def deleteReagents(self, reagentType):
selected = None
PRODACTIVE = False
SUBACTIVE = False
self.IGNORECHECK = True
if reagentType == 'substrate':
selected = [(it_.row(), it_.column()) for it_ in self.tblSub.selectedItems()]
SUBACTIVE = True
elif reagentType == 'product':
selected = [(it_.row(), it_.column()) for it_ in self.tblProd.selectedItems()]
PRODACTIVE = True
if selected != None:
deleteRow = []
if len(selected) == 2:
if selected[0][0] == selected[1][0]:
if selected[0][1]+1 == selected[1][1]:
deleteRow.append(selected[0][0])
elif len(selected) > 2:
for it_ in range(0, len(selected), 2):
if selected[it_][1] == selected[it_+1][1]:
if selected[it_][0]+1 == selected[it_+1][0]:
if selected[it_][0] not in deleteRow:
deleteRow.append(selected[it_][0])
if selected[it_][0]+1 not in deleteRow:
deleteRow.append(selected[it_][0]+1)
deleteRow.sort()
for d_ in range(len(deleteRow)-1,-1,-1):
if SUBACTIVE:
print('Deleting Sub table row: {}'.format(deleteRow[d_]))
self.statusBar.showMessage('Substrate(s) deleted')
#print(self._newSubs)
#print(str(self.tblSub.item(d_, 1).text()))
self._newSubs.pop(self._newSubs.index(str(self.tblSub.item(d_, 1).text())))
self.tblSub.removeRow(deleteRow[d_])
self.tblSubRow -= 1
elif PRODACTIVE:
print('Deleting Prod table row: {}'.format(deleteRow[d_]))
self.statusBar.showMessage('Product(s) deleted')
#print(self._newProds)
#print(str(self.tblProd.item(d_, 1).text()))
self._newProds.pop(self._newProds.index(str(self.tblProd.item(d_, 1).text())))
self.tblProd.removeRow(deleteRow[d_])
self.tblProdRow -= 1
self.IGNORECHECK = False
self.checkBalance()
def checkBalance(self):
if self.IGNORECHECK:
return
output = {}
left = {}
right = {}
for r_ in range(self.tblSubRow):
sid = str(self.tblSub.item(r_, 1).text())
scoef = float(str(self.tblSub.item(r_, 0).text()))
#print scoef
if sid in self._cfdict:
cf = self._cfdict[sid]
if cf not in [None, 'None', '', ' ']:
cfl = pp_chemicalFormula.parseString(cf).asList()
else:
cfl = []
#print sid, cf, cfl
for e_ in cfl:
if e_[0] in output:
output[e_[0]] = output[e_[0]] + -scoef*float(e_[1])
#print scoef*float(e_[1])
else:
output[e_[0]] = -scoef*float(e_[1])
#print scoef*float(e_[1])
if e_[0] in left:
left[e_[0]] = left[e_[0]] + scoef*float(e_[1])
else:
left[e_[0]] = scoef*float(e_[1])
for r_ in range(self.tblProdRow):
sid = str(self.tblProd.item(r_, 1).text())
pcoef = float(str(self.tblProd.item(r_, 0).text()))
#print pcoef, type(pcoef)
if sid in self._cfdict:
cf = self._cfdict[sid]
if cf not in [None, 'None', '', ' ']:
cfl = pp_chemicalFormula.parseString(cf).asList()
else:
cfl = []
#print sid, cf, cfl
for e_ in cfl:
if e_[0] in output:
#print -pcoef*float(e_[1])
output[e_[0]] = output[e_[0]] + pcoef*float(e_[1])
else:
#print -pcoef*float(e_[1])
output[e_[0]] = pcoef*float(e_[1])
if e_[0] in right:
#print -pcoef*float(e_[1])
right[e_[0]] = right[e_[0]] + pcoef*float(e_[1])
else:
#print -pcoef*float(e_[1])
right[e_[0]] = pcoef*float(e_[1])
#print output
self.updateBalance(output, left, right)
#self.txtBal.setText(str(output))
def updateBalance(self, bdict, left, right):
colHead = []
keys = list(bdict)
if self.tblBalCol > 0:
for c_ in range(self.tblBalCol-1,-1,-1):
self.tblBal.removeColumn(c_)
self.tblBalCol = 0
self.ISBALANCED = True
for k_ in range(len(keys)):
if not keys[k_] in left:
left[keys[k_]] = 'None'
if not keys[k_] in right:
right[keys[k_]] = 'None'
self.tblBalCol += 1
self.tblBal.insertColumn(k_)
self.tblBal.setItem(0, k_, QtGui.QTableWidgetItem('{}'.format(abs(bdict[keys[k_]]))))
self.tblBal.setItem(1, k_, QtGui.QTableWidgetItem('{}'.format(left[keys[k_]])))
self.tblBal.setItem(2, k_, QtGui.QTableWidgetItem('{}'.format(right[keys[k_]])))
self.tblBal.item(0, k_).setTextAlignment(QtCore.Qt.AlignCenter)
if k_ == 0:
boldFont = self.tblBal.item(0, k_).font()
boldFont.setBold(True)
self.tblBal.item(0, k_).setFont(boldFont)
self.tblBal.item(1, k_).setTextAlignment(QtCore.Qt.AlignCenter)
self.tblBal.item(2, k_).setTextAlignment(QtCore.Qt.AlignCenter)
if bdict[keys[k_]] != 0.0:
self.ISBALANCED = False
self.tblBal.item(0, k_).setForeground(self._errColour)
else:
self.tblBal.item(0, k_).setForeground(self._goodColour)
self.tblBal.setHorizontalHeaderLabels(QtCore.QStringList(keys))
def showErrorMessage(self, errorMsg, title="Reaction Creator"):
QtGui.QMessageBox.critical(None, title,\
errorMsg,\
QtGui.QMessageBox.Ok | QtGui.QMessageBox.Default,\
QtGui.QMessageBox.NoButton)
self.statusBar.showMessage(errorMsg)
def getNewReaction(self):
reversible = self.btReverse.isChecked()
if not reversible and self._Blower == '-inf':
self._Blower = 0.0
Id = str(self.txtId.toPlainText()).strip()
Name = str(self.txtNm.toPlainText()).strip()
if Id == 'NewReactionId':
print('\nWARNING: using default reaction id')
errorMsg = None
if Id == "":
errorMsg = 'Reaction ID must be specified.'
elif Id in self._rlist:
errorMsg = 'Reaction ID \"{}\" already exists.'.format(Id)
if errorMsg != None:
self.showErrorMessage(errorMsg)
self.NewReaction = None
return None
if self.tblSubRow == 0 and self.tblProdRow == 0:
self.showErrorMessage('At least one reagent must be defined.')
self.NewReaction = None
return None
#print('\nid=\"{}\"\nname=\"{}\"'.format(Id, Name))
#print self.tblSub.rowCount(), self.tblSubRow
#print self.tblProd.rowCount(), self.tblProdRow
Reag = {}
exReac = False
for s_ in range(self.tblSub.rowCount()):
coeff = -abs(float(self.tblSub.item(s_, 0).text()))
Sid = str(self.tblSub.item(s_, 1).text()).strip()
if Sid in self._flist:
exReac = True
Reag[Sid] = coeff
for p_ in range(self.tblProd.rowCount()):
coeff = abs(float(self.tblProd.item(p_, 0).text()))
Sid = str(self.tblProd.item(p_, 1).text()).strip()
if Sid in self._flist:
exReac = True
if Sid in Reag:
Reag[Sid] += coeff
else:
Reag[Sid] = coeff
for r_ in tuple(Reag):
if Reag[r_] == 0.0:
Reag.pop(r_)
print('removing zero coefficient reagent: {}'.format(r_))
self.NewReaction = {'reversible' : reversible,
'id' : Id,
'name' : Name,
'is_exchange' : exReac,
'is_balanced' : self.ISBALANCED,
'reagents' : Reag,
'upper_bound' : self._Bupper,
'lower_bound' : self._Blower
}
sub = ''
prod = ''
for r_ in Reag:
coeff = abs(Reag[r_])
if Reag[r_] < 0.0:
if coeff == 1.0:
sub += '%s + ' % (r_)
else:
sub += '{%s} %s + ' % (coeff, r_)
else:
if coeff == 1.0:
prod += '%s + ' % (r_)
else:
prod += '{%s} %s + ' % (coeff, r_)
if reversible:
eq = '%s\n\t%s\n%s' % (sub[:-3], '<==>', prod[:-2])
else:
eq = '%s\n\t%s\n%s' % (sub[:-3], '-->', prod[:-2])
#quit_msg = "Add reaction:\n\n{}\n\t{}\n{}".format(sub,rev,prod)
quit_msg = eq
reply = QtGui.QMessageBox.question(self, 'Do you want to add the reaction \"{}\" to the model?'.format(Id),
quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
self.statusBar.showMessage('Reaction {} added to model'.format(Id))
print(self.NewReaction)
QtGui.qApp.quit()
else:
print('Try again')
self.NewReaction = None
def initUI(self):
# create labels
lblSub = QtGui.QLabel('Substrates')
lblSub.setAlignment(QtCore.Qt.AlignCenter)
lblProd = QtGui.QLabel('Products')
lblProd.setAlignment(QtCore.Qt.AlignCenter)
lblId = QtGui.QLabel('Reaction id')
lblId.setAlignment(QtCore.Qt.AlignCenter)
lblNm = QtGui.QLabel('Reaction name')
lblNm.setAlignment(QtCore.Qt.AlignCenter)
# create text boxes
self.txtId = QtGui.QTextEdit()
self.txtId.setMaximumHeight(25)
self.txtId.setText('NewReactionId')
self.txtNm = QtGui.QTextEdit()
self.txtNm.setMaximumHeight(25)
self.txtNm.setText('NewReactionName')
self.txtBal = QtGui.QTextEdit()
self.txtBal.setMaximumHeight(40)
# create static lists
self.lstSub = QtGui.QListWidget()
self.lstSub.setSelectionMode(self.lstSub.ExtendedSelection)
self.lstProd = QtGui.QListWidget()
self.lstProd.setSelectionMode(self.lstProd.ExtendedSelection)
# populate lists
cntr = 0
for m_ in self._mlist:
cntr += 1
name = 'None'
comp = 'None'
if m_ in self._ccdict:
comp = self._ccdict[m_]
if m_ in self._cndict:
name = self._cndict[m_]
item = QtGui.QListWidgetItem(m_)
item.setToolTip('{}\t{}'.format(name, comp))
if m_ in self._flist:
item.setForeground(self._fixColour)
self.lstSub.addItem(item.clone())
self.lstProd.addItem(item)
#if cntr == 20: break
# create buttons
self.btAddSub = QtGui.QPushButton('Add substrate(s)')
QtCore.QObject.connect(self.btAddSub, QtCore.SIGNAL('clicked()'), self.addSelectedSubstrates)
self.btAddProd = QtGui.QPushButton('Add product(s)')
QtCore.QObject.connect(self.btAddProd, QtCore.SIGNAL('clicked()'), self.addSelectedProducts)
self.btReverse = QtGui.QPushButton('Reversible')
self.btReverse.setCheckable(True)
self.btReverse.setChecked(True)
# create tables
self.tblSub = QtGui.QTableWidget()
self.tblSub.setSortingEnabled(True)
self.tblSub.insertColumn(0)
self.tblSub.insertColumn(1)
self.tblSub.setHorizontalHeaderLabels(QtCore.QStringList(('Coefficient','Metabolite')))
self.tblSub.verticalHeader().setVisible(False)
QtCore.QObject.connect(self.tblSub, QtCore.SIGNAL('cellChanged(int,int)'), self.checkBalance)
self.tblSubRow = 0
self.tblProd = QtGui.QTableWidget()
self.tblProd.setSortingEnabled(True)
self.tblProd.insertColumn(0)
self.tblProd.insertColumn(1)
self.tblProd.setHorizontalHeaderLabels(QtCore.QStringList(('Coefficient','Metabolite')))
self.tblProd.verticalHeader().setVisible(False)
self.tblProdRow = 0
QtCore.QObject.connect(self.tblProd, QtCore.SIGNAL('cellChanged(int,int)'), self.checkBalance)
self.tblBal = QtGui.QTableWidget()
self.tblBal.setMaximumHeight(150)
self.tblBal.insertRow(0)
self.tblBal.insertRow(1)
self.tblBal.insertRow(2)
self.tblBal.verticalHeader().setVisible(False)
self.tblBalCol = 0
# set up menu and status bar
menuBar = QtGui.QMenuBar()
exitAction = QtGui.QAction('&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit and loose changes')
exitAction.triggered.connect(QtGui.qApp.quit)
addReAction = QtGui.QAction('&Add reaction and exit', self)
addReAction.setShortcut('Ctrl+A')
addReAction.setStatusTip('Add reaction to model and exit')
addReAction.triggered.connect(self.getNewReaction)
fileMenu = menuBar.addMenu('&Model')
fileMenu.addAction(exitAction)
fileMenu.addAction(addReAction)
subAddAction = QtGui.QAction('&Add', self)
subAddAction.triggered.connect(self.addSelectedSubstrates)
subDelAction = QtGui.QAction('&Delete selected', self)
subDelAction.triggered.connect(self.deleteSubstrates)
subDelAllAction = QtGui.QAction('&Delete all', self)
subDelAllAction.triggered.connect(self.deleteAllSubstrates)
subMenu = menuBar.addMenu('&Substrate')
subMenu.addAction(subAddAction)
subMenu.addAction(subDelAction)
subMenu.addAction(subDelAllAction)
prodAddAction = QtGui.QAction('&Add', self)
prodAddAction.triggered.connect(self.addSelectedProducts)
prodDelAction = QtGui.QAction('&Delete selected', self)
prodDelAction.triggered.connect(self.deleteProducts)
prodDelAllAction = QtGui.QAction('&Delete all', self)
prodDelAllAction.triggered.connect(self.deleteAllProducts)
prodMenu = menuBar.addMenu('&Product')
prodMenu.addAction(prodAddAction)
prodMenu.addAction(prodDelAction)
prodMenu.addAction(prodDelAllAction)
self.statusBar = QtGui.QStatusBar()
self.statusBar.showMessage('{} ready'.format('Model'))
# do layout
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(menuBar, 0, 0, 1, 2)
grid.addWidget(self.statusBar, 0, 2, 1, 2)
grid.addWidget(lblId, 1, 0)
grid.addWidget(self.txtId, 1, 1)
grid.addWidget(lblNm, 1, 2)
grid.addWidget(self.txtNm, 1, 3)
grid.addWidget(lblSub, 2, 0, 1, 2)
grid.addWidget(lblProd, 2, 2, 1, 2)
grid.addWidget(self.lstSub, 3, 0, 1, 2)
grid.addWidget(self.lstProd, 3, 2, 1, 2)
grid.addWidget(self.btAddSub, 4, 0)
grid.addWidget(self.btReverse, 4, 1, 1, 2)
grid.addWidget(self.btAddProd, 4, 3)
grid.addWidget(self.tblSub, 5, 0, 1, 2)
grid.addWidget(self.tblProd, 5, 2, 1, 2)
grid.addWidget(self.tblBal, 6, 0, 1, 4)
self.setLayout(grid)
self.setGeometry(self.mousePos.x()-75, self.mousePos.y()-75, 500, 640)
self.setWindowTitle('Reaction Creator')
self.show()
[docs]def createReaction(mod):
"""
Create a reaction using the graphical Reaction Creator
- *mod* a CBMPy model object
"""
cfdict = {}
cndict = {}
ccdict = {}
for s_ in mod.species:
cfdict[s_.getId()] = s_.getChemFormula()
cndict[s_.getId()] = s_.getName()
ccdict[s_.getId()] = s_.compartment
app = QtGui.QApplication([])
ex = ReactionCreator(mod.getReactionIds(), mod.getSpeciesIds(), mod.getBoundarySpeciesIds(), cfdict, cndict, ccdict)
app.exec_()
newR = ex.NewReaction
del app, ex
if newR == None:
return None
else:
R = CBMReaction(newR['id'], name=newR['name'], reversible=newR['reversible'])
R.is_balanced = newR['is_balanced']
R.is_exchange = newR['is_exchange']
for r_ in newR['reagents']:
R.createReagent(r_, newR['reagents'][r_])
mod.getSpecies(r_).setReagentOf(newR['id'])
mod.addReaction(R, create_default_bounds=False)
mod.createReactionLowerBound(newR['id'], newR['lower_bound'])
mod.createReactionUpperBound(newR['id'], newR['upper_bound'])
return R
class CBFileDialogue(QtGui.QWidget):
_appTitle = 'Open file'
work_dir = None
model_file = None
mode = None
def __init__(self, work_dir, mode='open', filters=None):
super(CBFileDialogue, self).__init__()
self.mousePos = self.cursor().pos()
self.work_dir = work_dir
self.mode = mode
if mode == 'save':
self._appTitle = 'Save file'
self.initUI()
def initUI(self):
#self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
#self.setHidden(True)
self.__dlg__ = QtGui.QFileDialog(self)
if self.mode == 'open':
#self.model_file = str(self.__dlg__.getOpenFileName(self, 'Open file', self.work_dir, options=QtGui.QFileDialog.DontUseNativeDialog))
self.model_file = str(self.__dlg__.getOpenFileName(self, 'Open file', self.work_dir))
elif self.mode == 'save':
#self.model_file = str(self.__dlg__.getSaveFileName(self, 'Save file as', self.work_dir, options=QtGui.QFileDialog.DontUseNativeDialog))
self.model_file = str(self.__dlg__.getSaveFileName(self, 'Save file as', self.work_dir))
self.model_file = os.path.normpath(self.model_file)
def fileDialogue(work_dir=None, mode='open', filters=None):
if work_dir == None:
work_dir = os.getcwd()
if mode in ['open', 'save']:
app = QtGui.QApplication([])
fileApp = CBFileDialogue(work_dir, mode=mode, filters=filters)
model_file = fileApp.model_file
fileApp.__dlg__.done(1)
app.exit()
if mode == 'open':
return model_file
else:
return True
class ViewSVG(QtGui.QWidget):
_fixColour = None
_errColour = None
_goodColour = None
_appTitle = 'ViewSVG'
def __init__(self, filename):
super(ViewSVG, self).__init__()
self.mousePos = self.cursor().pos()
self._fixColour = QtGui.QColor(0,0,153,alpha=255)
self._errColour = QtGui.QColor(255,0,0,alpha=255)
self._goodColour = QtGui.QColor(0,100,0,alpha=255)
self.filename = os.path.abspath(filename)
print('\nViewing file: {}'.format(filename))
self.initUI()
def initUI(self):
# create panels
self.txtId = QtGui.QTextEdit()
# set up menu and status bar
menuBar = QtGui.QMenuBar()
exitAction = QtGui.QAction('&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit and loose changes')
exitAction.triggered.connect(QtGui.qApp.quit)
fileMenu = menuBar.addMenu('&File')
fileMenu.addAction(exitAction)
self.statusBar = QtGui.QStatusBar()
self.statusBar.showMessage('Ready ...')
# webkit panel
scene = QtGui.QGraphicsScene()
view = QtGui.QGraphicsView(scene)
br = QtSvg.QGraphicsSvgItem(self.filename).boundingRect()
webview = QGraphicsWebView()
#webview.load(QtCore.QUrl("C:\your_interactive_svg.svg"))
webview.load(QtCore.QUrl(QtCore.QUrl.fromLocalFile(self.filename)))
webview.setFlags(QtGui.QGraphicsItem.ItemClipsToShape)
webview.setCacheMode(QtGui.QGraphicsItem.NoCache)
webview.resize(br.width(), br.height())
scene.addItem(webview)
view.resize(br.width()+10, br.height()+10)
#view.show()
# do layout
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(menuBar, 0, 0, 1, 2)
#grid.addWidget(self.txtId, 1, 0, 1, 2)
grid.addWidget(view, 1, 0, 4, 4)
grid.addWidget(self.statusBar, 5, 0, 1, 4)
self.setLayout(grid)
self.setGeometry(self.mousePos.x()-75, self.mousePos.y()-75, 500, 640)
self.setWindowTitle(self._appTitle)
self.show()
def loadViewSVG(filename):
app = QtGui.QApplication([])
ex = ViewSVG(filename)
app.exec_()
class ValueSlider(QtGui.QWidget):
_fixColour = None
_errColour = None
_goodColour = None
_appTitle = 'ValueSlider'
def __init__(self):
super(ValueSlider, self).__init__()
self.mousePos = self.cursor().pos()
self._fixColour = QtGui.QColor(0,0,153,alpha=255)
self._errColour = QtGui.QColor(255,0,0,alpha=255)
self._goodColour = QtGui.QColor(0,100,0,alpha=255)
self.initUI()
def initUI(self):
# create panels
#self.txtId = QtGui.QTextEdit()
l1a = QtGui.QLabel(self)
l1a.setText('Property')
sld1 = QtGui.QSlider(QtCore.Qt.Horizontal, self)
sld1.setTickPosition(sld1.TicksBelow)
sld1_min = -100
sld1_max = 100
sld1.setMinimum(sld1_min)
sld1.setMaximum(sld1_max)
sld1.setTickInterval((sld1_min-sld1_max)/10.0)
sld1.setSingleStep(0.1)
sld1.setFocusPolicy(QtCore.Qt.NoFocus)
sld1.valueChanged[int].connect(self.changeValue)
self.l1b = QtGui.QLabel(self)
self.l1b.setText('0.0')
# do layout
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(l1a, 0, 0, 1, 1)
grid.addWidget(self.l1b, 0, 1, 1, 1)
grid.addWidget(sld1, 0, 2, 1, 5)
#grid.addWidget(self.txtId, 1, 0, 1, 2)
#grid.addWidget(menuBar, 0, 0)
#grid.addWidget(self.statusBar, 0, 1)
self.setLayout(grid)
self.setGeometry(self.mousePos.x()-75, self.mousePos.y()-75, 280, 170)
self.setWindowTitle(self._appTitle)
self.show()
def changeValue(self, value):
getattr(self, 'l1b').setText('{}'.format(value))
def loadSlider():
app = QtGui.QApplication([])
ex = ValueSlider()
app.exec_()
data = "<DATASTART><return>{}</return>"
if __name__ == '__main__':
print(os.sys.argv)
if os.sys.argv[1] == 'fileOpen':
filename = fileDialogue(work_dir=None, mode='open', filters=None)
print(data.format(filename))
os.sys.exit(0)
# subprocess.check_output(['python', '_qtloader.py', 'fileOpen']).split('<DATASTART>')[1].strip()
# template widget
"""
class SmallAppBasicGrid(QtGui.QWidget):
_fixColour = None
_errColour = None
_goodColour = None
_appTitle = 'SmallAppBaseGrid'
def __init__(self):
super(SmallAppBasicGrid, self).__init__()
self.mousePos = self.cursor().pos()
self._fixColour = QtGui.QColor(0,0,153,alpha=255)
self._errColour = QtGui.QColor(255,0,0,alpha=255)
self._goodColour = QtGui.QColor(0,100,0,alpha=255)
self.initUI()
def initUI(self):
# create panels
self.txtId = QtGui.QTextEdit()
# set up menu and status bar
menuBar = QtGui.QMenuBar()
exitAction = QtGui.QAction('&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit and loose changes')
exitAction.triggered.connect(QtGui.qApp.quit)
fileMenu = menuBar.addMenu('&File')
fileMenu.addAction(exitAction)
self.statusBar = QtGui.QStatusBar()
self.statusBar.showMessage('Ready ...')
# do layout
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(menuBar, 0, 0, 1, 2)
grid.addWidget(self.txtId, 1, 0, 1, 2)
grid.addWidget(self.statusBar, 2, 0, 1, 2)
self.setLayout(grid)
self.setGeometry(self.mousePos.x()-75, self.mousePos.y()-75, 500, 640)
self.setWindowTitle(self._appTitle)
self.show()
def loadBasicApp(mod):
app = QtGui.QApplication([])
ex = SmallAppBasicGrid()
app.exec_()
"""
# template microGUI
"""
class MicroGUI(QtGui.QWidget):
_appTitle = 'MicroGUI'
def __init__(self):
super(MicroGUI, self).__init__()
self.mousePos = self.cursor().pos()
self.work_dir = work_dir
self.initUI()
def initUI(self):
self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
self.setHidden(True)
# action code (this example is for opening a file dialogue)
self.model_file = str(QtGui.QFileDialog.getOpenFileName(self, 'Open file', os.getcwd()))
def loadMicroGUI(*args):
app = QtGui.QApplication([])
mGUI = OpenFileDialogue()
appTitle = mGUI._appTitle
del mGUI, app
return
"""
"""
import sys
from PyQt4 import QtCore, QtGui, QtSvg
from PyQt4.QtWebKit import QGraphicsWebView
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
scene = QtGui.QGraphicsScene()
view = QtGui.QGraphicsView(scene)
br = QtSvg.QGraphicsSvgItem("C:\your_interactive_svg.svg").boundingRect()
webview = QGraphicsWebView()
webview.load(QtCore.QUrl("C:\your_interactive_svg.svg"))
webview.load(QtCore.QUrl(QtCore.QUrl.fromLocalFile("C:\your_interactive_svg.svg")))
webview.setFlags(QtGui.QGraphicsItem.ItemClipsToShape)
webview.setCacheMode(QtGui.QGraphicsItem.NoCache)
webview.resize(br.width(), br.height())
scene.addItem(webview)
view.resize(br.width()+10, br.height()+10)
view.show()
sys.exit(app.exec_())
"""