6 Replies - 24596 Views - Last Post: 27 October 2010 - 04:09 PM

#1 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Week #20 Challenge: Qt

Post icon  Posted 17 May 2010 - 10:04 PM

Qt Library

Posted Image

Challenge submitted by llemes4011

Challenge
Learn to use one or more of the Qt APIs to create a simple application. (Qt is currently on version 4.6)
  • Graphics
  • OpenGL
  • Scripting
  • XML
  • Unit Testing
  • Networking
  • Database
  • WebKit
  • Multimedia
  • And more!


Introduce the language/technology
"Qt is a cross-platform application and UI framework. Using Qt, you can write web-enabled applications once and deploy them across desktop, mobile and embedded operating systems without rewriting the source code." Qt is fairly easy to learn, and easy to maintain. It is a great UI API for C++ and has been ported to many other programming platforms. You can write the code on one OS, compile it, run it, then compile the same code on a different OS without changing anything, and get the same application. Many popular programs use Qt - VLC, GoogleEarth, The KDE Environment, and Skype.

Ideas
  • Spreadsheet
  • Graphical Tic-Tac-Toe game (or similar game)
  • File Browser
  • Database reader/editor
  • Music player
  • With Qts extensive APIs, you can make just about any kind of application that you want!


Resources
Qt Download Page - The Qt Designer download comes with a built-in help utility, that has a complete documentation available offline.
The Qt Examples page has many examples that go more in depth with Qt's functionality. If you haven't used Qt before, take a look at the Qt Tutorials page.

Other Platforms
  • Qt Jambi -- A Java binding. -- The examples that come with the Qt Creator for Jambi are outstanding.
  • PyQt -- A Python Binding.
  • Listing of other bindings -- There are other bindings for other languages though not quite as well established.


How to get Started
Getting started with Qt may seem a bit complicated. One you write your first couple applications, you start to see a pattern. I'm going to describe the process for making a GUI.

Qt uses C++'s main function, unlike the WIN32 API. But, Qt uses a "QApplication" object within the main function to define the application. (The Qt Classes all start with a capital "Q" to designate their relationship with Qt.) Look at this example:
#include <QtGui> // The Library that contains ALL of the classes that are used to make GUIs

int main(int argc, char **argv){
	QApplication app(argc, argv); // Pass the QApplication the command line args
	/*  Graphical "Widgets" go here */
	return app.exec();
}



Widgets are the components that make up a GUI. Example: A label is a widget, a text field is a widget, the WINDOW is a widget (get the picture? ;) ). When making a GUI application, most of the time your widgets will be in "QMainWindow". While this is the standard Window with a menubar, statusbar, and a central widget, any widget can act as a window, however. See the following:

#include <QtGui> // The Library that contains ALL of the classes that are used to make GUIs

int main(int argc, char **argv){
	QApplication app(argc, argv); // Pass the QApplication the command line args
	QMainWindow *window = new QMainWindow(); // Create a QMainWindow
	window->show(); // Make the window visible
	return app.exec();
}



#include <QtGui> // The Library that contains ALL of the classes that are used to make GUIs

int main(int argc, char **argv){
	QApplication app(argc, argv); // Pass the QApplication the command line args
	QLabel *hello = new QLabel("Hello World!"); // Create a QLabel with text "Hello World!"
	hello->show(); // Make the window visible
	return app.exec();
}



You'll notice that the spinbox is in its own window, as is the mainwindow. Okay, that's it for my tutorial, check out the official Qt Tutorials here. They offer a better, less rushed tutorial, that is much more detailed.


DIC Tutorials:
Beginning Qt Programming pt.1 by Amrykid
Beginning Qt Programming pt.2: Platforms by Amrykid

Is This A Good Question/Topic? 1
  • +

Replies To: Week #20 Challenge: Qt

#2 Fe98  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 1
  • Joined: 02-September 08

Re: Week #20 Challenge: Qt

Posted 17 May 2010 - 11:41 PM

Unless I'm mistaken, isn't this week #20?
Was This Post Helpful? 1
  • +
  • -

