changeset 333:dcae6574c974

Increment to qt5
author Windel Bouwman
date Sun, 09 Feb 2014 15:27:57 +0100
parents 87feb8a23b4d
children 6f4753202b9a
files python/ide/astviewer.py python/ide/codeedit.py python/ide/disasm.py python/ide/hexedit.py python/ide/ide.py python/ide/logview.py python/ide/qtwrapper.py python/ide/st-util.py
diffstat 8 files changed, 160 insertions(+), 139 deletions(-) [+]
line wrap: on
line diff
--- a/python/ide/astviewer.py	Fri Feb 07 12:51:55 2014 +0100
+++ b/python/ide/astviewer.py	Sun Feb 09 15:27:57 2014 +0100
@@ -1,13 +1,12 @@
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon
 from ppci.c3 import Visitor, astnodes
 
 class AstModelBuilder:
     def __init__(self):
-      self.functionIco = QIcon(QPixmap('icons/functionicon.png').scaled(32, 32))
-      self.variableIco = QIcon(QPixmap('icons/variableicon.png').scaled(32, 32))
-      self.model = QStandardItemModel()
-      self.model.setHorizontalHeaderLabels(['Object', 'Type'])
+        self.functionIco = get_icon('functionicon.png')
+        self.variableIco = get_icon('variableicon.png')
+        self.model = QtGui.QStandardItemModel()
+        self.model.setHorizontalHeaderLabels(['Object', 'Type'])
 
     def build(self, pkg):
         #self.model.clear()
@@ -28,7 +27,7 @@
       else:
          return
       typ = str(node.typ) if hasattr(node, 'typ') else ''
-      ti = QStandardItem(str(typ))
+      ti = QtGui.QStandardItem(str(typ))
       ti.setData(node)
       i.setData(node)
       self.curItem.appendRow([i, ti])
@@ -38,14 +37,15 @@
       if type(node) in [astnodes.Variable, astnodes.Function, astnodes.Package]:
          self.curItem = self.curItem.parent()
 
+
 # The actual widget:
-class AstViewer(QTreeView):
+class AstViewer(QtWidgets.QTreeView):
     sigNodeSelected = pyqtSignal(object)
     def __init__(self, parent=None):
-      super(AstViewer, self).__init__(parent)
-      self.clicked.connect(self.selectHandler)
-      self.modelBuilder = AstModelBuilder()
-      self.setModel(self.modelBuilder.model)
+        super().__init__(parent)
+        self.clicked.connect(self.selectHandler)
+        self.modelBuilder = AstModelBuilder()
+        self.setModel(self.modelBuilder.model)
 
     def setAst(self, ast):
         """ Create a new model and add all ast elements to it """
@@ -53,11 +53,9 @@
         self.expandAll()
 
     def selectHandler(self, index):
-      if not index.isValid():
-         return
-      model = self.model()
-      item = model.itemFromIndex(index)
-      node = item.data()
-      self.sigNodeSelected.emit(node)
-
-
+        if not index.isValid():
+            return
+        model = self.model()
+        item = model.itemFromIndex(index)
+        node = item.data()
+        self.sigNodeSelected.emit(node)
--- a/python/ide/codeedit.py	Fri Feb 07 12:51:55 2014 +0100
+++ b/python/ide/codeedit.py	Sun Feb 09 15:27:57 2014 +0100
@@ -2,8 +2,7 @@
 
 import sys
 import os
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, Qt, get_icon
 import inspect
 
 GAP = 5
@@ -13,25 +12,25 @@
    if v > mx: return mx
    return v
 
-class InnerCode(QWidget):
+class InnerCode(QtWidgets.QWidget):
     textChanged = pyqtSignal()
     def __init__(self, scrollArea):
       super().__init__(scrollArea)
       self.scrollArea = scrollArea
-      self.setFont(QFont('Courier', 12))
+      self.setFont(QtGui.QFont('Courier', 12))
       self.setFocusPolicy(Qt.StrongFocus)
       # TODO: only beam cursor in text area..
       self.setCursor(Qt.IBeamCursor)
-      h = QFontMetrics(self.font()).height()
-      self.errorPixmap = QPixmap('icons/error.png').scaled(h, h)
-      self.arrowPixmap = QPixmap('icons/arrow.png').scaled(h, h)
+      h = QtGui.QFontMetrics(self.font()).height()
+      self.errorPixmap = get_icon('error.png').scaled(h, h)
+      self.arrowPixmap = get_icon('arrow.png').scaled(h, h)
       self.blinkcursor = False
       self.errorlist = []
       self.arrow = None
       # Initial values:
       self.setSource('')
       self.CursorPosition = 0
-      self.t = QTimer(self)
+      self.t = QtCore.QTimer(self)
       self.t.timeout.connect(self.updateCursor)
       self.t.setInterval(500)
       self.t.start()
@@ -145,11 +144,11 @@
       # Helper variables:
       er = event.rect()
       chw, chh = self.charWidth, self.charHeight
-      painter = QPainter(self)
+      painter = QtGui.QPainter(self)
       # Background:
-      painter.fillRect(er, self.palette().color(QPalette.Base))
-      painter.fillRect(QRect(self.xposLNA, er.top(), 4 * chw, er.bottom() + 1), Qt.gray)
-      errorPen = QPen(Qt.red, 3)
+      painter.fillRect(er, self.palette().color(QtGui.QPalette.Base))
+      painter.fillRect(QtCore.QRect(self.xposLNA, er.top(), 4 * chw, er.bottom() + 1), Qt.gray)
+      errorPen = QtGui.QPen(Qt.red, 3)
       # first and last row:
       row1 = max(int(er.top() / chh) - 1, 1)
       row2 = max(int(er.bottom() / chh) + 1, 1)
@@ -187,27 +186,27 @@
          ypos += chh
 
     def keyPressEvent(self, event):
-      if event.matches(QKeySequence.MoveToNextChar):
+      if event.matches(QtGui.QKeySequence.MoveToNextChar):
          self.GotoNextChar()
-      elif event.matches(QKeySequence.MoveToPreviousChar):
+      elif event.matches(QtGui.QKeySequence.MoveToPreviousChar):
          self.GotoPrevChar()
-      elif event.matches(QKeySequence.MoveToNextLine):
+      elif event.matches(QtGui.QKeySequence.MoveToNextLine):
          self.GotoNextLine()
-      elif event.matches(QKeySequence.MoveToPreviousLine):
+      elif event.matches(QtGui.QKeySequence.MoveToPreviousLine):
          self.GotoPrevLine()
-      elif event.matches(QKeySequence.MoveToNextPage):
+      elif event.matches(QtGui.QKeySequence.MoveToNextPage):
          for i in range(5):
             self.GotoNextLine()
-      elif event.matches(QKeySequence.MoveToPreviousPage):
+      elif event.matches(QtGui.QKeySequence.MoveToPreviousPage):
          for i in range(5):
             self.GotoPrevLine()
-      elif event.matches(QKeySequence.MoveToEndOfLine):
+      elif event.matches(QtGui.QKeySequence.MoveToEndOfLine):
          self.CursorPosition += len(self.CurrentLine) - self.CursorCol + 1
-      elif event.matches(QKeySequence.MoveToStartOfLine):
+      elif event.matches(QtGui.QKeySequence.MoveToStartOfLine):
          self.CursorPosition -= self.CursorCol - 1
-      elif event.matches(QKeySequence.Delete):
+      elif event.matches(QtGui.QKeySequence.Delete):
          self.deleteChar()
-      elif event.matches(QKeySequence.InsertParagraphSeparator):
+      elif event.matches(QtGui.QKeySequence.InsertParagraphSeparator):
          self.insertText('\n')
       elif event.key() == Qt.Key_Backspace:
          self.CursorPosition -= 1
@@ -240,7 +239,7 @@
         self.setMinimumHeight(self.charHeight * len(txt))
         self.update()
 
-class CodeEdit(QScrollArea):
+class CodeEdit(QtWidgets.QScrollArea):
     def __init__(self):
         super().__init__()
         self.ic = InnerCode(self)
@@ -288,4 +287,3 @@
     ce.Source = src
     ce.resize(600, 800)
     app.exec()
-
--- a/python/ide/disasm.py	Fri Feb 07 12:51:55 2014 +0100
+++ b/python/ide/disasm.py	Sun Feb 09 15:27:57 2014 +0100
@@ -1,9 +1,8 @@
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
 import binascii
+from qtwrapper import QtGui, QtCore, QtWidgets, Qt
 
 
-class DisAsmModel(QAbstractTableModel):
+class DisAsmModel(QtCore.QAbstractTableModel):
     def __init__(self):
         super().__init__()
         self.outs = None
