Qt Project Logo |
The request to add Modality Worklist SCU to a product is common. This time, the product was already capable of exporting DICOM Images but didn't have any network capabilities. The guys from Marketing asked to send the DICOM files to a PACS and add Modality Worklist Query. Very reasonable and makes perfect sense. Only when I got the detailed system requirements did I realize that this project is going to be challenging after all but for different reasons.
Most of our custom software development projects at H.R.Z. are Windows Technology. We do some Java and iOS from time to time but that's not very common. This time we were asked to develop with Qt.
Qt is a cross-platform application framework. The programming language is C++ and there's a pre-processor called MOC on top of that and GUI framework which now, looking backwards, I can say that is actually very good. Originally developed by Trolltech and later acquired by Nokia, Qt offers a wide range of compilers for many target operating systems and hardware ranging from Handhelds and Cell Phones, embedded linux, Mac OS-X and of course Windows. Apparently Qt is more popular in Europe then in the United States, Maybe because of anti-corporate trends in the old continent or maybe simply because its free.
Most of our custom software development projects at H.R.Z. are Windows Technology. We do some Java and iOS from time to time but that's not very common. This time we were asked to develop with Qt.
Qt is a cross-platform application framework. The programming language is C++ and there's a pre-processor called MOC on top of that and GUI framework which now, looking backwards, I can say that is actually very good. Originally developed by Trolltech and later acquired by Nokia, Qt offers a wide range of compilers for many target operating systems and hardware ranging from Handhelds and Cell Phones, embedded linux, Mac OS-X and of course Windows. Apparently Qt is more popular in Europe then in the United States, Maybe because of anti-corporate trends in the old continent or maybe simply because its free.
I wanted to take this project. It was an opportunity to see how our DICOM library, RZDCX, performs outside of its C#/.NET comfort zone. We already had at least two respectable customers utilizing RZDCX and Qt in their medical device products that have completed the development cycle and had thousands of units sold worldwide, so I knew it's possible, but while they were using Microsoft Compiler that offers the full comfort of ATL, this project required MinGW compiler which was new to us. Before I could say yes, I had to verify that Qt + MinGW can talk with our DICOM Toolkit so we had to do a little research and evaluation project and that's exactly what we did.
Qt and COM
Like many open-source projects, when it comes to documentation, Qt documentation is inferior to MSDN for example and even to Apple Developer Center. After digging deep into the internet and separating the wheat from the chaff we were able to compile a short cookbook on using COM in Qt. Qt framework includes a class called QAxObject that inherits from QAxBase. These two classes is enough but luckily there's a pre-processor tool called dumpcpp that makes things much easier. dumpcpp generates C++ wrapper classes for type libraries (typelib). With dumpcpp, using RZDCX becomes very easy. Here's our Cookbook.
Using COM Objects in Qt
Using COM Objects in Qt
Registering the COM Object
Before starting make sure to regsiter RZDCX in the registry.
From command line with administrator priviliges run: regsvr32 rzdcx.dll
From command line with administrator priviliges run: regsvr32 rzdcx.dll
Importing the Type Library
In the Qt Project Configuration file, add this:
This will create rzdcx.h and rzdcx.c using the dumpcpp utility. The UID above is the UID of RZDCX Type Library.
Using the toolkit API
COM Exceptions are firing Qt signals. To get these signals connect to the QAxBase::exception signal.
Your class should be a QObject and implement a slot for QAxBase::exception.
In the implementation class handle the error, for example by caching the information in a member like this
Practically, that's about it. Beyond that its simple implementation of the application logic. Some questions that we've not found cool solutions for yet are the callback methods but luckily, most of the toolkit functionality can be used without it anyway.
Using the toolkit API
This example shows sending a C-ECHO commad
Error Handling
RZDCX throws COM Exceptions when errors occur.COM Exceptions are firing Qt signals. To get these signals connect to the QAxBase::exception signal.
Your class should be a QObject and implement a slot for QAxBase::exception.
Before calling the API, hook the slot to the object:
Passing interface objects in and out of the API
This is probably the most tricky part and it actually forced us to extend the DICOM API. We've added Create methods to DCXAPP to make it easier to get an interface pointer of the required API class. To pass interfaces to and from the API use create methods in DCXAPP (version 2.0.3.3 and later):
Since these are pointers that should be released, consider using auto pointers.
The example bellow sets the patient name and patient id elements into a new DICOM Object
No comments:
Post a Comment