Commit 0dae8cdb authored by Mark Hymers's avatar Mark Hymers

Merge branch 'stretch_fixes'

parents 1edca17f c0e1f9cb
......@@ -8,12 +8,12 @@ BINS=$(shell python setup.py --list-scripts)
USAGES=$(addsuffix .txt,$(addprefix doc/gen/usage_,$(BINS)))
SCRIPT_SRC=$(addsuffix .rst,$(addprefix doc/gen/source_,$(BINS)))
PY4UICFILES=$(subst .ui,.py,$(wildcard naf/gui/qt4/ui/*.ui))
PYUICFILES=$(subst .ui,.py,$(wildcard naf/gui/qt/ui/*.ui))
DEVELVERSION ?= 0.DEVEL.$(shell date +%Y%m%d%H%M)
RELEASEVERSION ?= $(DEVELVERSION)
all: $(PY4UICFILES)
all: $(PYUICFILES)
python setup.py build
doc: doc-html
......@@ -28,8 +28,8 @@ doc/gen/source_%.rst: bin/%
@mkdir -p doc/gen
sed "s@PROGNAME@$*@" doc/source_template > $@
naf/gui/qt4/ui/%.py: naf/gui/qt4/ui/%.ui
pyuic4 -o $@ $<
naf/gui/qt/ui/%.py: naf/gui/qt/ui/%.ui
pyuic5 -o $@ $<
doc/bibliography/paperindex.inc: doc/bibliography/references.bib doc/bibliography/parse_references.py
cd doc/bibliography && python parse_references.py
......@@ -47,7 +47,7 @@ clean:
rm -fr doc/bibliography/papers
rm -f doc/bibliography/paperindex.inc
rm -f $(USAGES) $(SCRIPT_SRC)
rm -f $(PY4UICFILES)
rm -f $(PY5UICFILES)
test: all
cd build && PYTHONPATH=lib.$(PYTHONARCH)/:$${PYTHONPATH} NAFTEST=../../naf-testdata nosetests -c ../nose.cfg lib.$(PYTHONARCH)/naf
......
......@@ -22,9 +22,9 @@ release onwards). Package names are Debian binary package names.
python-wxgtk3.0 >= 3.0.1
python-yaml >= 3.11
python-mpi4py >= 1.3.1
python-qt4 >= 4.11.2
pyqt4-dev-tools: >= 4.11.2
qt4-dev-tools >= 4.8.6
python-pyqt5 >= 5.3.2
python-pyqt5.qtopengl >= 5.3.2
pyqt5-dev-tools: >= 5.3.2
python-vtk >= 5.8
python-bibtex >= 1.2.7
libgsl0-dev >= 1.16
......@@ -32,6 +32,12 @@ release onwards). Package names are Debian binary package names.
python-statsmodels >= 0.8
python-sphinx >= 1.2.3 (for building documentation and reports)
python-nose >= 1.3.4 (for running the test suite)
python-vtk >= 5.6
python-bibtex >= 1.2.4
libgsl0-dev >= 1.14
fftw-dev >= 2.1.3
python-sphinx >= 1.0.7
python-nose >= 0.11 (for running the test suite)
python-coverage (for getting test coverage)
xvfb (if building on a machine without an X display set)
......@@ -56,8 +62,8 @@ The following apt-get command should get all of the required dependencies:
apt-get install python-numpy python-scipy python-matplotlib python-h5py \
python-imaging python-dicom python-nifti python-mdp \
python-wxgtk3.0 python-yaml python-mpi4py python-qt4 \
qt4-dev-tools pyqt4-dev-tools python-vtk python-bibtex \
python-wxgtk3.0 python-yaml python-mpi4py python-pyqt5 \
python-pyqt5.qtopengl pyqt5-dev-tools python-vtk python-bibtex \
python-sphinx libgsl0-dev fftw-dev python-nose python-coverage \
python-statsmodels
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -8,17 +8,14 @@
import sys
from os.path import join, dirname, abspath, isfile
from PyQt4 import QtGui
from PyQt4.QtCore import SIGNAL
#from naf.abstract import obj_from_hdf5file
from PyQt5 import QtWidgets
from naf.ynic.parser import YNiCOptionParser#, OptionBaseParameters, OptionDataRuns
from naf.ynic.study import YnicStudy
from naf.gui.qt4.ui.studyDefApp_ui import Ui_StudyDefApp
from naf.gui.qt.ui.studyDefApp_ui import Ui_StudyDefApp
class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
class StudyDefApp(QtWidgets.QMainWindow, Ui_StudyDefApp):
def __init__(self, fname=None, parent=None):
super(StudyDefApp, self).__init__(parent)
......@@ -26,11 +23,11 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
self.LoadStudy(fname)
self.connect(self.action_Open, SIGNAL("triggered()"), self.openYAMLFile)
self.connect(self.action_Save, SIGNAL("triggered()"), self.save)
self.connect(self.actionSave_As, SIGNAL("triggered()"), self.saveAs)
self.connect(self.action_Quit, SIGNAL("triggered()"), self.close)
self.connect(self.action_New, SIGNAL("triggered()"), self.new)
self.action_Open.triggered.connect(self.openYAMLFile)
self.action_Save.triggered.connect(self.save)
self.actionSave_As.triggered.connect(self.saveAs)
self.action_Quit.triggered.connect(self.close)
self.action_New.triggered.connect(self.new)
self.cleanDescendants = []
self.cleanEditDescendants = []
......@@ -81,14 +78,14 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
def CheckDescendantEdits(self):
for j in self.cleanEditDescendants:
while not j.updateclean:
resp = QtGui.QMessageBox.question(self, "Unsubmitted changes!",
resp = QtWidgets.QMessageBox.question(self, "Unsubmitted changes!",
"You have made changes to this study that have not been updated.\nDo you wish to update these changes before continuing?",
QtGui.QMessageBox.Yes|QtGui.QMessageBox.No|QtGui.QMessageBox.Cancel)
if resp == QtGui.QMessageBox.Cancel:
QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No|QtWidgets.QMessageBox.Cancel)
if resp == QtWidgets.QMessageBox.Cancel:
return False
if resp == QtGui.QMessageBox.No:
if resp == QtWidgets.QMessageBox.No:
j.clearData(force=True)
elif resp == QtGui.QMessageBox.Yes:
elif resp == QtWidgets.QMessageBox.Yes:
j.updateData()
return True
......@@ -120,10 +117,10 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
message += "If you answer No, loading of this file will be aborted."
if prompt:
ans = QtGui.QMessageBox.question(self, "Error!",
ans = QtWidgets.QMessageBox.question(self, "Error!",
message,
QtGui.QMessageBox.Yes|QtGui.QMessageBox.No)
if ans == QtGui.QMessageBox.No:
QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No)
if ans == QtWidgets.QMessageBox.No:
return YnicStudy(), None
from naf.meg.readers import EpochRejection
......@@ -168,10 +165,10 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
# We survived, update the YAML file
study.save_yaml_file(fname)
QtGui.QMessageBox.information(self, "Conversion Complete", "The study has been updated to use slice rejection files")
QtWidgets.QMessageBox.information(self, "Conversion Complete", "The study has been updated to use slice rejection files")
except StandardError, e:
QtGui.QMessageBox.warning(self, "Conversion Error", str(e) + "\n\nAborting read of study")
QtWidgets.QMessageBox.warning(self, "Conversion Error", str(e) + "\n\nAborting read of study")
study = YnicStudy()
fname = None
......@@ -180,12 +177,11 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
def LoadStudy(self, fname):
if fname is None:
study = YnicStudy()
else:
try:
study = YnicStudy.from_yaml_file(fname)
except Exception, e:
QtGui.QMessageBox.warning(None, "Invalid YAML File",
QtWidgets.QMessageBox.warning(None, "Invalid YAML File",
"Cannot load yaml file %s:\n%s" % (fname, e))
study = YnicStudy()
fname = None
......@@ -207,14 +203,14 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
return
if not self.clean:
ans = QtGui.QMessageBox.question(self, "Unsaved changes!",
ans = QtWidgets.QMessageBox.question(self, "Unsaved changes!",
"You have made unsaved changes.\nDo you wish to save this study YAML before opening another?",
QtGui.QMessageBox.Yes|QtGui.QMessageBox.No|QtGui.QMessageBox.Cancel)
if ans == QtGui.QMessageBox.Yes:
QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No|QtWidgets.QMessageBox.Cancel)
if ans == QtWidgets.QMessageBox.Yes:
self.save()
if not self.clean:
return
elif ans == QtGui.QMessageBox.Cancel:
elif ans == QtWidgets.QMessageBox.Cancel:
return
self.study = YnicStudy()
......@@ -235,14 +231,14 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
return
if not self.clean:
ans = QtGui.QMessageBox.question(self, "Unsaved changes!",
ans = QtWidgets.QMessageBox.question(self, "Unsaved changes!",
"You have made unsaved changes.\nDo you wish to save this study YAML before opening another?",
QtGui.QMessageBox.Yes|QtGui.QMessageBox.No|QtGui.QMessageBox.Cancel)
if ans == QtGui.QMessageBox.Yes:
QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No|QtWidgets.QMessageBox.Cancel)
if ans == QtWidgets.QMessageBox.Yes:
self.save()
if not self.clean:
return
elif ans == QtGui.QMessageBox.Cancel:
elif ans == QtWidgets.QMessageBox.Cancel:
return
if self.fname is not None:
......@@ -253,7 +249,7 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
extstr = '*.yaml'
else:
extstr = '*.' + extension
fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open Study File.', startfile, extstr))
fname, ffilter = QtWidgets.QFileDialog.getOpenFileName(self, 'Open Study File.', startfile, extstr)
if fname == '':
return
......@@ -264,14 +260,14 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
self.clean = True
except Exception, e:
QtGui.QMessageBox.warning(self, "Study Read Error",
QtWidgets.QMessageBox.warning(self, "Study Read Error",
"This study file is invalid and could not be loaded:\n%s" %e)
self.SetWindowTitle()
def validateStudy(self):
if self.study.name is None or self.study.name == '' or self.study.storage_dir is None or self.study.storage_dir == '':
QtGui.QMessageBox.warning(self, "Incomplete Study information",
QtWidgets.QMessageBox.warning(self, "Incomplete Study information",
"Study must have a name and storage directory\nPlease add this information before saving.")
return False
......@@ -304,7 +300,7 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
startdir = dirname(self.fname)
else:
startdir = '.'
fname = str(QtGui.QFileDialog.getSaveFileName(self, 'Save Study YAML File.', startdir, '*.yaml'))
fname, ffilter = QtWidgets.QFileDialog.getSaveFileName(self, 'Save Study YAML File.', startdir, '*.yaml')
if fname == '':
return
if not fname.endswith('.yaml'):
......@@ -330,16 +326,16 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
if self.clean:
event.accept()
else:
ans = QtGui.QMessageBox.question(self, "Unsaved changes!",
ans = QtWidgets.QMessageBox.question(self, "Unsaved changes!",
"You have made unsaved changes.\nDo you wish to save this study YAML before quitting?",
QtGui.QMessageBox.Yes|QtGui.QMessageBox.No|QtGui.QMessageBox.Cancel)
if ans == QtGui.QMessageBox.Yes:
QtWidgets.QMessageBox.Yes|QtWidgets.QMessageBox.No|QtWidgets.QMessageBox.Cancel)
if ans == QtWidgets.QMessageBox.Yes:
self.save()
if self.clean:
event.accept()
return
elif ans == QtGui.QMessageBox.No:
elif ans == QtWidgets.QMessageBox.No:
event.accept()
return
......@@ -347,7 +343,7 @@ class StudyDefApp(QtGui.QMainWindow, Ui_StudyDefApp):
def main():
app = QtGui.QApplication(sys.argv)
app = QtWidgets.QApplication(sys.argv)
usage_str = """%prog YAML_FILE
......
This diff is collapsed.
......@@ -6,8 +6,8 @@ Build-Depends: debhelper (>= 7), fftw-dev, openmpi-bin, libopenmpi-dev, libgsl0-
python-coverage, python-nose, python-sphinx, python-bibtex,
python-h5py, python-numpy, python-scipy, python-matplotlib,
python-nifti, python-yaml, python-mpi4py, python-mdp, python-imaging,
pyqt4-dev-tools, python-qt4, python-vtk, python-wxgtk3.0, python-tk,
python-surfer, python-statsmodels
pyqt5-dev-tools, python-pyqt5, python-pyqt5.qtopengl, python-vtk,
python-wxgtk3.0, python-tk, python-surfer, python-statsmodels
Standards-Version: 3.7.3
Homepage: https://vcs.ynic.york.ac.uk/naf
......@@ -16,7 +16,8 @@ Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends},
openmpi-bin, python-h5py, python-numpy, python-scipy, python-matplotlib,
python-nifti, python-yaml, python-mpi4py, python-mdp, python-imaging,
python-qt4, python-vtk, python-wxgtk3.0, python-tk, python-statsmodels
python-pyqt5, python-pyqt5.qtopengl, python-vtk, python-wxgtk3.0, python-tk,
python-statsmodels
Description: NeuroImaging Analysis Framework
YNiC NAF Code
......
......@@ -2,7 +2,12 @@
from numpy import round
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
# Force the user of Qt5 backend in Matplotlib to avoid trying to load both Qt4
# and Qt5 by accident
from matplotlib import rcParams
rcParams['backend'] = 'Qt5Agg'
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.cm import gray
......
#!/usr/bin/python
from PyQt4 import QtGui, QtCore
from PyQt5 import QtWidgets
from naf.gui.qt4.ui.dipoleResultsDialog_ui import Ui_dipoleResultsDialog
from naf.gui.qt.ui.dipoleResultsDialog_ui import Ui_dipoleResultsDialog
__all__ = []
class DipoleResults(QtGui.QDialog, Ui_dipoleResultsDialog):
class DipoleResults(QtWidgets.QDialog, Ui_dipoleResultsDialog):
def __init__(self, parent=None, fit=None, dat=None, config=None):
super(DipoleResults, self).__init__(parent)
self.setupUi(self)
......@@ -15,9 +15,9 @@ class DipoleResults(QtGui.QDialog, Ui_dipoleResultsDialog):
self.dat = dat
self.config = config
self.connect(self.closeButton, QtCore.SIGNAL("clicked()"), self.close)
self.connect(self.exportResultsButton, QtCore.SIGNAL("clicked()"), self.exportResults)
self.connect(self.spaceComboBox, QtCore.SIGNAL("currentIndexChanged(int)"), self.changeSpace)
self.closeButton.clicked.connect(self.close)
self.exportResultsButton.clicked.connect(self.exportResults)
self.spaceComboBox.currentIndexChanged.connect(self.changeSpace)
self.resTextEdit.setReadOnly(True)
self.update_space()
......@@ -26,7 +26,7 @@ class DipoleResults(QtGui.QDialog, Ui_dipoleResultsDialog):
self.show()
def exportResults(self):
QtGui.QMessageBox.critical(self,
QtWidgets.QMessageBox.critical(self,
"Warning",
"Exporting not yet implemented, please copy and paste.")
......
......@@ -5,10 +5,14 @@
from numpy import mod, arctan2, sin, cos, rad2deg, deg2rad, zeros, array, sqrt
from PyQt4 import QtGui
from PyQt5 import QtWidgets
# Force the user of Qt5 backend in Matplotlib to avoid trying to load both Qt4
# and Qt5 by accident
from matplotlib import rcParams
rcParams['backend'] = 'Qt5Agg'
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.lines import Line2D
from matplotlib.widgets import Cursor
......@@ -32,8 +36,8 @@ class TimeSeriesCanvas(FigureCanvas):
self.mpl_connect('button_press_event', self.button_pressed)
self.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding)
self.updateGeometry()
......@@ -280,8 +284,8 @@ class ContourCanvas(FigureCanvas):
self.mpl_connect('pick_event', self.onpick1)
FigureCanvas.setSizePolicy(self,
QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
self.selection = False
......
This diff is collapsed.
......@@ -4,19 +4,18 @@
# This file is part of the NeuroImaging Analysis Framework
# For copyright and redistribution details, please see the COPYING file
from PyQt4 import QtGui
from PyQt4.QtCore import SIGNAL
from PyQt5 import QtWidgets
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from naf.maths.coords import get_merged_lines
from naf.meg.coords import COORD_INTERNAL_MM, COORD_ALIGNED_MM
from naf.meg.readers import OffReader
from naf.gui.vtkutils import ActorSpheresVTK, ActorLinesVTK, ActorVertTriVTK, ActorStructuredPointsVTK
from naf.gui.qt4.ui.coregOptions_ui import Ui_coregOptions
from naf.gui.qt4.ui.sfmOptions_ui import Ui_sfmOptions
from naf.gui.qt.ui.coregOptions_ui import Ui_coregOptions
from naf.gui.qt.ui.sfmOptions_ui import Ui_sfmOptions
class SpheresForwardModelVTK(object):
def __init__(self, transforms, forwardmodel, update_callback=None):
......@@ -145,13 +144,15 @@ class CoregVTKWindow(QVTKRenderWindowInteractor):
self.coreg = CoregVTK(transforms, update_callback=self.update_vtk)
self.sfm = SpheresForwardModelVTK(transforms, forwardmodel, update_callback=self.update_vtk)
style = vtk.vtkInteractorStyleTrackballCamera()
self.SetInteractorStyle(style)
# Disabled until we can rely on Qt 5.6
# (see https://codereview.qt-project.org/#/c/126136/ )
#style = vtk.vtkInteractorStyleTrackballCamera()
#self.SetInteractorStyle(style)
self.coreg.add_all_actors(self.vrenderer)
self.sfm.add_all_actors(self.vrenderer)
class CoregOptions(QtGui.QGroupBox, Ui_coregOptions):
class CoregOptions(QtWidgets.QGroupBox, Ui_coregOptions):
def __init__(self, parent=None):
super(CoregOptions, self).__init__(parent)
......@@ -169,11 +170,11 @@ class CoregOptions(QtGui.QGroupBox, Ui_coregOptions):
self.hsdigToggle.setChecked( self.vtk.coreg.dig_pts.global_visible )
self.hsidxToggle.setChecked( self.vtk.coreg.dig_pts.global_visible )
self.connect( self.scalpToggle, SIGNAL("toggled(bool)"), self.vtk.coreg.scalp.SetVisibility )
self.connect( self.scalpSlider, SIGNAL("valueChanged(int)"), self.scalp_trans )
self.connect( self.hsdigToggle, SIGNAL("toggled(bool)"), self.vtk.coreg.dig_pts.SetVisibility )
self.connect( self.hsidxToggle, SIGNAL("toggled(bool)"), self.vtk.coreg.idx_pts.SetVisibility )
self.connect( self, SIGNAL("toggled(bool)"), self.coreg_toggle )
self.scalpToggle.toggled.connect(self.vtk.coreg.scalp.SetVisibility)
self.scalpSlider.valueChanged.connect(self.scalp_trans)
self.hsdigToggle.toggled.connect(self.vtk.coreg.dig_pts.SetVisibility)
self.hsidxToggle.toggled.connect(self.vtk.coreg.idx_pts.SetVisibility)
self.toggled.connect(self.coreg_toggle)
def scalp_trans(self, value):
value = value / 100.0
......@@ -186,7 +187,7 @@ class CoregOptions(QtGui.QGroupBox, Ui_coregOptions):
self.vtk.coreg.scalp.SetVisibility(value & self.scalpToggle.isChecked())
self.vtk.update()
class SfmOptions(QtGui.QGroupBox, Ui_sfmOptions):
class SfmOptions(QtWidgets.QGroupBox, Ui_sfmOptions):
def __init__(self, parent=None):
super(SfmOptions, self).__init__(parent)
......@@ -208,12 +209,12 @@ class SfmOptions(QtGui.QGroupBox, Ui_sfmOptions):
self.set_current_active(1)
self.connect( self.skullToggle, SIGNAL("toggled(bool)"), self.vtk.sfm.inskull_surface.SetVisibility )
self.connect( self.skullSlider, SIGNAL("sliderMoved(int)"), self.skull_trans )
self.connect( self.sphereToggle, SIGNAL("toggled(bool)"), self.vtk.sfm.spheres.SetVisibility )
self.connect( self.chansToggle, SIGNAL("toggled(bool)"), self.vtk.sfm.coils.SetVisibility )
self.connect( self.sphereSpinbox, SIGNAL("valueChanged(int)"), self.set_current_active )
self.connect( self, SIGNAL("toggled(bool)"), self.fm_toggle )
self.skullToggle.toggled.connect(self.vtk.sfm.inskull_surface.SetVisibility)
self.skullSlider.sliderMoved.connect(self.skull_trans)
self.sphereToggle.toggled.connect(self.vtk.sfm.spheres.SetVisibility)
self.chansToggle.toggled.connect(self.vtk.sfm.coils.SetVisibility)
self.sphereSpinbox.valueChanged.connect(self.set_current_active)
self.toggled.connect(self.fm_toggle)
def fm_toggle(self, value):
self.vtk.sfm.inskull_surface.SetVisibility(value & self.skullToggle.isChecked())
......
......@@ -3,13 +3,13 @@
# This file is part of the NeuroImaging Analysis Framework
# For copyright and redistribution details, please see the COPYING file
from PyQt4 import QtCore
from PyQt5 import QtCore
from subprocess import Popen, PIPE
from naf.gui.qt4.timedthread import TimedThread
from naf.gui.qt4.tablemodel import ListModel
from naf.gui.qt4.jobhandlers import *
from naf.gui.qt.timedthread import TimedThread
from naf.gui.qt.tablemodel import ListModel
from naf.gui.qt.jobhandlers import *
__all__ = []
......@@ -79,10 +79,10 @@ class ExecutionModel(ListModel):
self.update_thread = ExecutionThread(model=self)
self.connect(self.update_thread, QtCore.SIGNAL("lastUpdated(QDateTime, bool)"), self.last_updated)
self.update_thread.lastUpdated.connect(self.last_updated)
def last_updated(self, datetime, changed):
self.emit(QtCore.SIGNAL("lastUpdated(QDateTime, bool)"), datetime, changed)
self.lastUpdated.emit(datetime, changed)
def clear_ended_jobs(self):
# Take a copy as we're going to stomp all over our jobs list
......@@ -101,9 +101,9 @@ class ExecutionModel(ListModel):
jidx = len(self.items) - 1
idx = self.index(jidx, 0)
idx_end = self.index(jidx, self.columnCount()-1)
self.emit(QtCore.SIGNAL("countChanged()"))
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx_end)
self.emit(QtCore.SIGNAL("modelChanged()"))
self.countChanged.emit()
self.dataChanged.emit(idx, idx_end)
self.modelChanged.emit()
finally:
self.lock.unlock()
......@@ -119,7 +119,7 @@ class ExecutionModel(ListModel):
idx = self.index(jidx, 0)
idx_end = self.index(jidx, self.columnCount())
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx_end)
self.dataChanged.emit(idx, idx_end)
retjob = j
break
......@@ -142,7 +142,7 @@ class ExecutionModel(ListModel):
idx = self.index(jidx, 0)
idx_end = self.index(jidx, self.columnCount())
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx_end)
self.dataChanged.emit(idx, idx_end)
except ValueError:
pass
......
......@@ -7,7 +7,7 @@ from os import stat, unlink
from os.path import join, abspath, dirname
from PyQt4 import QtCore
from PyQt5 import QtCore
from naf.meg.coords import COORD_MEG, COORD_INTERNAL_MM, COORD_ALIGNED_MM, COORD_NIFTI_PIX, COORD_NIFTI_MM
......
......@@ -3,13 +3,18 @@
# This file is part of the NeuroImaging Analysis Framework
# For copyright and redistribution details, please see the COPYING file
from PyQt4 import QtCore
from PyQt5 import QtCore
from naf.gui.qt4.timedthread import TimedThread
from naf.gui.qt.timedthread import TimedThread
__all__ = []
class ListModel(QtCore.QAbstractTableModel):
countChanged = QtCore.pyqtSignal()
lastUpdated = QtCore.pyqtSignal(QtCore.QDateTime, int)
forceRefresh = QtCore.pyqtSignal()
modelChanged = QtCore.pyqtSignal()
def __init__(self):
super(ListModel, self).__init__()
......@@ -51,7 +56,7 @@ class ListModel(QtCore.QAbstractTableModel):
self.lock.unlock()
self.emit(QtCore.SIGNAL("countChanged()"))
self.countChanged.emit()
def remove_item(self, item):
self.lock.lockForWrite()
......@@ -69,7 +74,7 @@ class ListModel(QtCore.QAbstractTableModel):
self.lock.unlock()
self.emit(QtCore.SIGNAL("countChanged()"))
self.countChanged.emit()
def clear(self):
self.lock.lockForWrite()
......@@ -80,7 +85,7 @@ class ListModel(QtCore.QAbstractTableModel):
self.lock.unlock()
self.emit(QtCore.SIGNAL("countChanged()"))
self.countChanged.emit()
def rowCount(self, index=QtCore.QModelIndex()):
return len(self.items)
......@@ -153,14 +158,14 @@ class ListModelWithThread(ListModel):
# Create a thread
self.update_thread = ListModelThread(model=self)
self.connect(self.update_thread, QtCore.SIGNAL("finished()"), self.update_thread, QtCore.SLOT("deleteLater()"))
self.connect(self.update_thread, QtCore.SIGNAL("lastUpdated(QDateTime, bool)"), self.last_updated)
self.update_thread.finished.connect(self.update_thread.deleteLater)
self.update_thread.lastUpdated.connect(self.last_updated)
# Note that we don't start the thread, subclasses must do that themselves
# once all initialisation is taken care of
def refresh(self):
self.emit(QtCore.SIGNAL("forceRefresh()"))
self.forceRefresh.emit()
def timer_update(self):
"""Function called by thread to perform updates"""
......@@ -168,7 +173,7 @@ class ListModelWithThread(ListModel):
def last_updated(self, datetime, changed):
"""Function called by thread when an updated has been performed"""
self.emit(QtCore.SIGNAL("lastUpdated(QDateTime, bool)"), datetime, changed)
self.lastUpdated.emit(datetime, changed)
__all__.append('ListModelWithThread')
......@@ -184,7 +189,7 @@ class RemoteJobListModel(ListModelWithThread):
def timer_update(self):
from naf.utils.sgeutils import qstat_jobs
from naf.gui.qt4.jobhandlers import JOB_STATUS_QUEUED, JOB_STATUS_RUNNING, JOB_STATUS_UNKNOWN, JOB_STATUS_ENDED
from naf.gui.qt.jobhandlers import JOB_STATUS_QUEUED, JOB_STATUS_RUNNING, JOB_STATUS_UNKNOWN, JOB_STATUS_ENDED
self.lock.lockForWrite()
......@@ -219,25 +224,25 @@ class RemoteJobListModel(ListModelWithThread):
if j.jobstatus != JOB_STATUS_QUEUED:
j.jobstatus = JOB_STATUS_QUEUED
if idx:
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx)
self.dataChanged.emit(idx, idx)
ret = True
elif ji.state == 'running':
if j.jobstatus != JOB_STATUS_RUNNING:
j.jobstatus = JOB_STATUS_RUNNING
if idx:
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx)
self.dataChanged.emit(idx, idx)
ret = True
else:
if j.jobstatus != JOB_STATUS_UNKNOWN:
j.jobstatus = JOB_STATUS_UNKNOWN
if idx:
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx)
self.dataChanged.emit(idx, idx)
ret = True
else:
if j.jobstatus != JOB_STATUS_ENDED:
j.jobstatus = JOB_STATUS_ENDED
if idx:
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx)
self.dataChanged.emit(idx, idx)
ret = True
finally:
......@@ -252,7 +257,7 @@ class StudyCoregRunModel(ListModelWithThread):
"""Specialised model for watching the state of coregistration files"""
def __init__(self, study=None):
from naf.gui.qt4.jobhandlers import COREG_RUN_ID, COREG_RUN_NAME, COREG_RUN_INDIVIDUAL, COREG_RUN_MNI, COREG_COL_NAMES
from naf.gui.qt.jobhandlers import COREG_RUN_ID, COREG_RUN_NAME, COREG_RUN_INDIVIDUAL, COREG_RUN_MNI, COREG_COL_NAMES
ListModelWithThread.__init__(self)
......@@ -270,14 +275,14 @@ class StudyCoregRunModel(ListModelWithThread):
idx = self.index(ridx, 0)
idx_end = self.index(ridx, self.columnCount()-1)
run.erase_coreg()
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx_end)
self.dataChanged.emit(idx, idx_end)
break
finally:
self.lock.unlock()
def timer_update(self):