Are you still with me?
I’ve taken a long break from The Road for some time, but fear not, I haven’t forgotten about my initial goal. But since it’s been so long, maybe you have? Let’s start this step with a short recap:
- Step 0 – At the beginning of the summer 2009, I started my journey to “KDE Devland” to become a KDE developer. By sharing my experiences I hoped that I could motivate others to do the same, and leave behind useful tips for those who wanted to walk the same path. The first step was mostly an introduction.
- Step 1 – Before going on a journey, you should be prepared. In this step I shared useful links for soon-to-be developers and wrote about my plan and which books I would use.
- Step 2 – I started with C++. This post went through pointers, something I found hard to understand in the beginning.
- Step 3 – Talking about my temporary workspace and which applications I use to write the code.
- Step 4 – At this point I finally had some screenshots to show. In this step I showed my achievements after the summer and wrote a little bit about Qt programming.
I feel fairly comfortable with Qt now, and try to learn some specific parts of the toolkit when I find the time and motivation. Right now I’m struggling with the Interview framework – I think I understand the theory behind it, but I need to get a feeling for how to actually use it.
In this step I’ll show you some of my own applications I’ve done to familiarize myself with Qt. If you still remember the last step you’ll recognize some of them, however they’re actually all made from scratch. First one out is the smallest application, but also the one giving me the most trouble.
TextSync
Description
TextSync is an extremely simple text editor. Rather than loading and saving text files, it “syncs” to a user-defined text file (from now on referred to as the original file; synced text is the text shown in the application):
- Original file modified – TextSync reloads the synced text
- Synced text modified – TextSync saves the new text to the original file
The idea is to make a plasmoid version of TextSync. It would behave pretty much like the Notes widget in the sense that you don’t have to think about saving and loading the text, but with additional benefits:
- You know where the text is saved and can easily make backups, for example
- TextSync can be used to display logs by pointing it to a log file and set it to read-only
- You can easily sync text across computers with services like Dropbox. This combination will let you use TextSync as a synced Notes widget, or you can turn it into a basic chat widget by sharing the synced file with a friend
I want to stress, however, that TextSync is not meant to be used as a collaborative tool.
By the way, TextSync is just a semi-temporary name, like the names of the other applications – I might rename it sometime in the future if I find a better name. Maybe “TextView”, similar to the FolderView widget?
What’s next
There are still some things I need to iron out before porting it to Plasma. For example I currently use QFileSystemWatcher
to monitor the source file, but I don’t know if it’s a good idea performance-wise.
Also, TextSync only saves the text every n second (currently set to 5) when the synced text is modified to avoid excessive write to disc, so I have to decide how to handle the following two situations:
- Synced text modified (unsaved), original file modified – At the moment TextSync simply reloads the source file, discarding any changes you’ve made during the last 5 seconds
- Original file modified (not loaded), synced text modified – This is less likely due to the use of
QFileSystemWatcher
, but can still happen
I want to avoid using dialogs – the user shouldn’t be aware of the whole loading/saving mechanism. I’ve been thinking about using something like diff to merge the two texts, but I’m not sure about this approach yet; even if I was, I don’t know how to implement it.
The easiest solution would be to do what TextSync currently does – discard any changes made in one of the texts, preferable the synced text.
What I learned
TextSync proved to be good lecture on how to structure your classes. In the beginning I had everything in two classes, TextSync
for the main application and SettingsDialog
for the settings.
Soon I found that QFileSystemWatcher
wasn’t flawless. When I modified the source file with vim, it would stop monitoring the file – the next time the original file was modified, TextSync wouldn’t reload it. To workaround this, I had to readd the path whenever QFileSystemWatcher
noticed that the file had been changed. This was not as easy as it may sound, as it didn’t work to simply add it immediately.
This extra code didn’t really belong to the main application, so I moved it to its own class, FileWatcher
. Now TextSync can use the new class in a very similar way to QFileSystemWatcher
, and it doesn’t have to know that FileWatcher
attempts to readd the path.
I’m in the progress of doing a similar thing with the loading/saving functions – move everything to a separate class. Since these functions are tightly connected to the QTextEdit
widget (the text box), it makes sense to derive the new class from QTextEdit
and add the extra loading/saving functionality to it.
GridView
Description
GridView is a reimplementation of the spreadsheet application I did in the previous step. As I wrote back then, I found the spreadsheet example far from easy – by making a similar application myself, I hoped I would understand some parts I didn’t before.
As the name implies, GridView is meant to view grid files (*.grd
). In a previous summer job I worked a lot with these files, so I thought it would be nice to make an application to view and edit grid files.
The files themselves are very easy to read, the grid above looks like this:
DSAA 4 4 0 4 0 4 1.8 9.9 7.5 6.3 2.0 0.7 9.9 5.8 1.8 3.0 8.2 5.7 8.6 7.4 7.6 4.4 4.2 2.3
What’s next
For now, GridView is mostly an empty shell – most functionalities need to be implemented. The UI was made with Qt Designer in contrast to the spreadsheet application, which was mostly made in a text editor.
This is mostly a test application, something I won’t spend time to improve and polish. Once I’ve added the features I want, I’ll leave it at that. But I’m sure it’ll be useful as reference for future applications.
What I learned
Not much yet. Since the application isn’t really needed, I don’t feel much motivation to work on GridView. When I’m back home again I’ll look at the source code of the spreadsheet application again and add some basic features to GridView.
Quiz!
Description
So I only planned to do two applications for this step. But one day when I was generating random dates “manually” (with a random number generator) I realized, “Hey I can make an application to do the hard work instead”. And thus Quiz! (I couldn’t find a good name – the current one is inspired by Qalculate!) was born.
Now I don’t have to check if my answers are correct in a calendar either, since Quiz! does it for me. Quite a handy little application.
Quiz! can be used for other questions as well – you just have to derive from AbstractQuestionGenerator
and implement the generate()
function. I’ve only made two question generators so far, the one shown above and one for a math quiz:
As you can see, I also played around with HTML in QTextBrowser
.
What’s next
The application works fine for me now, and since I don’t plan to release it, I don’t think I’ll work on it much more. For now you have to change a line in the source code and recompile to switch question generator. It should be very easy to add a feature to change it at run time, however.
Right now the date quiz only asks for dates in 2009, but I have to change it to 2010 now. When I’ve become better I’ll make it generate a random year in the 21th century.
What I learned
Quiz! was very fun to code. It’s small, yet something I know I would find useful.
When working on this application, I came to appreciate object-oriented programming more and more. One good example is the use of QDate
to handle dates. Writing a function to generate a random date isn’t hard, but it’s not a one-liner either – you have to take into account that the lengths of the months are different, and with random years you need to remember leap years as well.
With QDate
I generate a random month (1-12) and day (1-31) and use the bool QDate::setDate(int year, int month, int day)
function in a do while
loop. If the date is invalid it returns false
and a new date is generated, otherwise it returns true
and exits the loop.
As a bonus, QDate
offers a dayOfWeek()
function to easily check the weekday for a specific date. Thanks to this class, the source code for my date quiz generator is very short and straightforward.
Next stop: The land of yellow cashews
For now I’ve only worked with C++ and Qt, but hopefully I can write a little bit about working with the KDE Platform in the next step. The plan is to first port TextSync to Plasma. There is another plasmoid I want to do – I’ll write more about it the next time if my first step into Plasma land is successful.
January 1, 2010 at 17:57
Awesome !!!TextSync Sounds cool
January 1, 2010 at 18:01
Are your programs open source? I’m learning Model/View architecture now, so could you show your code for GridView? It would be very helpful to understand how to implement it 🙂
January 1, 2010 at 19:31
[…] Re: The Road to KDE and Qt Development A New Year's update from the main place: The Road to KDE Devland – step 5 Who Says Penguins Can't Fly? […]
January 2, 2010 at 10:21
@Fazer:
Yep they’re all open source. However, as mention, GridView is not much more than a ui file right now – I need to implement most of the features. Furthermore, I don’t think I’ll use Model/View for this application.
If you still want the source, just give me a poke and I’ll put it up on Dropbox or something. 🙂
By the way, there are some Model/View examples here that you might find useful (I haven’t looked at them myself yet): http://doc.trolltech.com/model-view-programming.html
January 2, 2010 at 17:47
@Hans:
I’ve read that tutorial in your link earlier, but only lately I’ve managed to implement that architecture properly in my app here – http://gitorious.org/presto (I’ll commit the working model/view patch soon). You said you won’t use model/view, so I guess it won’t help me, but I believe I’ll be able to complete my implementation on my own 😉