@@ -16,7 +15,7 @@
 
     def rowCount(self, parent):
         return len(self.instructions)
-        
+
     def columnCount(self, parent):
         return len(self.headers)
 
@@ -31,13 +30,13 @@
     def headerData(self, section, orientation, role):
         if orientation == Qt.Horizontal and role == Qt.DisplayRole:
             return self.headers[section]
-            
+
     def setInstructions(self, ins):
         self.instructions = ins
         self.modelReset.emit()
-    
+
 
-class Disassembly(QTableView):
+class Disassembly(QtWidgets.QTableView):
     def __init__(self):
         super().__init__()
         self.dm = DisAsmModel()
--- a/python/ide/hexedit.py	Fri Feb 07 12:51:55 2014 +0100
+++ b/python/ide/hexedit.py	Sun Feb 09 15:27:57 2014 +0100
@@ -2,9 +2,8 @@
 
 import sys
 import os
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from PyQt4 import uic
+from qtwrapper import QtGui, QtCore, QtWidgets, Qt
+
 
 BYTES_PER_LINE, GAP = 8, 12
 
@@ -17,25 +16,27 @@
    else:
       return chr(v)
 
-class BinViewer(QWidget):
+class BinViewer(QtWidgets.QWidget):
    """ The view has an address, hex byte and ascii column """
    def __init__(self, scrollArea):
       super().__init__(scrollArea)
       self.scrollArea = scrollArea
-      self.setFont(QFont('Courier', 16))
+      self.setFont(QtGui.QFont('Courier', 16))
       self.setFocusPolicy(Qt.StrongFocus)
       self.blinkcursor = False
       self.cursorX = self.cursorY = 0
       self.scrollArea = scrollArea
       self.Data = bytearray()
       self.Offset = 0
-      t = QTimer(self)
+      t = QtCore.QTimer(self)
       t.timeout.connect(self.updateCursor)
       t.setInterval(500)
       t.start()
+
    def updateCursor(self):
       self.blinkcursor = not self.blinkcursor
       self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight)
+
    def setCursorPosition(self, position):
       position = clamp(0, int(position), len(self.Data) * 2 - 1)
       self.cursorPosition = position
@@ -46,21 +47,23 @@
       self.cursorY = y * self.charHeight + 2
       self.blinkcursor = True
       self.update()
+
    def getCursorPosition(self):
       return self.cursorPosition
    CursorPosition = property(getCursorPosition, setCursorPosition)
    def setOffset(self, off):
       self.offset = off
       self.update()
+
    Offset = property(lambda self: self.offset, setOffset)
    def paintEvent(self, event):
       # Helper variables:
       er = event.rect()
       chw, chh = self.charWidth, self.charHeight
-      painter = QPainter(self)
+      painter = QtGui.QPainter(self)
       # Background:
-      painter.fillRect(er, self.palette().color(QPalette.Base))
-      painter.fillRect(QRect(self.xposAddr, er.top(), 8 * chw, er.bottom() + 1), Qt.gray)
+      painter.fillRect(er, self.palette().color(QtGui.QPalette.Base))
+      painter.fillRect(QtCore.QRect(self.xposAddr, er.top(), 8 * chw, er.bottom() + 1), Qt.gray)
       painter.setPen(Qt.gray)
       x = self.xposAscii - (GAP / 2)
       painter.drawLine(x, er.top(), x, er.bottom())
@@ -94,6 +97,7 @@
       # cursor
       if self.blinkcursor:
          painter.fillRect(self.cursorX, self.cursorY + chh - 2, chw, 2, Qt.black)
+
    def keyPressEvent(self, event):
       if event.matches(QKeySequence.MoveToNextChar):
          self.CursorPosition += 1
@@ -122,14 +126,17 @@
          self.CursorPosition += 1
       self.scrollArea.ensureVisible(self.cursorX, self.cursorY + self.charHeight / 2, 4, self.charHeight / 2 + 4)
       self.update()
+
    def setCursorPositionAt(self, pos):
       """ Calculate cursor position at a certain point """
       if pos.x() > self.xposHex and pos.x() < self.xposAscii:
          x = round((2 * (pos.x() - self.xposHex)) / (self.charWidth * 3))
          y = int(pos.y() / self.charHeight) * 2 * BYTES_PER_LINE
          self.setCursorPosition(x + y)