#3 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2255
  • View blog
  • Posts: 9,444
  • Joined: 29-May 08

Re: Week #20 Challenge: Qt

Posted 17 May 2010 - 11:45 PM

Thanks for spotting that.
Was This Post Helpful? 0
  • +
  • -

#4 taylorc8  Icon User is offline

  • B&

Reputation: 149
  • View blog
  • Posts: 1,572
  • Joined: 21-July 09

Re: Week #20 Challenge: Qt

Posted 18 May 2010 - 06:24 AM

Posted Image

This is my second QT application.

This is an app to use SMTP to send text messages to mobile phones, two service providers are available provided you have an account with AOL or YAHOO. Select the recipient phone's service provider (required) and it sends the message, or messages. A link to a free service to find a mobile phone's service provider is included as a button near the "Instructions" button.

It works, but I have never used it on any PC but my own, even though I have the proper dependencies included in a .zip archive, because the copyright stuff confused me, and I'm also not responsible for abuse of the system and someone getting banned from AOL or YAHOO; not to mention the phone harassment charge(s).
Was This Post Helpful? 0
  • +
  • -

#5 laserbeak43  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 134
  • Joined: 07-November 09

Re: Week #20 Challenge: Qt

Posted 13 July 2010 - 12:43 PM

crap, missed it...
Was This Post Helpful? 0
  • +
  • -

#6 ladyinblack  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 9
  • View blog
  • Posts: 419
  • Joined: 08-April 09

Re: Week #20 Challenge: Qt

Posted 01 August 2010 - 10:38 PM

Hi, I see nobody posted any piece of code for this challenge. What I got is nowhere near an mp3 player, but something that I thunk up while going through a beginners tutorial of address book, and made my own recipe book. Now, all that needs to be done is to make it an executable.

This program was created using Qt Creator. The first thing to do was to create the interface. The interesting part was to get the QMap functionalities to work as it was slightly different. Since I'm currently doing qt as part of my degree, when I have something more interesting, will put it up here.

recipe.h:
#ifndef RECIPEBOOK_H
#define RECIPEBOOK_H

#include <QWidget>
#include <QMap>
#include "finddialog.h"

class QLabel;
class QLineEdit;
class QTextEdit;
class QPushButton;


class RecipeBook : public QWidget
{
    Q_OBJECT

    public:
        RecipeBook (QWidget * parent = 0);
        enum Mode { NavigationMode, AddingMode, EditMode };

    public slots:
        void addRecipe();
        void submitRecipe();
        void cancel();
        void next();
        void previous();
        void editRecipe();
        void removeRecipe();
        void findRecipe();
        void saveToFile();
        void loadFromFile();
        void exportAsVCard();

    private:
        void updateInterface(Mode mode);
        QLineEdit * nameLine;
        QTextEdit * ingredientsText;
        QTextEdit * methodText;
        QPushButton * addButton;
        QPushButton * submitButton;
        QPushButton * cancelButton;
//        QPushButton * closeButton;
        QMap <QString, QString> ingredient;
        QMap <QString, QString> methods;
        QString oldName;
        QString oldIngredients;
        QString oldMethod;
        QPushButton * nextButton;
        QPushButton * previousButton;
        QPushButton * editButton;
        QPushButton * removeButton;
        QPushButton * findButton;
        Mode currentMode;
        FindDialog * dialog;
        QPushButton * saveButton;
        QPushButton * loadButton;
        QPushButton * exportButton;
};

#endif // RECIPEBOOK_H


recipe.cpp:
#include "recipebook.h"
#include "QtGui"

