Monday, April 30, 2012

Programming in Qt 2 - The core

Introduction
Signals
Slots
Exercise
 Function definition
 Connecting the slot
Finishing things up


Introduction
In the first tutorial I taught you how to basically create a "hello world" program in QT and change the value of a button. However, explicitly defining everything in that method is not the purpose of a GUI. User interaction is a key feature of any user interface, so in this tutorial I will show you how to create a button that toggles its text. To do so I will use signals and slots. Before we delve into the code, I will explain what those two things are.

Signals
During the execution of a Qt application there is a main loop until the user commands the program to stop or there is a serious exception. Signals are Qt constructs that are emitted when a certain action has occurred. You can create your own signals with the emit keyword, but for now we will only worry about custom slots.

Slots
Slots are the code executed when a signal has been emitted. These slots are connected to the signals of a certain object within the application. For instance, the slot we will make will be connected to the clicked() signal of the PushButton.

Exercise
 Function Definition
Create a toggling button
Open Qt creator and open the .pro file that you created in the last exercise. .pro files, or project files are what tell qmake to include that particular file in compilation.

You should already have an application complete with a PushButton in the center. If not, follow the steps in the first tutorial to get to that point. Our first step is to create a prototype for toggleVal() in MainWindow.h. Go to MainWindow.h in Qt creator. The file is located under the "headers" tab which may be collapsed.

I usually append the class after private: since that is the end of the generated code, but you can place these next two lines wherever you want. Some prefer to do it after public:.You need to add this code:

public slots:
void toggleVal();

As you probably already know from studying C++ this creates a prototype, or undefined declaration, of the function toggleVal(), which we will define in MainWindow.cpp.

Navigate to MainWindow.cpp and after the definition of the MainWindow deconstructor add the following lines:

void MainWindow::toggleVal(){
    QString val1="Value 1";
    QString val2="Value 2";
    if(ui->pushButton->text()=="Value 1")
        ui->pushButton->setText("Value 2");
    else if(ui->pushButton->text()=="Value 2")
        ui->pushButton->setText("Value 1");
} 

This is the slot for the PushButton. There are a few new things here. QString is used instead of std::string for Qt text. std::strings can be converted using the fromStdString() function of QString.

text() for pushButton returns the displayed text and setText() sets the text.

Why were the ifs so strict? I find it to be in good style to explicitly define my conditions in my graphical interfaces since other functions could possibly change the value and you may not want it changing at that point. You can define it however you wish, though. The main parts of this code to take are text() and setText().

 Connecting the slot

So far the only thing we have accomplished is making a function that checks the value of a button and changes the text accordingly. This can be called explicitly, but again, that does not give the user enough control. We will connect the slot in the MainWindow constructor of MainWindow.cpp.


After the code 
ui->setupUi(this);
add these two lines:
ui->pushButton->setText("Value 1"); QObject::connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(toggleVal()));






The first line explicitly sets the text of the button to "Value 1" so that the function can work properly. The second line is a bit trickier.

We call the connect function of QObject which has 4 parameters. The first is the sender, which in this case is the pushButton. Then, the signal  to act on. The signal is placed inside SIGNAL(). If you typed this yourself rather than copy-pasting, you would have seen the list of signals available for use with PushButton. Next is the member, which in this case is the MainWindow. Then, the slot. Like SIGNAL() slots must also go within SLOT(). We supplied our toggleVal() function, but you will see a list of predefined slots if you type that code yourself.

Multiple slots can be connected to a single signal, and multiple signals to a single slot. This becomes an important concept once you have multiple ways to quit or to initiate an action.

This power is immense. You can define toggleVal() to do anything you want. Close the application, parse, move the application wildly around the desktop, draw squares with OpenGL... Anything that Qt and C++ are capable of can be done in slots.

Finishing things up
In this tutorial you learned how to define and connect signals and slots. In the next few tutorials, you will learn about some other parts of the Qt library like QString and QPainter in depth. The next tutorial will be on a slight delay as I still have Qt related learning to do before I am able to write it. Other resources do an alright job of explaining things, but the purpose of these tutorials is to provide a very straightforward approach to Qt. 

Sunday, April 29, 2012

Ubuntu 12.04 review

A year after the release of Ubuntu 11.04, Natty Narwhal,  the LTS release of Ubuntu, Precise Pangolin, was released. The new version featured Unity 5 with features such as the HUD and lenses. Also on the list of additions was the inclusion of classic gnome and the replacement of banshee with good-old rhythmbox.