+
    def mousePressEvent(self, event):
       self.setCursorPositionAt(event.pos())
+
    def adjust(self):
       self.charHeight = self.fontMetrics().height()
       self.charWidth = self.fontMetrics().width('x')
@@ -146,9 +153,11 @@
       self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + r) * self.charHeight + 4)
       self.scrollArea.setMinimumHeight(self.charHeight * 8)
       self.update()
+
    def showEvent(self, e):
       self.adjust()
       super().showEvent(e)
+
    def setData(self, d):
       self.data = bytearray(d)
       self.originalData = bytearray(d)
@@ -156,7 +165,8 @@
       self.setCursorPosition(0)
    Data = property(lambda self: self.data, setData)
 
-class HexEdit(QScrollArea):
+
+class HexEdit(QtWidgets.QScrollArea):
    def __init__(self):
       super().__init__()
       self.bv = BinViewer(self)
@@ -165,7 +175,8 @@
       self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
       self.setFocusPolicy(Qt.NoFocus)
 
-class HexEditor(QMainWindow):
+
+class HexEditor(QtWidgets.QMainWindow):
    def __init__(self):
       super().__init__()
       basedir = os.path.dirname(__file__)
@@ -198,10 +209,10 @@
          self.fileName = filename
       self.updateControls()
 
+
 if __name__ == '__main__':
    app = QApplication(sys.argv)
    he = HexEditor()
    he.show()
    #he.bv.Data = bytearray(range(100)) * 8 + b'x'
    app.exec()
-
--- a/python/ide/ide.py	Fri Feb 07 12:51:55 2014 +0100
+++ b/python/ide/ide.py	Sun Feb 09 15:27:57 2014 +0100
@@ -6,8 +6,7 @@
 import traceback
 import io
 
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon, abspath, Qt
 
 # Compiler imports:
 p = os.path.join(os.path.dirname(__file__), '..')
@@ -30,18 +29,18 @@
     for i in tb:
         logging.critical(i.strip())
 
-sys.excepthook = handle_exception
+# sys.excepthook = handle_exception
 
-class BuildErrors(QTreeView):
+class BuildErrors(QtWidgets.QTreeView):
     sigErrorSelected = pyqtSignal(object)
 
     def __init__(self, parent=None):
         super(BuildErrors, self).__init__(parent)
-        model = QStandardItemModel()
+        model = QtGui.QStandardItemModel()
         self.setModel(model)
         self.clicked.connect(self.itemSelected)
-        self.errorIcon = QIcon('icons/error.png')
-        self.model = QStandardItemModel()
+        self.errorIcon = get_icon('error.png')
+        self.model = QtGui.QStandardItemModel()
         self.model.setHorizontalHeaderLabels(['Message', 'Row', 'Column'])
         self.header().setStretchLastSection(True)
         self.setModel(self.model)
@@ -50,13 +49,13 @@
         c = self.model.rowCount()
         self.model.removeRows(0, c)
         for e in errorlist:
-            item = QStandardItem(self.errorIcon, str(e.msg))
+            item = QtGui.QStandardItem(self.errorIcon, str(e.msg))
             item.setData(e)
             row = str(e.loc.row) if e.loc else ''
-            irow = QStandardItem(row)
+            irow = QtGui.QStandardItem(row)
             irow.setData(e)
             col = str(e.loc.col) if e.loc else ''
-            icol = QStandardItem(col)
+            icol = QtGui.QStandardItem(col)
             icol.setData(e)
             self.model.appendRow([item, irow, icol])
         for i in range(3):
@@ -71,31 +70,31 @@
 
 
 
-class AboutDialog(QDialog):
+class AboutDialog(QtWidgets.QDialog):
     def __init__(self, parent=None):
         super(AboutDialog, self).__init__(parent)
         self.setWindowTitle('About')
-        l = QVBoxLayout(self)
-        txt = QTextEdit(self)
+        l = QtWidgets.QVBoxLayout(self)
+        txt = QtWidgets.QTextEdit(self)
         txt.setReadOnly(True)
-        with open(os.path.join('..', '..', 'readme.rst'), 'r') as f:
+        with open(abspath(os.path.join('..', '..', 'readme.rst')), 'r') as f:
             aboutText = f.read()
         txt.append(aboutText)
         l.addWidget(txt)
-        but = QPushButton('OK')
+        but = QtWidgets.QPushButton('OK')
         but.setDefault(True)
         but.clicked.connect(self.close)
         l.addWidget(but)
 
 
-class Ide(QMainWindow):
+class Ide(QtWidgets.QMainWindow):
     def __init__(self, parent=None):
         super(Ide, self).__init__(parent)
         self.to_open_files = []
         self.logger = logging.getLogger('ide')
 
         self.setWindowTitle('LCFOS IDE')
-        icon = QIcon('icons/logo.png')
+        icon = QtGui.QIcon(get_icon('logo.png'))
         self.setWindowIcon(icon)
 
         # Create menus:
@@ -105,15 +104,15 @@
         self.helpMenu = mb.addMenu('Help')
 
         # Create mdi area:
-        self.mdiArea = QMdiArea()
-        self.mdiArea.setViewMode(QMdiArea.TabbedView)
+        self.mdiArea = QtWidgets.QMdiArea()
+        self.mdiArea.setViewMode(QtWidgets.QMdiArea.TabbedView)
         self.mdiArea.setTabsClosable(True)
         self.mdiArea.setTabsMovable(True)
         self.setCentralWidget(self.mdiArea)
 
         # Create components:
         def addComponent(name, widget):
-            dw = QDockWidget(name)
+            dw = QtWidgets.QDockWidget(name)
             dw.setWidget(widget)
             dw.setObjectName(name)
             self.addDockWidget(Qt.RightDockWidgetArea, dw)
@@ -145,20 +144,20 @@
 
         # Create actions:
         def addMenuEntry(name, menu, callback, shortcut=None):
-            a = QAction(name, self)
+            a = QtWidgets.QAction(name, self)
             menu.addAction(a)
             a.triggered.connect(callback)
             if shortcut:
-                a.setShortcut(shortcut)
+                a.setShortcut(QtGui.QKeySequence(shortcut))
 
-        addMenuEntry("New", self.fileMenu, self.newFile, shortcut=QKeySequence(QKeySequence.New))
-        addMenuEntry("Open", self.fileMenu, self.openFile, shortcut=QKeySequence(QKeySequence.Open))
-        addMenuEntry("Save", self.fileMenu, self.saveFile, shortcut=QKeySequence(QKeySequence.Save))
-        addMenuEntry("Build", self.fileMenu, self.buildFile, shortcut=QKeySequence("F7"))
-        addMenuEntry("Build and flash", self.fileMenu, self.buildFileAndFlash, shortcut=QKeySequence("F8"))
+        addMenuEntry("New", self.fileMenu, self.newFile, shortcut=QtGui.QKeySequence.New)
+        addMenuEntry("Open", self.fileMenu, self.openFile, shortcut=QtGui.QKeySequence.Open)
+        addMenuEntry("Save", self.fileMenu, self.saveFile, shortcut=QtGui.QKeySequence.Save)
+        addMenuEntry("Build", self.fileMenu, self.buildFile, shortcut="F7")
+        addMenuEntry("Build and flash", self.fileMenu, self.buildFileAndFlash, shortcut="F8")
 
-        self.helpAction = QAction('Help', self)
-        self.helpAction.setShortcut(QKeySequence('F1'))
+        self.helpAction = QtWidgets.QAction('Help', self)
+        self.helpAction.setShortcut(QtGui.QKeySequence('F1'))
         self.helpMenu.addAction(self.helpAction)
         addMenuEntry('About', self.helpMenu, self.aboutDialog.open)
 
@@ -167,7 +166,7 @@
         sb = self.statusBar()
 
         # Load settings:
-        self.settings = QSettings('windelsoft', 'lcfoside')
+        self.settings = QtCore.QSettings('windelsoft', 'lcfoside')
         self.loadSettings()
         self.diag = ppci.DiagnosticsManager()
 
@@ -176,10 +175,10 @@
         self.newCodeEdit()
 
     def openFile(self):