RecipeBook::RecipeBook(QWidget * parent)
        : QWidget(parent)
{
    QLabel * nameLabel = new QLabel(tr("Recipe name:"));
    nameLine = new QLineEdit;
    nameLine->setReadOnly(true);

    QLabel * ingredientsLabel = new QLabel(tr("Ingredients:"));
    ingredientsText = new QTextEdit;
    ingredientsText->setReadOnly(true);

    QLabel * methodLabel = new QLabel(tr("Method:"));
    methodText = new QTextEdit;
    methodText->setReadOnly(true);

    addButton = new QPushButton(tr("&Add"));
    addButton->show();
    submitButton = new QPushButton(tr("&Submit"));
    submitButton->hide();
    cancelButton = new QPushButton(tr("&Cancel"));
    cancelButton->hide();
//    closeButton = new QPushButton(tr("E&xit"));
//    closeButton->show();
    nextButton = new QPushButton(tr("&Next"));
    nextButton->setEnabled(false);
    previousButton = new QPushButton(tr("&Previous"));
    previousButton->setEnabled(false);

    editButton = new QPushButton(tr("&Edit"));
    editButton->setEnabled(false);
    removeButton = new QPushButton(tr("&Remove"));
    removeButton->setEnabled(false);

    findButton = new QPushButton(tr("&Find"));
    findButton->setEnabled(false);

    dialog = new FindDialog;

    loadButton = new QPushButton(tr("&Load..."));
    loadButton->setToolTip(tr("Load recipe from a file"));
    saveButton = new QPushButton(tr("Sa&ve..."));
    saveButton->setToolTip(tr("Save recipe to a file"));

    exportButton = new QPushButton(tr("E&xport"));
    exportButton->setToolTip(tr("Export as vCard"));
    exportButton->setEnabled(false);

    connect(addButton, SIGNAL(clicked()), this, SLOT(addRecipe()));
    connect(submitButton, SIGNAL(clicked()), this, SLOT(submitRecipe()));
    connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel()));
//    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(nextButton, SIGNAL(clicked()), this, SLOT(next()));
    connect(previousButton, SIGNAL(clicked()), this, SLOT(previous()));
    connect(editButton, SIGNAL(clicked()), this, SLOT(editRecipe()));
    connect(removeButton, SIGNAL(clicked()), this, SLOT(removeRecipe()));
    connect(findButton, SIGNAL(clicked()), this, SLOT(findRecipe()));
    connect(loadButton, SIGNAL(clicked()), this, SLOT(loadFromFile()));
    connect(saveButton, SIGNAL(clicked()), this, SLOT(saveToFile()));
    connect(exportButton, SIGNAL(clicked()), this, SLOT(exportAsVCard()));

    QHBoxLayout * buttonLayout1 = new QHBoxLayout;
    buttonLayout1->addWidget(addButton, Qt::AlignLeft);
    buttonLayout1->addWidget(submitButton);
    buttonLayout1->addWidget(cancelButton);
    buttonLayout1->addStretch();
    QHBoxLayout * buttonHLayout = new QHBoxLayout;
    buttonHLayout->addWidget(editButton);
    buttonHLayout->addWidget(removeButton);
    buttonHLayout->addWidget(exportButton);
    QHBoxLayout * buttonLayout4 = new QHBoxLayout;
    buttonLayout4->addWidget(findButton);
    buttonLayout4->addWidget(loadButton);
    buttonLayout4->addWidget(saveButton);
    QVBoxLayout * buttonVLayout = new QVBoxLayout;
    buttonVLayout->addLayout(buttonHLayout);

    QHBoxLayout * buttonLayout3 = new QHBoxLayout;
    buttonLayout3->addWidget(previousButton);
    buttonLayout3->addWidget(nextButton);

    QGridLayout * mainLayout = new QGridLayout;
    QHBoxLayout * buttonLayout2 = new QHBoxLayout;
    buttonLayout2->addWidget(nameLabel, Qt::AlignLeft);
    buttonLayout2->addWidget(nameLine, Qt::AlignRight);
    buttonLayout2->addStretch();
    mainLayout->addLayout(buttonLayout2, 0, 0);
    mainLayout->addWidget(ingredientsLabel, 1, 0);
    mainLayout->addWidget(ingredientsText, 2, 0);
    mainLayout->addWidget(methodLabel, 1, 1);
    mainLayout->addWidget(methodText, 2, 1);
    mainLayout->addLayout(buttonLayout1, 3, 0);
    mainLayout->addLayout(buttonLayout3, 3, 1);
    mainLayout->addLayout(buttonVLayout, 4, 0);
    mainLayout->addLayout(buttonLayout4, 4, 1);

    setLayout(mainLayout);
    setWindowTitle(tr("Recipe Book"));
}

void RecipeBook::addRecipe()
{
    oldName = nameLine->text();
    oldIngredients = ingredientsText->toPlainText();
    oldMethod = methodText->toPlainText();

    nameLine->clear();
    ingredientsText->clear();
    methodText->clear();

    updateInterface(AddingMode);
}

void RecipeBook::submitRecipe()
{
    QString name = nameLine->text();
    QString ingredients = ingredientsText->toPlainText();
    QString method = methodText->toPlainText();

    if (name == "" || ingredients == "" || method == "")
    {
        QMessageBox::information(this, tr("Empty Field"), tr("Please enter a name and ingredients and method."));
        return;
    }

    if (currentMode == AddingMode)
    {
        if (!ingredient.contains(name))
        {
            ingredient.insert(name, ingredients);

            if (!methods.contains(name))
            {
                methods.insert(name, method);
                QMessageBox::information(this, tr("Add Successful"), tr("\"%1\" has been added to your recipe book.").arg(name));
            }
        }
        else
        {
            QMessageBox::information(this, tr("Add Unsuccessful"), tr("\"%1\" is already in your recipe book.").arg(name));
            return;
        }
    }
    else if (currentMode == EditMode)
    {
        if (oldName != name)
        {
            if (!ingredient.contains(name))
            {
                if (!methods.contains(ingredients))
                {
                    QMessageBox::information(this, tr("Edit Successful"), tr("\"%1\" has been edited in your recipe book.").arg(oldName));
                    ingredient.remove(oldName);
                    ingredient.insert(name, ingredients);
                    methods.remove(oldName);
                    methods.insert(name, method);
                }
            }
            else
            {
                QMessageBox::information(this, tr("Edit Unsuccessful"), tr("Sorry, \"%1\" is already in your recipe book.").arg(name));
            }
        }
        else if (oldIngredients != ingredients)
        {
            QMessageBox::information(this, tr("Edit Successful"), tr("\"%1\" has been edited in your recipe book.").arg(name));
            ingredient[name] = ingredients;
        }
        else if (oldMethod != method)
        {
            QMessageBox::information(this, tr("Edit Successful"), tr("\"%1\" has been edited in your recipe book.").arg(name));
            methods[name] = method;
        }
    }
    updateInterface(NavigationMode);
}

void RecipeBook::cancel()
{
    nameLine->setText(oldName);
    ingredientsText->setText(oldIngredients);
    methodText->setText(oldMethod);
}

void RecipeBook::next()
{
    QString name = nameLine->text();
    QMap<QString, QString>::iterator i = ingredient.find(name);
    QMap<QString, QString>::iterator j = methods.find(name);

    if (i != ingredient.end())
        i++;

    if (i == ingredient.end())
        i = ingredient.begin();

    if (j != methods.end())
        j++;

    if (j == methods.end())
        j = methods.begin();

    nameLine->setText(i.key());
    ingredientsText->setText(i.value());
    nameLine->setText(j.key());
    methodText->setText(j.value());
}

void RecipeBook::previous()
{
    QString name = nameLine->text();
    QMap<QString, QString>::iterator i = ingredient.find(name);
    QMap<QString, QString>::iterator j = methods.find(name);

    if (i == ingredient.end())
    {
        nameLine->clear();
        ingredientsText->clear();
        methodText->clear();
        return;
    }

    if (i == ingredient.begin())
        i = ingredient.end();

    i--;

    if (j == methods.end())
    {
        nameLine->clear();
        ingredientsText->clear();
        methodText->clear();
        return;
    }

    if (j == methods.begin())
        j = methods.end();

    j--;
    nameLine->setText(i.key());
    ingredientsText->setText(i.value());
    nameLine->setText(j.key());
    methodText->setText(j.value());
}

void RecipeBook::editRecipe()
{
    oldName = nameLine->text();
    oldIngredients = ingredientsText->toPlainText();
    oldMethod = methodText->toPlainText();

    updateInterface(EditMode);
}

void RecipeBook::removeRecipe()
{
    QString name = nameLine->text();
    QString ingredients = ingredientsText->toPlainText();
    QString method = methodText->toPlainText();

    if ((ingredient.contains(name)) && (methods.contains(name)))
    {
        int button = QMessageBox::question(this, tr("Confirm Remove"), tr("Are you sure you want to remove \"%1\"?").arg(name), QMessageBox::Yes | QMessageBox::No);

        if (button = QMessageBox::Yes)
        {
            previous();
            ingredient.remove(name);
            methods.remove(name);
            QMessageBox::information(this, tr("Remove Successful"), tr("\"%1\" has been removed from your recipe book.").arg(name));
        }
    }
    updateInterface(NavigationMode);
}

void RecipeBook::findRecipe()
{
    dialog->show();

    if (dialog->exec() == QDialog::Accepted)
    {
        QString recipeName = dialog->getFindText();

        if ((ingredient.contains(recipeName)) && (methods.contains(recipeName)))
        {
            nameLine->setText(recipeName);
            ingredientsText->setText(ingredient.value(recipeName));
            methodText->setText(methods.value(recipeName));
        }
        else
        {
            QMessageBox::information(this, tr("Recipe Not Found"), tr("Sorry, \"%1\" is not in your recipe book.").arg(recipeName));
            return;
        }
    }
    updateInterface(NavigationMode);
}

void RecipeBook::updateInterface(Mode mode)
{
    currentMode = mode;

    switch (currentMode)
    {
        case AddingMode:
        case EditMode:

            nameLine->setReadOnly(false);
            nameLine->setFocus(Qt::OtherFocusReason);
            ingredientsText->setReadOnly(false);
            methodText->setReadOnly(false);

            addButton->setEnabled(false);
            editButton->setEnabled(false);
            removeButton->setEnabled(false);

            nextButton->setEnabled(false);
            previousButton->setEnabled(false);

            submitButton->show();
            cancelButton->show();

            loadButton->setEnabled(false);
            saveButton->setEnabled(false);
            exportButton->setEnabled(false);
            break;

        case NavigationMode:

            if (ingredient.isEmpty())
            {
                if (methods.isEmpty())
                {
                    nameLine->clear();
                    ingredientsText->clear();
                    methodText->clear();
                }
            }

            nameLine->setReadOnly(true);
            ingredientsText->setReadOnly(true);
            methodText->setReadOnly(true);
            addButton->setEnabled(true);

            int number1 = ingredient.size();
            int number2 = methods.size();
            editButton->setEnabled(number1 >= 1 && number2 >= 1);
            removeButton->setEnabled(number1 >= 1 && number2 >= 1);
            nextButton->setEnabled(number1 > 1 && number2 > 1);
            previousButton->setEnabled(number1 > 1 && number2 > 1);
            findButton->setEnabled(number1 > 2 && number2 > 2);

            submitButton->hide();
            cancelButton->hide();

            exportButton->setEnabled(number1 >= 1 && number2 >= 1);

            loadButton->setEnabled(true);
            saveButton->setEnabled(number1 >= 1 && number2 >= 1);
            break;
    }
}

void RecipeBook::saveToFile()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save Recipe Book"), "", tr("Recipe Book (*.rbk);;All Files (*)"));

    if (fileName.isEmpty())
        return;
    else
    {
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly))
        {
            QMessageBox::information(this, tr("Unable to open file"), file.errorString());
        }
        QDataStream out(&file);
        out.setVersion(QDataStream::Qt_4_5);
        out << ingredient << methods;
    }
}

void RecipeBook::loadFromFile()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Recipe Book"), "", tr("Recipe Book (*.rbk);;All Files (*)"));

    if (fileName.isEmpty())
        return;
    else
    {
        QFile file(fileName);

        if (!file.open(QIODevice::ReadOnly))
        {
            QMessageBox::information(this, tr("Unable to open file"), file.errorString());
            return;
        }

        QDataStream in(&file);
        in.setVersion(QDataStream::Qt_4_5);
        ingredient.empty();         // empty existing ingredient key
        methods.empty();            // empty existing method key
        in >> ingredient >> methods;

        if (ingredient.isEmpty() && methods.isEmpty())
        {
            QMessageBox::information(this, tr("No recipes in file"), tr("The file you are attempting to open contains no recipes."));
        }
        else
        {
            QMap<QString, QString>::iterator i = ingredient.begin();
            QMap<QString, QString>::iterator j = methods.begin();
            nameLine->setText(i.key());
            ingredientsText->setText(i.value());
            nameLine->setText(j.key());
            methodText->setText(j.value());
        }
    }
    updateInterface(NavigationMode);
}

void RecipeBook::exportAsVCard()
{
    QString name = nameLine->text();
    QString ingredients = ingredientsText->toPlainText();
    QString method = methodText->toPlainText();

    QString fileName = QFileDialog::getSaveFileName(this, tr("Export Recipe"), "", tr("vCard Files (*.vcf);;All Files (*)"));

    if (fileName.isEmpty())
        return;

    QFile file(fileName);

    if (!file.open(QIODevice::WriteOnly))
    {
        QMessageBox::information(this, tr("Unable to open file"), file.errorString());
        return;
    }

    QTextStream out(&file);

    out << "BEGIN:VCARD" << "\n";
    out << "VERSION:2.1" << "\n";
    out << "NAME: "  << name << "\n";

    ingredients.replace("\n", ";", Qt::CaseInsensitive);
    method.replace("\n", ";", Qt::CaseInsensitive);

    out << "INGREDIENTS: " << ingredients << "\n";
    out << "METHOD: " << method << "\n";
    out << "END:VCARD" << "\n";

    QMessageBox::information(this, tr("Export Successful"), tr("\"%1\" has been exported as a vCard.").arg(name));
}



finddialog.h:
#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>

class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
    Q_OBJECT

    public:
        FindDialog(QWidget * parent = 0);
        QString getFindText();

    public slots:
        void findClicked();

    private:
        QPushButton * findButton;
        QLineEdit * lineEdit;
        QString findText;
};

#endif // FINDDIALOG_H


finddialog.cpp:
#include "finddialog.h"
#include <QtGui>

FindDialog::FindDialog(QWidget * parent)
        : QDialog(parent)
{
    QLabel * findLabel = new QLabel(tr("Enter the name of a recipe:"));
    lineEdit = new QLineEdit;
    findButton = new QPushButton(tr("&Find"));
    findText = "";

    QHBoxLayout * layout = new QHBoxLayout;
    layout->addWidget(findLabel);
    layout->addWidget(lineEdit);
    layout->addWidget(findButton);

    setLayout(layout);
    setWindowTitle(tr("Find a Recipe"));
    connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
    connect(findButton, SIGNAL(clicked()), this, SLOT(accept()));
}

void FindDialog::findClicked()
{
    QString text = lineEdit->text();

    if (text.isEmpty())
    {
        QMessageBox::information(this, tr("Empty Field"), tr("Please enter a name."));
        return;
    }
    else
    {
        findText = text;
        lineEdit->clear();
        hide();
    }
}

QString FindDialog::getFindText()
{
    return findText;
}

Was This Post Helpful? 0
  • +
  • -

#7 Tethik  Icon User is offline

  • D.I.C Head

Reputation: 17
  • View blog
  • Posts: 61
  • Joined: 14-March 10

Re: Week #20 Challenge: Qt

Posted 27 October 2010 - 04:09 PM

I made a sudoku solver (bruteforce) in Qt this summer. Guess I might as well submit it here as this thread is looking somewhat empty.
Code is a bit too long to post in codetags so I ll attach it.

Compiled it with CMAKE in kdevelop4 which I don't have anymore since I switched back from kde to gnome. But I think it's compileable, at least the binary works.

Attached File(s)


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1