Monthly Archives: October 2013

How to use Qt only in a part of your application

I have been developing an application in ROS and I have needed to create GUI for one specific subtask. Because the GUI might get quite complicated I have decided to use Qt. However I didn’t want to use Qt in the whole application because this “GUI task” might not have been invoked in the applications lifetime.

The standard way how Qt sets itself up is this:

I simply couldn’t do this for the reasons listed. After some experimentation I have arrived at this solution (It’s just a prototype):

The important things are:

  1. QApplication is created only once. Pointer to it is made private static. That way even if you create more instances of the class (ManualFeatureMatcher in this case) there will still be only one instance of QApplication. I have also faced bugs when the QApplication was destroyed and created again. Smart pointer isn’t really that much necessary here, normal pointer would have achieved the same.
  2. QDialogs are used. I wanted to make the method matchFeatures() blocking. QDialogs also have their own EventLoop so there is no need to use the QApplication::exec()
  3. Fake argc and argv are static. This gave me a headache for a while. Those fake arguments need to live as long as the QApplication lives because it keeps their addresses.
  4. There is a check for an existing QApplication instance using QApplication::instance and not a check for nullness of the private pointer. Not needed for now but I do not want to break this module when I decide to use GUI somewhere else.

This solution seems quite solid and works fine for me. I am a Qt newbie however (started yesterday), so there is a possibility I may have overlooked something.

Think twice before pulling up

Pull up refactoring means that you move a member from a subclass to a superclass. It might be useful to remove duplicated code but it can also damage your design quite a lot.

A lot of times I wanted to perform pull up I came up with a better solution. The thing is that the behavior has to make sense in the context of the superclass. Yesterday I came up  with this code.

 

 This is the result of bad pull up refactoring. Some of the subclasses shared method CreateDirectionVector so I decided to pull it up to the parent. As you can see the method doesn’t really fit there. You can ask why is the WeaponBehavior responsible for carrying out this vector calculation. Also none of the other methods uses it so it isn’t obvious why the method even exists.

I have solved this by creating a class VectorUtilities and put the method there. I am always anxious when I want to create such class but I think in this case the Utility class is justifiable in my architecture.