An awesome frequency control widget

Gqrx / C++ update June 4, 2011: After establishing the basic framework for a GNU Radio receiver written in C++ it was time to start working on the GUI framework. As you may recall the GUI will be written in Qt and I am hoping that it will simplify porting the application to Mac OS X.

The basic receiver framework mentioned above is a simple flow graph consisting of a Funcube Dongle source, a frequency translating band pass filter, a narrow band frequency demodulator and an audio sink. All this is encapsulated in a master receiver class that provides a single control interface to be accessed from the outside world (GUI, CLI, network, etc.). This is actually a working receiver and the result can be regarded as a successful proof of concept. Finishing the core receiver will now be a matter of adding new blocks and API calls.

Concerning the GUI, I felt that the first thing to do was to add a widget  that allows convenient change of RF frequency. I wanted something similar to what I implemented in the Grig “quick-tune” interface where the user can tune by clicking on the digits. This method turned out to provide a very efficient and flexible tuning experience.

Instead of writing something from scratch I started to look at what is already available out there. I found that the recently released Cutesdr already has such a tuning widget that implements all I wanted and even more. In fact, Moe did a great job with this widget and its functionality exceeds my expectations. In addition to the basic click-to-tune functionality it has very good support for tuning using the keyboard, including direct frequency entry. It is implemented in its own class and adding it to gqrx was as simple as adding the .cpp and .h files to the project and creating an instance of the class. The screenshot below shows a slightly modified frequency controller embedded into the current gqrx mock-up. I have changed the color of the digits from screaming-green to something more discrete.

Frequency controller widget in gqrx

Here is a list of tuning features provided by this frequency controller widget:

  • Tune using the mouse wheel on any digit.
  • Tune by clicking on any digit. The widget can operate in two modes:
    • Left-click on the upper half of the digit to increment, on the lower half to decrement.
    • Left-click anywhere on a digit to increment, right-click to decrement (or the other way around).
  • Use left/right arrow keys to select the active digit, up/down arrow to increment and decrement the active digit (active digit = the highlighted digit).
  • Enter the frequency directly using the keyboard, starting at the current active digit. Entering the number selects the next digit to the right as the active one, so it really works like direct number entry into an entry field.

When a digit is changed the widget emits a signal that can be connected to slots. Very easy.

One thing I found strange about the behaviour of the widget was that whenever a digit was changed, the digits below it were all reset to 0. So, if the frequency was 144.712 MHz and we incremented by 100 kHz, the new frequency would become 144.800 instead of 144.812 MHz. While I can see how this might be useful in certain cases, I found it rather confusing and changed the code to only change the active digit and not the ones below it. Actually, I made this an option, so the original behaviour can still be enabled. But I think it will not be necessary once I also add the middle-button click, which will reset the active digit to 0.

I also found some other quirks with the frequency controller. For example, the font size doesn’t have any effect and the text will be scaled according to the size allocation. This issue can be circumvented by giving the widget a fixed size allocation. If the widget is resized the digits disappear and they will  reappear only when the mouse hovers over them. Probably some missing “repaint” function.

In any case, the widget works great and it has saved me a lot of coding time. Thanks to Moe Wheatley for the excellent work!