kuroi neko
kuroi neko

Reputation: 8671

How to create and use Qt 5.14.0 custom widget plugins with MSVC 2019?

I finally solved this amusing riddle so I'll answer my own question. It drove me half nuts though, so I guess it might help a few fellow programmers.

Problem definition

What I want to do seems fairly simple: create my own widget and integrate it to my own Qt Creator (the version that runs on my local machine, as shipped with the standard Qt install) so that I can use it freely to design my own interfaces with the ad hoc GUI design tool.

Promoting a generic QWidget works adequately, it's just not very convenient.
I thought seeing the widget in the GUI design tool (instead of an invisible rectangle) and having the possibility to modify specific properties (instead of having to do it programmatically) would be nice.
Unfortunately, this did not go as smoothly as I hoped.

I can’t even be responsible for my own compiler!

Using:

I started by naively compiling the example (the clock widget) for x64. Nothing happened. Then x86. Same result or lack thereof.
I actually realized this was conceptually wrong just before trying to compile it for MinGW.
Clearly the produced DLL had to match the native format of the actual Qt Creator, so this idea of the makefile magically adding a plugin to the current Qt Creator binary was all rubbish.
I gave up the wishful thought and set off to put the proper bit of DLL in its proper place by hand.

That's where I went astray for good.

I soon saw that the Qt Creator executable being shipped with Qt 5.14.0 has been compiled with MSVC2017 in win32 mode (that's stated in the "about" window, though no precise version of the compiler and/or toolchain is clearly stated, just this rather unreliable "MSVC2017" which is also used to designate an actual MSVC2019 environment).

The path defined in the example project was leading to some cryptic MSVC2017 subtree where nothing happened at all.
Putting DLLs there had no effect. Deleting the ones that were already present had no effect either.
Clearly my version of Qt Creator never used any of these DLLs. I have no idea what use they are supposed to be and frankly I could not care less. It was just another cold trail that wasted a bit more of my time.

Looking at the "about plugins.." window from Qt Creator, I noticed that all plugins listed there were located in <Qt install root>\Qt\Tools\QtCreator\lib\qtcreator\plugins\ (as stated in the windows that opens when clicking the "details" button). I wrongly assumed this was were all plugins should go. However, putting the result of the standard example (the cute little clock widget) into this directory did nothing at all.

I then lost a whole day trying to understand why in the blazes this bloody plugin would not show up.

Since the current MSVC integration is somewhat whacky (Qt still refers to MSVC2017 while using the binary compatible MSVC2019), I set out to try and use the v14.16 Microsoft toolchain (the last using MSVC2017 that can be installed with the Web installer).

I never managed to make this bloody older version of the toolchain work.
Frankly this Qt/VS integration is a quagmire. It boils down to calling this horrendous "vcvarsall.bat" command file that sets up a truckload of cryptic environment variables. As it happens, vcvarsall.bat requires an extra command line argument (-vcvars_ver=14.16) that Qt is unable to pass (it considers the compiler definition invalid instead... What a rotten luck...).
You can still wrap the call into yet another batch file (@vcvarsall.bat %* -vcvars_ver=14.16) and feed that to the Qt compiler setup. But even then I never could bring the bloody thing to compile.
I got missing includes and whatnot. Clearly the IDE must make some other assumptions about whatever file locations that make it impossible to work outside the "autodetected"' MSVC versions (namely the MSVC2019 current version in the present state of things).

I was mightily pissed off after all this painful waste of time, so I scoured the Qt forums again and got cluttered by countless (mostly Linux) discussions about paths and compiler options. More time wasted. A lot of time, actually.

In a last desperate attempt I used the nifty process explorer (that's right, spying on all resources opened by an executable) to locate the DLLs used by my running copy of Qt Creator. That is when I finally located the go[beep]mn directory.

From there on everything went quite smoothly indeed. Just compile your little DLL and put it in the right place, and Bob will be your uncle.

Upvotes: 1

Views: 1047

Answers (1)

kuroi neko
kuroi neko

Reputation: 8671

A bit of bullshit lore

There are two informations that might lead you to think the designer plugins live either in Qt\Tools\QtCreator\lib\qtcreator\plugins (the path reported by the "About plugins..." window) or Qt/5.14.0/msvc2017/plugins/designer (the cryptic install path used by the example project)

Both are wrong and misleading.

Another bit of lore pretends the Qt Creator executable requires the exact same version of the compiler to produce compatible plugins.

This is another piece of bullshit. You can very well compile with MSVC2019 for the current version of the tool, that has apparently been compiled with MSVC2017 (though the about window does not say with which exact version of the toolchain or compiler, alas).

All you need is a binary compatible DLL (obviously), that means a Win32 compilation from a binary compatible Microsoft compiler (which could theoretically be as old as MSVC2015, as far as binary compatibility is concerned, but since apparently nothing but the latest version of the toolchain is likely to ever work, this is of purely academic interest).

It is not even necessary to compile in release mode, apparently debug DLLs work just as well.

Trying to make the previous version of MSVC work is not only a nightmare of undocumented and cryptic failures, it is also totally useless.

And the solution is...

Just build the project for MSVC 2019 (what Qt calls MSVC2017 for some reason) in WIn32/release mode and put the go[beep]mn resulting DLL into this directory:

<Qt install root>\Qt\Tools\QtCreator\bin\plugins\designer

Yup, that's right. You get a Qt\Tools\QtCreator\lib\qtcreator\plugins where strange things seem to happen but no "widget plugin" will ever be loaded, and another Qt\Tools\QtCreator\bin\plugins with a bunch of subdirectories, including the "designer" folder where your little "widget plugin" will finally come alive.

You get also a lot of bullshit and/or outdated tips from various Qt forum threads. Apparently Qt is crawling with a truckload of different "plugins" that don't all live in the same hovel and love to migrate with each new minor version... I could find no hints or lists of useful directories in the Qt documentation either. And believe me, I did read quite a lot of Qt documentation.

And btw, to make use of your reusable widgets you will still need to provide either their source code or an interface header and some DLL/LIB for linking.
This "plugin" thing is a nice way to integrate your widget to the GUI editor, but it will not install a library containing your widget nor its interface header (that would be a nifty trick indeed :)).

Bloody awful nightmare. But now it's over and playing with my little custom widget cuties is a load of fun. Yay...

Upvotes: 0

Related Questions