-        filename = QFileDialog.getOpenFileName(self, "Open C3 file...", "*.c3",
+        filename = QtWidgets.QFileDialog.getOpenFileName(self, "Open C3 file...", "*.c3",
                     "C3 source files (*.c3)")
         if filename:
-            self.loadFile(filename)
+            self.loadFile(filename[0])
 
     def saveFile(self):
         ac = self.activeMdiChild()
@@ -193,7 +192,7 @@
                 ce.Source = f.read()
                 ce.FileName = filename
         except Exception as e:
-            print('exception opening file', e)
+            print('exception opening file:', e)
 
     # MDI:
     def newCodeEdit(self):
@@ -314,8 +313,8 @@
 
 
 if __name__ == '__main__':
-    logging.basicConfig(format=zcc.logformat, level=logging.DEBUG)
-    app = QApplication(sys.argv)
+    logging.basicConfig(format=ppci.logformat, level=logging.DEBUG)
+    app = QtWidgets.QApplication(sys.argv)
     ide = Ide()
     ide.show()
     ide.logger.info('IDE started')
--- a/python/ide/logview.py	Fri Feb 07 12:51:55 2014 +0100
+++ b/python/ide/logview.py	Sun Feb 09 15:27:57 2014 +0100
@@ -5,16 +5,14 @@
 import logging
 import datetime
 
-from PyQt4.QtGui import QApplication, QWidget, QTableView, QVBoxLayout
-from PyQt4.QtGui import QHeaderView
-from PyQt4.QtCore import Qt
-from PyQt4.QtCore import QAbstractTableModel
+from qtwrapper import QtGui, QtCore, QtWidgets, Qt
 
 def formatTime(t):
     t2 = datetime.datetime.fromtimestamp(t)
     return t2.strftime('%H:%M:%S')
 
-class LogModel(QAbstractTableModel):
+
+class LogModel(QtCore.QAbstractTableModel):
     def __init__(self):
         super().__init__()
         self.entries = []
@@ -27,7 +25,7 @@
 
     def rowCount(self, parent):
         return len(self.entries)
-        
+
     def columnCount(self, parent):
         return len(self.headers)
 
@@ -42,23 +40,23 @@
     def headerData(self, section, orientation, role):
         if orientation == Qt.Horizontal and role == Qt.DisplayRole:
             return self.headers[section]
-            
+
     def newLog(self, x):
         self.entries.append(x)
         self.modelReset.emit()
 
 
-class LogView(QWidget):
+class LogView(QtWidgets.QWidget):
     """ Log view component """
     def __init__(self, parent=None):
         super().__init__(parent)
-        l = QVBoxLayout(self)
-        self.tv = QTableView(self)
+        l = QtWidgets.QVBoxLayout(self)
+        self.tv = QtWidgets.QTableView(self)
         self.tv.horizontalHeader().setStretchLastSection(True)
         l.addWidget(self.tv)
         self.lm = LogModel()
         self.tv.setModel(self.lm)
-    
+
         class MyHandler(logging.Handler):
             def emit(self2, x):
                 self.lm.newLog(x)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ide/qtwrapper.py	Sun Feb 09 15:27:57 2014 +0100
@@ -0,0 +1,11 @@
+import os
+from PyQt5 import QtCore, QtGui, QtWidgets
+from PyQt5.QtCore import pyqtSignal, Qt
+
+def abspath(filename):
+    script_path = os.path.abspath(os.path.dirname(__file__))
+    return os.path.join(script_path, filename)
+
+def get_icon(filename):
+    return QtGui.QPixmap(abspath(os.path.join('icons', filename)))
+
--- a/python/ide/st-util.py	Fri Feb 07 12:51:55 2014 +0100
+++ b/python/ide/st-util.py	Sun Feb 09 15:27:57 2014 +0100
@@ -1,14 +1,13 @@
 #!/usr/bin/python
 
 import sys
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from qtwrapper import QtGui, QtCore, QtWidgets, pyqtSignal, get_icon, Qt
 import stlink, devices, stm32, usb
 from devices import Interface, Device
 from hexedit import HexEdit
 
 
-class InformationDialog(QDialog):
+class InformationDialog(QtWidgets.QDialog):
    def __init__(self, parent):
       super().__init__(parent)
       self.setWindowTitle('Info')
@@ -20,7 +19,7 @@
          fl.addRow('Status:', QLabel(parent.stl.StatusString))
 
 
-class RegisterModel(QAbstractTableModel):
+class RegisterModel(QtCore.QAbstractTableModel):
     def __init__(self):
       super().__init__()
       self.regCount = 15
@@ -85,7 +84,7 @@
          self.dataChanged.emit(fromIndex, toIndex)
 
 
-class RegisterView(QTableView):
+class RegisterView(QtWidgets.QTableView):
     def __init__(self):
       super().__init__()
       self.mdl = RegisterModel()
@@ -97,20 +96,20 @@
       self.mdl.refresh()
 
 
-class MemoryView(QWidget):
+class MemoryView(QtWidgets.QWidget):
     BlockSize = 0x100
     def __init__(self):
       super().__init__()
-      l = QVBoxLayout(self)
-      l2 = QHBoxLayout()
-      l2.addWidget(QLabel('Address'))
-      self.addressLine = QLineEdit()
+      l = QtWidgets.QVBoxLayout(self)
+      l2 = QtWidgets.QHBoxLayout()
+      l2.addWidget(QtWidgets.QLabel('Address'))
+      self.addressLine = QtWidgets.QLineEdit()
       self.addressLine.setInputMask('Hhhhhhhh')
       l2.addWidget(self.addressLine)
-      upButton = QPushButton('up')
+      upButton = QtWidgets.QPushButton('up')
       l2.addWidget(upButton)
       upButton.clicked.connect(self.doUp)
-      downButton = QPushButton('down')
+      downButton = QtWidgets.QPushButton('down')
       downButton.clicked.connect(self.doDown)
       l2.addWidget(downButton)
       l.addLayout(l2)
@@ -148,15 +147,16 @@
       self.Address = 0x8000000
 
 
-class DebugToolbar(QToolBar):
-   statusChange = pyqtSignal()
-   codePosition = pyqtSignal(int)
-   def __init__(self):
+class DebugToolbar(QtWidgets.QToolBar):
+    statusChange = pyqtSignal()
+    codePosition = pyqtSignal(int)
+
+    def __init__(self):
       super().__init__()
       self.device = None
       # generate actions:
       def genAction(name, callback):
-         a = QAction(name, self)
+         a = QtWidgets.QAction(name, self)
          a.triggered.connect(callback)
          self.addAction(a)
          return a
@@ -166,7 +166,8 @@
       self.resetAction = genAction('Reset', self.doReset)
       self.enableTraceAction = genAction('Enable trace', self.doEnableTrace)
       self.updateEnables()
-   def updateEnables(self):
+
+    def updateEnables(self):
       if self.device:
          self.resetAction.setEnabled(True)
          self.enableTraceAction.setEnabled(True)
@@ -184,37 +185,43 @@
          self.runAction.setEnabled(False)
          self.stepAction.setEnabled(False)
          self.stopAction.setEnabled(False)
-   def doStep(self):
+
+    def doStep(self):
       self.device.iface.step()
       self.updateEnables()
-   def doReset(self):
+
+    def doReset(self):
       self.device.iface.reset()
       self.updateEnables()
-   def doRun(self):
+
+    def doRun(self):
       self.device.iface.run()
       self.updateEnables()
-   def doHalt(self):
+
+    def doHalt(self):
       self.device.iface.halt()
       self.updateEnables()
-   def doEnableTrace(self):
+
+    def doEnableTrace(self):
       self.device.iface.traceEnable()
       self.updateEnables()
-   def setDevice(self, dev):
+
+    def setDevice(self, dev):
       self.device = dev
       self.updateEnables()
 
 
-class FlashTool(QWidget):
+class FlashTool(QtWidgets.QWidget):
    def __init__(self):
       super().__init__()
       # TODO!
 
 
-class DeviceTreeModel(QAbstractItemModel):
+class DeviceTreeModel(QtCore.QAbstractItemModel):
    def __init__(self):
       super().__init__()
-      self.chipPixmap = QPixmap('icons/chip.png').scaled(32, 32)
-      self.hardwarePixmap = QPixmap('icons/hardware.png').scaled(32, 32)
+      self.chipPixmap = get_icon('chip.png').scaled(32, 32)
+      self.hardwarePixmap = get_icon('hardware.png').scaled(32, 32)
       self.refresh()
    def refresh(self):
       """ Check all usb interfaces for interfaces """
@@ -271,7 +278,7 @@
             if isinstance(ip, Device):
                return self.chipPixmap
 
-class DeviceExplorer(QTreeView):
+class DeviceExplorer(QtWidgets.QTreeView):
    """ Lists all interfaces plugged in and allows selection """
    deviceSelected = pyqtSignal(Device)
    def __init__(self):
@@ -320,7 +327,7 @@
       menu.exec(self.mapToGlobal(pt))
 
 
-class StUtil(QMainWindow):
+class StUtil(QtWidgets.QMainWindow):
    connected = pyqtSignal(bool)
    def __init__(self):
       super().__init__()