A page out of Debian's book
Debian, the father distribution of hundreds of derivatives, uses Gnome 2 in their stable version. After all the gripe over Gnome 3 and Unity the ubuntu development team decided to include a full blown gnome-classic DE in the release. The inclusion was aimed to move people away from outdated versions of Ubuntu that are still clinging to gnome 2.

Rhythmbox, Debian's media player of choice, is also included over banshee in this distribution. After dropping rhythmbox to include Banshee for 11.04 they have gone back to their roots, leaving banshee in the dust. This was because of community preference, bugs in banshee, and stability in Rhythmbox.

Despite the reasons for these changes, Debian users will be in a more comfortable default environment than before when switching to Ubuntu.

Unity 5
In contrast to the original Unity from 12.04 Unity 5 is a vast, vast improvement. With one fell swoop the Ubuntu team has turned Unity into a tool of timesaving and productivity, and it's called the HUD. The HUD, activated with the alt key, allows access to the menu bar of any application. It also caches results so it can learn your preferences, making quick judgments about what you want to do and what you want to do quickest. The Unity interface can now be customized in a ton of ways, from myunity to the ccsm to even the appearance menu.

Small improvements define the latest version of Unity, however. The simplest features like leaving old queries in the Dash really make using the interface a much more productive experience than before. Unity is no longer the clown car of the desktop interface world.

Conclusion
12.04 is the first distribution after a year of volatility over some of Canonical's decisions to get things right. They dropped unstable software in favor of old, stable software and pushed enough bug patches to make Unity look like a family quilt. Where 11.04 had a cutting-edge, unstable feeling to it 12.04 is a noticeably stable experience that is easy for newcomers and power users alike.

How to package a .deb

          On Debian-based systems, the package manager uses .deb containers to handle the installation of packages. Many people make a connection between .deb and .exe since both are easy formats that usually lead to the installation of a program, but this is not the case. Deb files are more like an advanced .tar, and they don't even need to be used for installing programs. In this tutorial I will show you how to make and build a debian package. Make a new directory, let's say for instance, mydeb. Then, in the mydeb directory make a folder named DEBIAN. Now we can begin.

There are a few essential things to put into DEBIAN. You need to have a control file called control, a pre-installation script called preinst, and a pre-removal file called prerm. The control file uses a special syntax to define dependencies, make a description, and note the authors. Here is a sample control file:

Package: mydeb
Version: 1.0.0-0ubuntu1
Architecture: amd64
Maintainer: You <You@email>
Installed-Size: 154
Depends:
Section: accessories
Priority: optional
Description: A sample debian package.

Package is the name of the package, in this case it's mydeb. The version is the version of the file with any special revision names included. Architecture is what type of CPU it can run on. Depends is the most important, which lists dependencies. The operations > < and >= <= can be used to specify higher or lower version numbers for dependencies. The section is what type of application it is. Priority is whether or not the package is a necessity. In this case it's not. Description is a long description of what the package can do. This can be multiple lines.

