Show
Ignore:
Timestamp:
09/04/08 15:44:34 (19 months ago)
Author:
stefan
Message:

initial changes

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • nodebox/branches/try-qt-graphics-view/nodebox/gui/qt/__init__.py

    r286 r486  
    77import random 
    88 
    9 from PyQt4.QtGui import QApplication, QWidget, QColor, QPainter, QMenuBar, QMenu, QKeySequence, QTextEdit, QSplitter, QGridLayout, QDialog, QScrollArea, QFont, QTextCharFormat, QFileDialog, QTextCursor, QPixmap, QPrinter, QImage, QMainWindow 
    10 from PyQt4.QtCore import Qt, SIGNAL, SLOT, pyqtSignature, QTimer, QRectF, QSize, QCoreApplication, QSettings, QVariant 
     9from PyQt4.QtGui import * 
     10from PyQt4.QtCore import * 
    1111from PyQt4.QtSvg import QSvgGenerator 
    12  
    13 from nodebox.gui.qt.editor import PythonHighlighter, CodeEdit, loadConfig 
    14  
    15 MAGICVAR = "__magic_var__" 
     12from PyQt4.QtOpenGL import QGLWidget, QGLFormat, QGL 
     13 
     14from nodebox.gui.qt.ValueLadder import MAGICVAR 
     15from nodebox.gui.qt.pytextview import PythonHighlighter, PyTextView, loadConfig, Config 
     16from nodebox.gui.qt.dashboard import DashboardController 
    1617 
    1718from nodebox import graphics 
     
    3233        self.data.append((self.isErr, data)) 
    3334 
    34 class NodeBoxGraphicsView(QWidget): 
    35  
     35class GraphicsScene(QGraphicsScene): 
    3636    def __init__(self, parent=None): 
    37         QWidget.__init__(self, parent) 
    38         self.setMinimumSize(300, 300) 
     37        QGraphicsScene.__init__(self, parent) 
     38        self.num = 0 
     39 
     40    def addItem(self, item): 
     41        item.setZValue(self.num) 
     42        QGraphicsScene.addItem(self, item) 
     43        self.num += 1 
     44 
     45    def removeItem(self, item): 
     46        QGraphicsScene.removeItem(self, item) 
     47        self.num -= 1 
     48 
     49    def clear(self): 
     50        try: 
     51            QGraphicsScene.clear(self) 
     52        except AttributeError: 
     53            for item in self.items(): 
     54                QGraphicsScene.removeItem(self, item)  
     55        self.num = 0 
     56         
     57    def drawItems(self, painter, items, options, widget): 
     58        painter.setClipRect(self.sceneRect()) 
     59        QGraphicsScene.drawItems(self, painter, items, options, widget) 
     60         
     61class NodeBoxGraphicsView(QGraphicsView): 
     62    zoomLevels = [0.1, 0.25, 0.5, 0.75] 
     63    zoom = 1.0 
     64    while zoom <= 20.0: 
     65        zoomLevels.append(zoom) 
     66        zoom += 1.0 
     67 
     68    def __init__(self, parent=None): 
     69        QGraphicsView.__init__(self) 
     70        self.setAlignment(Qt.AlignLeft | Qt.AlignTop) 
     71        self._scene = GraphicsScene(self) 
     72        self.setScene(self._scene) 
     73        self._scene.setSceneRect(0,0,1000,1000) 
     74        self._scene.setItemIndexMethod(QGraphicsScene.NoIndex) 
    3975        self._canvas = None 
    4076        self._image = None 
    4177        self._dirty = True 
    42          
     78        self._zoom = 1.0 
     79        self._dx = 0 
     80        self._dy = 0 
     81        self._mouseDown = False 
     82         
     83    def scrollContentsBy(self, dx, dy): 
     84        self._dx -= dx 
     85        self._dy -= dy 
     86        QGraphicsView.scrollContentsBy(self, dx, dy) 
     87 
     88    def mousePressEvent(self, event): 
     89        if event.button() == Qt.LeftButton: 
     90            self._mouseDown = True 
     91 
     92    def mouseReleaseEvent(self, event): 
     93        if event.button() == Qt.LeftButton: 
     94            self._mouseDown = False 
     95 
     96    def mousePosition(self): 
     97        pos = self.mapFromGlobal(QCursor.pos()) 
     98        return QPoint(pos.x() + self._dx, pos.y() + self._dy) 
     99     
    43100    def _get_canvas(self): 
    44101        return self._canvas 
    45102    def _set_canvas(self, canvas): 
    46103        self._canvas = canvas 
    47         size = self.width(), self.height() 
    48         if size != self.canvas.size: 
    49             self.resize(*self.canvas.size) 
    50104        self.markDirty() 
    51105    canvas = property(_get_canvas, _set_canvas) 
    52          
     106 
     107    def _get_zoom(self): 
     108        return self._zoom 
     109    def _set_zoom(self, zoom): 
     110        self._zoom = zoom 
     111        self.document.zoomLevel.setText("%i%%" % (self._zoom * 100.0)) 
     112        self.document.zoomSlider.setValue(self._zoom * 100.0) 
     113        transform = QTransform() 
     114        transform.scale(self.zoom, self.zoom) 
     115        self.setTransform( transform) 
     116    zoom = property(_get_zoom, _set_zoom) 
     117 
     118    def findNearestZoomIndex(self, zoom): 
     119        """Returns the nearest zoom level, and whether we found a direct, exact 
     120        match or a fuzzy match.""" 
     121        try: # Search for a direct hit first. 
     122            idx = self.zoomLevels.index(zoom) 
     123            return idx, True 
     124        except ValueError: # Can't find the zoom level, try looking at the indexes. 
     125            idx = 0 
     126            try: 
     127                while self.zoomLevels[idx] < zoom: 
     128                    idx += 1 
     129            except KeyError: # End of the list 
     130                idx = len(self.zoomLevels) - 1 # Just return the last index. 
     131            return idx, False 
     132 
     133    def zoomIn_(self): 
     134        idx, direct = self.findNearestZoomIndex(self.zoom) 
     135        # Direct hits are perfect, but indirect hits require a bit of help. 
     136        # Because of the way indirect hits are calculated, they are already 
     137        # rounded up to the upper zoom level; this means we don't need to add 1. 
     138        if direct: 
     139            idx += 1 
     140        idx = max(min(idx, len(self.zoomLevels)-1), 0) 
     141        self.zoom = self.zoomLevels[idx] 
     142 
     143    def zoomOut_(self): 
     144        idx, direct = self.findNearestZoomIndex(self.zoom) 
     145        idx -= 1 
     146        idx = max(min(idx, len(self.zoomLevels)-1), 0) 
     147        self.zoom = self.zoomLevels[idx] 
     148 
     149    def zoomTo_(self, value): 
     150        self.zoom = value 
     151 
     152    def zoomToFit_(self): 
     153        w, h = self.canvas.size 
     154        viewport = self.viewport() 
     155        fw = viewport.width() 
     156        fh = viewport.height() 
     157        factor = min(fw / float(w), fh / float(h)) 
     158        self.zoom = factor         
     159 
     160    def dragZoom_(self, value): 
     161        self.zoom = value / 100.0 
     162 
    53163    def markDirty(self, redraw=True): 
    54164        self._dirty = True 
    55165        if redraw: 
    56             self.repaint() 
    57              
     166            self._updateImage() 
     167 
    58168    def _updateImage(self): 
    59         self._image = None 
    60169        if self.canvas is None: return 
    61         img = QPixmap(self.canvas.width, self.canvas.height) 
    62         p = QPainter(img) 
    63         p.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing) 
    64         p.setClipRect(QRectF(0, 0, self.canvas.width, self.canvas.height)) 
    65170        try: 
    66             self.canvas.draw(p) 
     171            self._scene.clear() 
     172            if self._scene.width() != self.canvas.width or self._scene.height() != self.canvas.height: 
     173                self._scene.setSceneRect(QRectF(0, 0, self.canvas.width, self.canvas.height)) 
     174            self.canvas._scene = self._scene 
     175            self.canvas.draw() 
     176            self._scene.update() 
    67177        except: 
    68178            # A lot of code just to display the error in the output view. 
     
    75185            outputView.setTextColor(QColor(255, 0, 0)) # TODO: Refactor color 
    76186            outputView.insertPlainText(data) 
    77         finally: 
    78             p.end() # TODO: This doesn't fix the QWidget warning if error happens during drawing. 
    79         self._image = img 
    80          
    81     def paintEvent(self, event): 
    82         p = QPainter(self) 
    83         p.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing) 
    84         if self.canvas is None: 
    85             p.fillRect(0, 0, self.width(), self.height(), QColor(Qt.white)) 
    86         else: 
    87             if self._dirty: 
    88                 self._updateImage() 
    89             p.drawPixmap(0, 0, self._image) 
    90187         
    91188class NodeBoxDocument(QMainWindow): 
     
    98195        self.namespace = {} 
    99196        self.canvas = graphics.Canvas() 
     197        textScaleFactor = QPixmap().logicalDpiX() / 72.0 
     198        self.canvas._setTextScaleFactor(textScaleFactor) 
    100199        self.context = graphics.Context(self.canvas, self.namespace) 
    101200        self.animationTimer = None 
     
    110209 
    111210    def createMenu(self): 
    112         #self.menuBar = QMenuBar() 
    113  
    114211        self.fileMenu = QMenu(self.tr("&File"), self) 
    115212        self.fileMenu.addAction(self.tr("&New"), self, SLOT("doNew()"), QKeySequence("Ctrl+N")) 
     
    134231        self.editMenu.addAction(self.tr("&Redo"), self.codeView, SLOT("redo()"), QKeySequence("Ctrl+Shift+Z")) 
    135232        self.editMenu.addSeparator() 
     233        self.editMenu.addAction(self.tr("&Switch Viewport"), self, SLOT("switchViewport()"), QKeySequence("Ctrl+Shift+P")) 
    136234        self.menuBar().addMenu(self.editMenu) 
     235 
     236        self.viewMenu = QMenu(self.tr("&View"), self) 
     237        self.viewMenu.addAction(self.tr("Zoom &In"), self, SLOT("zoomIn_()"), QKeySequence("Ctrl++")) 
     238        self.viewMenu.addAction(self.tr("Zoom &Out"), self, SLOT("zoomOut_()"), QKeySequence("Ctrl+-")) 
     239        self.zoomToMenu = QMenu(self.tr("Zoom to"), self) 
     240        self.zoomToMenu.addAction(self.tr("To &Fit"), self, SLOT("zoomToFit_()"), QKeySequence("Ctrl+0")) 
     241        self.zoomToMenu.addAction(self.tr("Actual &Size"), self, SLOT("zoomTo100_()"), QKeySequence("Ctrl+1")) 
     242        self.zoomToMenu.addAction(self.tr("200%"), self, SLOT("zoomTo200_()"), QKeySequence("Ctrl+2")) 
     243        self.zoomToMenu.addAction(self.tr("300%"), self, SLOT("zoomTo300_()"), QKeySequence("Ctrl+3")) 
     244        self.zoomToMenu.addAction(self.tr("400%"), self, SLOT("zoomTo400_()"), QKeySequence("Ctrl+4")) 
     245        self.zoomToMenu.addAction(self.tr("50%"), self, SLOT("zoomTo50_()"), QKeySequence("Ctrl+5")) 
     246        self.viewMenu.addMenu(self.zoomToMenu) 
     247        self.menuBar().addMenu(self.viewMenu) 
    137248 
    138249        self.pythonMenu = QMenu(self.tr("&Python"), self) 
    139250        self.runAction = self.pythonMenu.addAction(self.tr("&Run"), self, SLOT("doRun()"), QKeySequence("Ctrl+R")) 
    140         self.runAction = self.pythonMenu.addAction(self.tr("&Stop"), self, SLOT("doStop()"), QKeySequence("Ctrl+.")) 
     251        self.runAction = self.pythonMenu.addAction(self.tr("&Stop"), self, SLOT("doStop()"), QKeySequence("Ctrl+B")) 
    141252        self.menuBar().addMenu(self.pythonMenu) 
    142253 
     
    164275        codeFormat.setFont(codeFont) 
    165276         
    166         self.graphicsView = NodeBoxGraphicsView() 
     277        global app 
     278        self.graphicsView = NodeBoxGraphicsView(self) 
    167279        self.graphicsView.document = self 
    168         self.graphicsView.resize(1000, 1000) 
    169         self.graphicsScroll = QScrollArea() 
    170         self.graphicsScroll.setWidget(self.graphicsView) 
    171         self.graphicsScroll.setMinimumSize(300, 300) 
    172         self.codeView = CodeEdit() 
     280        self.graphicsView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 
     281        self.graphicsView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 
     282        if app._startgl: 
     283            self.graphicsView.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers | QGL.AlphaChannel))) 
     284            self.graphicsView.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) 
     285            self._oldViewport = "qwidget" 
     286        else: 
     287            self.graphicsView.setViewport(QWidget()) 
     288            self.graphicsView.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate) 
     289            self._oldViewport = "qglwidget"             
     290        self.graphicsView.setOptimizationFlags(QGraphicsView.DontClipPainter | QGraphicsView.DontSavePainterState) 
     291         
     292        self.codeView = PyTextView() 
     293        self.codeView._document = self 
    173294        self.codeView.setFontFamily(codeFont.defaultFamily()) 
    174295        self.codeView.setCurrentFont(codeFont) 
     
    176297        self.codeView.setMinimumSize(300, 300) 
    177298        self.codeView.setAcceptRichText(False) 
     299        self.codeView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 
     300        self.codeView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 
    178301        PythonHighlighter(self.codeView.document()) 
    179302        self.outputView = QTextEdit() 
     
    184307        self.outputView.setAcceptRichText(False) 
    185308        self.outputView.setReadOnly(True) 
    186          
     309        self.outputView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 
     310 
    187311        self.code_errors = QSplitter(Qt.Vertical) 
    188312        self.code_errors.addWidget(self.codeView) 
    189313        self.code_errors.addWidget(self.outputView) 
    190314 
     315        self.zoomLevel = QLabel("100%") 
     316        ft = self.zoomLevel.font() 
     317        ft.setPointSizeF(10) 
     318        self.zoomLevel.setFont(ft) 
     319        self.zoomSlider = QSlider(Qt.Horizontal) 
     320        self.zoomSlider.setMinimumWidth(130) 
     321        self.zoomSlider.setMinimum(1) 
     322        self.zoomSlider.setMaximum(1000) 
     323        self.zoomSlider.setValue(100) 
     324        self.zoom_small = QPushButton() 
     325        self.zoom_small.setIcon(QIcon(os.path.join(app.dir_gui, "zoomsmall.png"))) 
     326        self.zoom_small.setStyleSheet("border: 0;") 
     327        self.zoom_big = QPushButton() 
     328        self.zoom_big.setIcon(QIcon(os.path.join(app.dir_gui, "zoombig.png"))) 
     329        self.zoom_big.setStyleSheet("border: 0;") 
     330        self.connect(self.zoom_small, SIGNAL("clicked()"), self, SLOT("zoomOut_()")) 
     331        self.connect(self.zoom_big, SIGNAL("clicked()"), self, SLOT("zoomIn_()")) 
     332        self.connect(self.zoomSlider, SIGNAL("valueChanged(int)"), self, SLOT("dragZoom_(int)")) 
     333 
     334        lh = QHBoxLayout() 
     335        lh.addWidget(self.zoomLevel) 
     336        lh.addWidget(self.zoom_small) 
     337        lh.addWidget(self.zoomSlider) 
     338        lh.addWidget(self.zoom_big) 
     339        lh.setContentsMargins(0,0,0,0) 
     340        lh.setSpacing(8) 
     341 
     342        self.zoom = QWidget(self) 
     343        self.zoom.setLayout(lh) 
     344 
     345        lv = QVBoxLayout() 
     346        lv.addWidget(self.graphicsView) 
     347        lv.addWidget(self.zoom, 0, Qt.AlignRight) 
     348        lv.setContentsMargins(0, 0, 0, 0) 
     349 
     350        self.graphics_zoom = QWidget(self) 
     351        self.graphics_zoom.setLayout(lv) 
     352 
    191353        self.view_edit = QSplitter() 
    192         self.view_edit.addWidget(self.graphicsScroll) 
     354        self.view_edit.addWidget(self.graphics_zoom) 
    193355        self.view_edit.addWidget(self.code_errors) 
    194356        self.view_edit.setObjectName("view_edit") 
    195         self.view_edit.setStyleSheet("QSplitter#view_edit { margin: 10px 10px 20px 10px; border: 0 }") 
     357        self.view_edit.setStyleSheet("#view_edit { margin: 10px 10px 20px 10px; border: 0 }") 
    196358        l = QGridLayout() 
    197359        l.setHorizontalSpacing(10) 
    198360        l.setVerticalSpacing(10) 
    199361        self.view_edit.setLayout(l) 
    200          
    201         #self.centralWidget = QWidget() 
    202         #self.centralWidget.addWidget(self.view_edit) 
    203         #self.centralWidget.setLayout(QGridLayout()) 
    204          
    205362        self.setCentralWidget(self.view_edit) 
    206363        self.setUnifiedTitleAndToolBarOnMac(True) 
     
    208365 
    209366        self.setWindowTitle(self.tr("Untitled")) 
     367        self.dashboardController = DashboardController(self) 
    210368        self.resize(800, 600) 
    211          
     369 
     370    @pyqtSignature("") 
     371    def switchViewport(self): 
     372        self.outputView.setTextColor(QColor(0,0,0)) 
     373        if self._oldViewport == "qwidget": 
     374            self.outputView.insertPlainText("switch to normal view\n") 
     375            self.graphicsView.setViewport(QWidget()) 
     376            self.graphicsView.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate) 
     377            self._oldViewport = "qglwidget" 
     378        else: 
     379            self.outputView.insertPlainText("switch to OpenGL view\n") 
     380            self.graphicsView.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers | QGL.AlphaChannel))) 
     381            self.graphicsView.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) 
     382            self._oldViewport = "qwidget" 
     383 
     384    @pyqtSignature("") 
     385    def zoomIn_(self): 
     386        if self.fullScreen is not None: return         
     387        self.graphicsView.zoomIn_()         
     388         
     389    @pyqtSignature("") 
     390    def zoomOut_(self): 
     391        if self.fullScreen is not None: return 
     392        self.graphicsView.zoomOut_()         
     393 
     394    @pyqtSignature("int") 
     395    def dragZoom_(self, value): 
     396        if self.fullScreen is not None: return 
     397        self.graphicsView.dragZoom_(value)         
     398 
     399    @pyqtSignature("") 
     400    def zoomTo100_(self): 
     401        if self.fullScreen is not None: return 
     402        self.graphicsView.zoomTo_(1.0) 
     403 
     404    @pyqtSignature("") 
     405    def zoomTo200_(self): 
     406        if self.fullScreen is not None: return 
     407        self.graphicsView.zoomTo_(2.0) 
     408 
     409    @pyqtSignature("") 
     410    def zoomTo300_(self): 
     411        if self.fullScreen is not None: return 
     412        self.graphicsView.zoomTo_(3.0) 
     413 
     414    @pyqtSignature("") 
     415    def zoomTo400_(self): 
     416        if self.fullScreen is not None: return 
     417        self.graphicsView.zoomTo_(4.0) 
     418 
     419    @pyqtSignature("") 
     420    def zoomTo50_(self): 
     421        if self.fullScreen is not None: return 
     422        self.graphicsView.zoomTo_(0.5) 
     423 
     424    @pyqtSignature("") 
     425    def zoomToFit_(self): 
     426        if self.fullScreen is not None: return 
     427        self.graphicsView.zoomToFit_() 
     428 
    212429    @pyqtSignature("") 
    213430    def doNew(self): 
     
    279496 
    280497    @pyqtSignature("") 
     498    def doExportAsMovie(self): 
     499        pass 
     500 
     501    @pyqtSignature("") 
     502    def doPrint(self): 
     503        pass 
     504 
     505    @pyqtSignature("") 
    281506    def doRun(self): 
    282507        if self.fullScreen is not None: return 
     
    317542    fileName = property(_get_fileName, _set_fileName) 
    318543 
     544    def buildInterface_(self): 
     545        if not self.dashboardController: 
     546            self.dashboardController = DashboardController(self) 
     547        self.dashboardController.buildInterface_(self.vars) 
     548 
    319549    def _runScript(self, compile=True, newSeed=True): 
    320         if not self.cleanRun(self._execScript): 
     550        if not self.cleanRun(self._execScript, newSeed): 
    321551            pass 
    322552 
     
    337567            if self.namespace.has_key("setup"): 
    338568                self.fastRun(self.namespace["setup"]) 
    339             window = self.currentView.window() 
     569#            window = self.currentView.window() 
    340570            #window.makeFirstResponder_(self.currentView) 
    341571 
     
    344574            self.connect(self.animationTimer, SIGNAL("timeout()"), self, SLOT("doFrame()")) 
    345575            self.animationTimer.start(1000.0 / self.speed) 
    346  
     576             
    347577    def runScriptFast_(self):         
    348578        if self.animationTimer is None: 
     
    365595            # Build the interface 
    366596            self.vars = self.namespace["_ctx"]._vars 
    367             if len(self.vars) > 0: 
     597            if newSeed and len(self.vars) > 0: 
    368598                self.buildInterface_() 
    369599 
     
    406636 
    407637        # Set the mouse position 
    408         # TODO: Get correct mouse position 
    409         #window = self.currentView.window() 
    410         pt = 0, 0 # window.mouseLocationOutsideOfEventStream() 
    411         mx, my = 0, 0 # window.contentView().convertPoint_toView_(pt, self.currentView) 
    412         # Hack: mouse coordinates are flipped vertically in FullscreenView. 
    413         # This flips them back. 
    414         if isinstance(self.currentView, FullscreenView): 
    415             my = self.currentView.bounds()[1][1] - my 
     638        pos = self.currentView.mousePosition() 
     639        mx, my = pos.x(), pos.y() 
     640 
     641#        if isinstance(self.currentView, FullscreenView): 
     642#            my = self.currentView.bounds()[1][1] - my 
     643 
     644        if self.fullScreen is None: 
     645            mx /= self.currentView.zoom 
     646            my /= self.currentView.zoom             
    416647        self.namespace["MOUSEX"], self.namespace["MOUSEY"] = mx, my 
    417         #self.namespace["mousedown"] = QApplication.mouseButtons() & Qt.LeftButton 
     648        self.namespace["mousedown"] = self.currentView._mouseDown 
    418649        #self.namespace["keydown"] = self.currentView.keydown 
    419650        #self.namespace["key"] = self.currentView.key 
     
    563794class FullscreenView(QDialog): 
    564795    pass 
     796 
     797def overrideConfig(app): 
     798    settings = app.settings 
     799    Config["fontfamily"] = settings.value("fontfamily", 
     800            QVariant("Monaco")).toString() 
     801    Config["fontsize"] = settings.value("fontsize", 
     802            QVariant(11)).toInt()[0] 
     803    for name, color, bold, italic in ( 
     804            ("normal", "#000000", False, False), 
     805            ("keyword", "#0000FF", False, False), 
     806            ("builtin", "#000000", False, False), 
     807            ("constant", "#0000FF", False, False), 
     808            ("decorator", "#000000", False, False), 
     809            ("comment", "#808080", False, False), 
     810            ("string", "#FF00FF", False, False), 
     811            ("number", "#000000", False, False), 
     812            ("error", "#FF0000", False, False), 
     813            ("pyqt", "#000000", False, False)): 
     814        Config["%sfontcolor" % name] = settings.value( 
     815                "%sfontcolor" % name, QVariant(color)).toString() 
     816        Config["%sfontbold" % name] = settings.value( 
     817                "%sfontbold" % name, QVariant(bold)).toBool() 
     818        Config["%sfontitalic" % name] = settings.value( 
     819                "%sfontitalic" % name, QVariant(italic)).toBool() 
    565820     
    566821class NodeBoxApplication(QApplication): 
     
    572827        self.settings = QSettings() 
    573828        loadConfig() 
     829        overrideConfig(self) 
    574830        self.documents = [] 
    575831        if sys.platform == "win32": 
     
    591847        except OSError: pass 
    592848        except IOError: pass 
    593              
     849        import nodebox.gui 
     850        dir_gui = nodebox.gui.__file__ 
     851        self.dir_gui = os.path.split(os.path.realpath(dir_gui))[0] 
     852        self._startgl = '-gl' in args 
     853 
    594854    def newDocument(self): 
    595855        doc = NodeBoxDocument()