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 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?
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 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
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.
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
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.
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.