8
$\begingroup$

I have been trying to import PyQt into Blender following Has anyone hooked up PySide to Blender? in Windows. However I am unable to get it to work.

import sys
sys.path.append('C:/Users/apple/blenderqt/py/Lib/site-packages')
import bpy
from PyQt5.QtWidgets import (QApplication, QWidget, QToolTip,
    QPushButton)
from PyQt5.QtGui import QIcon, QFont

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        QToolTip.setFont(QFont('SanSerif', 10))

        self.setToolTip('This is a <b>QWidget</b> widget')

        btn = QPushButton('Button', self)
        btn.setToolTip('This is a <b>QPushButton</b> widget')
        btn.resize(btn.sizeHint())
        btn.move(50, 50)

        self.setGeometry(300, 300, 300, 220)
        self.setWindowTitle('Icon')
        self.setWindowIcon(QIcon('web.png'))

        self.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())   

I followed the same steps in the other question and PyQt works fine in the virtual environment but it does not work when I put it in the Blender project. What is the problem?

$\endgroup$
3
+50
$\begingroup$

I have PyQt5 working from within Blender on Windows 10. There are likely multiple setup scenarios that are possible and you didn't provide any information on exactly what errors you are running in to, so I'll describe the setup that is working for me::

  • blender-2.76b-windows64.msi
  • PyQt5-5.5.1-gpl-Py3.4-Qt5.5.1-x64.exe
  • python-3.4.4.amd64.msi (probably not required)

In my case, I had already installed PyQt5 in to an existing python-3.4.4 installation. The PyQt5 installer does not support installing to multiple locations, but I suspect I could uninstall and then reinstall it into the {blender-install}/python directory. What I did instead was create a text file named qt.conf inside of my {blender-install} directory with this content:

[Paths]
Prefix = C:/Dev/python-3.4/Lib/site-packages/PyQt5
Binaries = C:/Dev/python-3.4/Lib/site-packages/PyQt5

The PyQt5 installer usually puts a qt.conf file in the python-install folder for you with relative paths. (My python install folder was C:/Dev/python-3.4).

One technique I found useful for troubleshooting things was to run the blender.exe from a DOS command prompt. At first when I tried launching a QApplication, blender and everything would immediately crash and there would be no error message. By running from the DOS command prompt, I was able to see the errors. (This is different from the console window within Blender which does not have the chance to show errors when Qt crashes Blender itself.)

With the above done, I was able to run your script above. However, because you called app.exec(), once the Qt window was shown Blender became completely unresponsive. Closing the Qt window then immediately exited blender.

It doesn't seem to be necessary to call app.exec(). I also thought it would be necessary to somehow start the Qt event loop, but that doesn't seem to be the case. This answer on StackOverflow might explain why: https://stackoverflow.com/questions/28060218/where-is-pyqt-event-loop-running

For my own test, I used this simple script:

import sys 
sys.path.append('C:\\Dev\\python-3.4\\Lib\\site-packages')
import bpy

from PyQt5.QtCore import Qt
from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QGridLayout, QLabel, QLineEdit, QWidget, QPushButton

class TestWindow(QWidget):
    def __init__(self, parent=None):
        super(TestWindow, self).__init__(parent)

        mainLayout = QGridLayout()

        test1Label = QLabel("Test 1:")
        test1Line = QLineEdit()
        mainLayout.addWidget(test1Label, 0, 0)
        mainLayout.addWidget(test1Line, 0, 1)

        test2Label = QLabel("Test 2:")
        test2Line = QLineEdit()
        mainLayout.addWidget(test2Label, 1, 0, Qt.AlignTop)
        mainLayout.addWidget(test2Line, 1, 1)

        button = QPushButton('Close', self)
        button.clicked.connect(self.handleButton)
        mainLayout.addWidget(button, 2, 0)

        self.setLayout(mainLayout)
        self.setWindowTitle("Simple Qt Test in Blender")

    def handleButton(self):
        print("close clicked")
        app.beep()
        window.hide()
        # note that at this point, I think the Qt app
        # is technically still 'running'

try:
    app = QtWidgets.QApplication(sys.argv) 
    window = TestWindow()
    window.show()

    # I was surprised to see that it wasn't necessary to 
    # somehow start the Qt event loop.  Normally something like
    # app.exec() would need to be called, but that of course
    # would hang blender. I found some info on why
    # event loop likely works from within blender without
    # additional setup here:
    # https://stackoverflow.com/questions/28060218/where-is-pyqt-event-loop-running

except Exception as e:
    print ('error')
    print (e)

If the above does not help, consider posting more information about exactly what errors or response you are seeing.

|improve this answer|||||
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.