Now that the control file is out of the way, make two scripts called preinst and postinst. These are bash scripts (text files with #!/bin/bash at the top) that list the commands to install and remove the parts of the program that were included on install. ldconfig should be called in either file.

The fun part
The fun and arguably the most important step is specifying the directories where files will be installed. Leave the DEBIAN folder and make one called home. Then, make one that is exactly equal to your home folder. Make a sample text file here. When the .deb is installed that text file will be placed in your home folder. This is used to spread resources across the files system, for instance the icon goes in /usr/share/pixmaps. You actually have to create those directories inside of the parent directory.

Now you should have two directories in the parent directory, DEBIAN and home. Now we can package these with the dpkg command. Enter the terminal and use the command
dpkg -b 'PATH_TO_PARENT_FOLDER' myDeb.deb


This should create a file in your home folder called myDeb.deb. Now you can install the package with gdebi, the software center, or dpkg.

A note for application developers: ldd lists the dependencies of an executable file for the Depends: part of a command file.

External: http://www.linuxfordevices.com/c/a/Linux-For-Devices-Articles/How-to-make-deb-packages/

Programming in Qt 1 - Absolute Basics

INDEX:
Purpose
Prerequisites
First program in depth

Purpose 
             As a somewhat new programmer (less than a year) I have run into some irritating tutorials in my experiences. When I began to learn the Qt framework and the Qt creator Integrated Development Environment (IDE) these experiences were ubiquitous. This is in part due to the self-explanatory documentation of the library, since the documentation is enough for some people to learn their way around. Through the few good online tutorials and documentation I have taught myself the basics of Qt and am now ready to share my learning process with the internet so that upcoming programmers can learn from my breakthroughs and mistakes.

Prerequisites
               During the next posts pertaining to this I will cover Qt, Qt creator and all of its parts, and .deb packaging later on. Qt is absolutely required, and Qt creator is required for this tutorial since I will use information specific to that IDE, but Qt development can be done without it. The main reason I choose to write about and use Qt creator is for its GUI designer. You can download Qt creator and Qt at http://qt.nokia.com/downloads. Qt is a huge library, so be patient.

First program in depth
            There really is nothing more that you need to do once you have a working version of Qt creator. Launch it and we can begin writing the first program. Launch Qt creator and do the following: Create project > Qt Widget project (Qt GUI Application) > (name it and put it in the folder) > use default settings > Default settings > Finish.

             You should now be placed in mainwindow.cpp, where the constructor and deconstructor are defined. There should be a folder on the left side of the application called "Forms" with an arrow. Click on it and click on mainwindow.ui. This is a blank canvas of a user interface. Next, take a push button from the left and drag it onto the canvas. The button will read "PushButton". The code you write now will show you how to change this to demonstrate control over the UI. You do not have to do this since you can edit the text right from the Gui designer, but this will be an introduction to external UI control.

         Hit edit on the left hand side and you will be brought to the QML (Q markup langauge) for the user interface. Ignore this and move back go mainwindow.cpp under sources.

        The user interface is accessed with "ui->" from mainwindow.cpp, So, after the code ui->setupUi(this); we can change the text of the push button. After it, write ui and hit ".". The . will convert itself into -> and you will have a list of UI items. The entries with a blue block are Qt classes, including pushButton, which is what we want. Type p and enter to select the push button. Now, use "." again to see a list of variables and functions relating to pushButton. Use setText("text here"); to change the button to whatever you wish.

The final code should look like this: ui->setupUi(this); ui->pushButton->setText("text here");
      
       This code is executed right after the program sets itself up, so the user never sees "PushButton" on the button.

In the next tutorial I will show you how to use Signals and Slots, which are the Qt equivalent of Swing's events. You will make it so the button toggles its name on every click.

Sunday, April 8, 2012

Learning C++ after Java - My experience

As I have stated in previous posts and on the other pages of this blog, I attended a course at my community college to learn the Java programming language. Java is object oriented, allowing for inheritance, polymorphism, and encapsulation. However, after a while of programming in Java, I decided that the inefficient way that it executed would be too much of a burden when I started to write larger programs (and I was starting; one reached about 4000 lines). I began to learn another language: python. Python is a scripting language that has some of the same disadvantages of Java, so after I learned some of the key principles, I began to teach myself my first compiled language: C++.

C++ is object oriented as well. In fact, when it was first created it was called "C with classes". So, using online documentation I began to write a few simple programs in C++.

The C++ Hello World
#include <iostream>
using namespace std;
int main(){
cout << "Hello, world!"<<endl;
return 0;
}

As a reader of this article, you are probably a Java programmer interested in knowing how hard switching to C++ is. Java is designed to be similar to C++, so some may think that it is an easy transition; and it is.

Similarities
The syntax between the two languages is pretty similar. if, switch, int, double, float, short, void, etc. are all the same. This makes porting Java programs into C++ a pretty easy task. Most things that java can do without an import that are not in C++ can also be added with the #include directive. Cstdlib and boost are two other libraries that will provide enough functions to cover pretty much any usage that you will need for common tasks that you may have used in Java.


Differences
In Java, functions (methods) are called in such a fashion as class.func(arg); In C++, functions can be called that way from classes, structures, and unions, but they are commonly called by themselves, like this: func(arg). For functions following this format, it may be difficult to organize functions, which is why C++ offers class support. Also, C++ allows for pass-by-reference with pointers, and the syntax of pointers tend to really confuse newcomers (it confused be a lot. The video below really helps with them.


Also, Java includes its own graphical toolkit. In C++ a third-party library like GTK+ or Qt must be used.

It is also my opinion that no C++ IDE compares to the usefulness of a Java IDE. Eclipse and Netbeans, for example, are huge projects that make development a fun and easy task. With C++ I use Code::Blocks but many stick to vim and their compiler.
My personal experience
At first, it seemed like smooth sailing. However, when I started to do some of the more complicated things (changing parameter values in functions, for instance) I ran into some issues. Pointers were a really hard thing for me to grasp, and I could not see why they were needed. Aside from pointers and the god awful mess that seemed to be  the C++ library, it has been a surprisingly easy transition from Java to C++ and anybody looking to attempt it should have no trouble. To travel from C++ to Java, you will probably have no issues whatsoever, other than finding the equivalents to  functions in the C++ library.