Wednesday, September 23, 2015

PyQt5 on WinPython with mingw

Getting PyQt5 running on WinPython required a lot of tweaking. WinPython (32 bit) 2.7.10.2 comes with mingw. This is installed in E:\WinPython-32bit-2.7.10.2\python-2.7.10\share\mingwpy. Following the instructions on the PyQt5 download page I first downloaded SIP from this page. I downloaded the zip file for windows. Following these instructions I configured sip for mingw by running

python configure.py --platform win32-g++

The next step then is to run make. However if you start a WinPython Command Prompt you do not have make. I fixed this by copying an old msys installation, from an older (not connected to WinPython) mingw installation, to the mingw folder in the WinPython folder (as noted above). Then by changing the fstab file in msys/1.0/etc to this e:/WinPython-32bit-2.7.10.2/python-2.7.10/share/mingwpy/ /mingw I have a msys system setup for working with the mingw from the WinPython distribution. From a msys shell I can then run make and make install for sip.

Next step is to do the same for PyQt5 download. However, there the configure.py script does not recognize the --platform switch. Use the --spec=win32-g++ switch is also not good enough. The problem is that it somehow still puts "windows" commands in the Makefiles it generates for rename, deleting files folders etc. I could only fix this by changing some code in the configure.py script. In the function run_qmake I added the lines

args.append('-spec')
args.append('win32-g++')

(do this before the "if recursive:" statement). While you are busy editing the configure.py file you can also follow the advice in this forum post to handle any issues with mismatching licenses. Somehow configure.py was detecting a different Qt version. This version was actually located in the site-packages/PyQt4 folder (in WinPython-32bit-2.7.10.2/python-2.7.10). By temporarily renaming this PyQt4 folder you can fix this issue.

After this. If you run

python configure.py --spec=win32-g++

from a msys shell should create the right Makefile (note that this means you have to put WinPython in your system path (environment variables in control panel from advanced system settings in the control panel of windows) because otherwise you have no python in your msys shell. Then you can run make and make install from the msys shell.

Then you are almost done. If at this stage you run a PyQt5 python script it will probably complain that it 'Failed to load platform plugin "windows"'. This was a tricky one to solve. For c++ qt applications it is usually enough to copy the plugins folder to the location of your executable (+ any other needed qt dll's), but what is the location of your executable in this case? I only managed to get it running by adding a new environment variable:

QT_QPA_PLATFORM_PLUGIN_PATH='E:\Qt\5.5\mingw492_32\plugins'

Sunday, February 15, 2015

UI not updating in Qt Creator

After not having opened a project for while in QtCreator it often happens that changes made to the user interface in QtCreator are not coming through in the application after recompiling. This is then caused because I am now using a new version of QtCreator or I used to work on the project under Linux instead of Windows (or something like that). The problem is that QtCreator keeps changing where it puts the output of compiling the .ui file. Sometimes it is in the main project folder, sometimes where the .ui file is located and now it was changed into the folder with the impossible name yourProject-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK__Release/Release (where it also puts the object files). And because previously it was stored in the project folder it will first find that old version. I guess removing the old version could work but I liked the solution I found here better: in the project file you can specify where the ui compilation output is stored:

UI_DIR = c:\YourLocation

Monday, January 26, 2015

cx_freeze issues with scipy

When using Cx_freeze with a script that uses an interpolation function from scipy I was getting import errors. More specifically the error was "ImportError: No module named _ufuncs_cxx"

This can be solved by explicitly adding two scipy modules:
cxfreeze --include-modules=scipy.special._ufuncs_cxx,scipy.sparse.csgraph._validation your_script.py --target-dir your_target_dir

This solution is based on information from this website.

Friday, December 26, 2014

Minimize button in a QDialog in PyQt

Often it is easy to write a small application in PyQt as a QDialog (instead of using a QMainWindow). If it is intended as an application that has to be open for a longer time (e.g. while the user is using other programs) it is nice if the program can minimize (e.g. when the user clicks the show desktop button in windows (or the nice windows-key+d key shortcut). However, by default the QDialog window only has a close button. Luckily adding minimize and maximize buttons is easy:

from PyQt4.QtCore import *
from PyQt4.QtGui import *


class MainForm(QDialog):

    def __init__(self, fn=None,parent=None):
        super(MainForm, self).__init__(parent,\
           flags=Qt.WindowMinimizeButtonHint|Qt.WindowMaximizeButtonHint)

Other flags can be found here

Tuesday, October 7, 2014

SQLITE DATETIME troubles

Recently, I have started to play with SQLITE. For the database creation and queries I actually use PyQt but that is not really the issue. I was unaware of the complications with SQL databases and DATETIME formats. I made the wrong assumption that if I provided input that did not give any errors and looked good in the nice SQLite Database Browser everything would be okay. What happened was that I filled a datetime column with strings like '09-11-2014 12:43:00'. This actually is one of the few not supported datetime formats. When running a query where the datetime has to be before or after another (similarly formatted) datetime this actually seemed to produce sensible results. Only when I tried to do more fancy datetime stuff like datetime('09-11-2014 12:43:00','-1 month') did things suddenly stop working. I think sqlite is treating the wrong input for a datetime column as a string and is actually doing a string comparison when comparing two wrongly formatted datetime values (which can sometimes give sensible output). The solution is of course simple: only use one of the supported datetime formats when inserting data into a table.

Monday, October 6, 2014

Cython modules not automatically rebuild through setup.py on changes of pxd files

After some frustrating hours I discovered that if you use a distutils setup.py script to create a cython module the module is not updated if you only change a pxd header file. Especially in a bigger project with many cython modules this can be easily forgotten, so in case of unexpected behaviour just try removing all pyd files so everything will be build fresh.

It is perhaps even saver to touch all .pyx files because if you remove the pyd file the .c file is not necessarily recreated!

interp1d x-axis order must be in ascending order

Today I discovered that the nice scipy 1d interpolation function interp1d requires that the values in x-array passed as the first argument are in ascending order. Perhaps this makes sense but it took me some time to figure out that this was the reason I was getting out-of-bounds errors (my x-array was in descending order).