Thursday, March 13, 2008

Grader: GUI

I find GUI programming to be enjoyable most of the time, with dashes of frustration thrown in for good measure. The fun part is the rapid feedback loop that exists as changes appear immediately on screen. It's also easy to bang out the code and get a lot accomplished in a short amount of time. The frustration comes in when my perfectionist tendencies inspire me to spend an inordinate amount of time trying to get every last detail exactly right, something that is quite difficult to do.

I've worked with QT for quite a while now (5+ years give or take) and really enjoy working with it. Having started out my professional career writing in Java, I like the similarities between the QT framework and the Java Standard library. But like the Java Standard library, QT is quite large and can require a lot of digging to uncover functionality you know is likely to exist, but doesn't seem to exist where you expect it.

Case in point...the Grader application uses a QTableWidget to allow users to enter player grades. After quickly getting the initial GUI up and running, I was surprised to see the cells of the table were not expanding to fit the entire widget, leaving empty white space along the bottom and right borders. I knew there had to be a way to correct this issue, but searched high and low through the QT documentation, unable to find it.

I reached the point where I was ready to give up, subclass QTableWidget, and write some overly complex code that filled the widget, making sure each column and row was the same size, handling resizing issues, etc... But one last search resulted in me finally finding what I needed in the QHeaderViewClass, the class that provides the table's row/column headers. I probably skipped over the function at least once when skimming the documentation, making things even more frustrating. But at least I didn't spend any time rewriting functionality that already existed.

I tackled two other issues in the first iteration of this project: fast data entry and displaying the grading data.

Fast Data Entry
I wanted to make sure the user could complete data entry without having his hands leave the keyboard. I used QActions to provide shortcut keys to save a play (Ctrl-S) and output a report (Ctrl-W). These actions exist in a menu, which I didn't really want to add as I didn't even want to give the user the option of using the mouse. But the QActions didn't seem to be active unless the menu was available.

Displaying Grade Data
My first attempt at this functionality was to display the entire grading table at the top of the window, using a QLabel with the text set to an html table. However, this resulted in a lot of screen clutter and looked really ugly. My next attempt was to just set the QLabel text to an html table that contained two columns, one for the grading scores and one for the grading descriptions based on the current selected column in the grade entry table. This worked well except that the table was always changing sizes and required the user to refocus when looking at the grade data. My brother actually complained about this problem when I gave him the first iteration to test out. I settled on using another QTableWidget which has the benefit of staying a fixed size, but has the disadvantage of looking as if it's editable even though I disabled any selection of the table cells (disabling the entire widget didn't look correct).

Overall, I think the GUI is decent enough for something that I wanted to keep as simple as possible. There probably are still some sizing issues that could be handled better but at this point, I think that's running into the Law of Diminishing Returns.

No comments: