Falco's QT Programs

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Falco's QT Programs

Post by Falco Girgis »

I'm starting this topic thanks to my Software Design class (CPE353), where we write QT programs. I must admit that I almost never pay attention in there. For folks like us who are used to game development, this shit is cake. But I will also admit that I think QT is by far the most impressive and versatile GUI development kit that I have seen. Sorry WxWidgets, sorry .NET. QT compiles identically on a PC, Mac, Linux, and even smartphones. The KDE desktop environment for Ubuntu/Kubuntu was written in it.

So without further ado, here it is. The assignment was to make a simple GUI-based encryptor that works by simply shifting letters. I have tested it on Kubuntu and Windows XP, and it is definitely identical:

main.cpp

Code: Select all

/*
    Falco Girgis
    CPE353
    QT Project #1
    9/18/09
*/

#include <QApplication>
#include "EncryptDialog.h"

int main(int argc, char *argv[]) {

    QApplication application(argc, argv);
    //Instantiate the EncryptDialog
    EncryptDialog encryptDialog;
    //Show it
    encryptDialog.show();
    return application.exec();
}
encryptdialog.h

Code: Select all

#ifndef ENCRYPTDIALOG_H
#define ENCRYPTDIALOG_H

#include <QDialog>
#include <QLineEdit>
#include <QLabel>
#include <QSpinBox>

#define MAX_LINE_LENGTH 26
enum ENCRYPTION_STATE { STATE_ENCRYPT, STATE_DECRYPT };

class EncryptDialog: public QDialog {
    Q_OBJECT

public:
    EncryptDialog();

private:
    /*
      Member pointers are for parts of the dialog that need to be
      referred to outside of the constructor for signals and slots.
     */
    QSpinBox *encryptionKeyInput;
    QLineEdit *plainTextInput;
    QLineEdit *cipherTextInput;
    QPushButton *switchButton;
    QPushButton *clearButton;
    QPushButton *quitButton;
    QLabel *encryptKeyLabel;

    ENCRYPTION_STATE state;
    int key;

private slots:
    void Clear();
    void SwitchMode();
    void CipherTextChanged(const QString &string);
    void PlainTextChanged(const QString &string);
    void KeyChanged(int p_key);


};

#endif
encryptdialog.cpp

Code: Select all

#include "EncryptDialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QDebug>
#include <QTextCodec>

/*
  Default constructor for our EncryptDialog window
  */
EncryptDialog::EncryptDialog(): encryptionKeyInput(NULL), plainTextInput(NULL), cipherTextInput(NULL),
switchButton(NULL), clearButton(NULL), quitButton(NULL),state(STATE_ENCRYPT), key(0)  {
    //allocating layouts on the heap
    //Ties mainLayout and everything tied to it to "this" (which in our case would be on the stack.
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    QHBoxLayout *encryptionLayout = new QHBoxLayout();
    QGridLayout *plainCipherTextLayout = new QGridLayout();
    QHBoxLayout *buttonLayout = new QHBoxLayout();

    setWindowTitle(tr("Dialog"));

    //Set up mainLayout
    mainLayout->addLayout(encryptionLayout);
    mainLayout->addStretch();
    mainLayout->addLayout(plainCipherTextLayout);
    mainLayout->addStretch();
    mainLayout->addLayout(buttonLayout);

    //Set up encryptionLayout
    encryptKeyLabel = new QLabel(tr("Encryption Key"));
    encryptionKeyInput = new QSpinBox();
    encryptionKeyInput->setMaximum(25);
    encryptionLayout->addWidget(encryptKeyLabel);
    encryptionLayout->addWidget(encryptionKeyInput);

    //Set up Encrypt/Decrypt layout using a grid
    QLabel *plainTextLabel = new QLabel(tr("Plaintext"));
    plainTextInput = new QLineEdit();
    plainTextInput->setValidator( new QRegExpValidator( QRegExp( "[a-z]+"), this));
    plainTextInput->setMaxLength(MAX_LINE_LENGTH);
    QLabel *cipherTextLabel = new QLabel(tr("Ciphertext"));
    cipherTextInput = new QLineEdit();
    cipherTextInput->setValidator( new QRegExpValidator( QRegExp( "[a-z]+"), this));
    cipherTextInput->setMaxLength(MAX_LINE_LENGTH);
    cipherTextInput->setFrame(false);
    cipherTextInput->setReadOnly(true);
    plainCipherTextLayout->addWidget(plainTextLabel, 0, 0);
    plainCipherTextLayout->addWidget(plainTextInput, 0, 1);
    plainCipherTextLayout->addWidget(cipherTextLabel, 1, 0);
    plainCipherTextLayout->addWidget(cipherTextInput, 1, 1);

    //Set up layout for buttons
    switchButton = new QPushButton(tr("Switch to Decryption Mode"));
    switchButton->setDefault(true);
    clearButton = new QPushButton(tr("Clear"));
    quitButton = new QPushButton(tr("Quit"));
    buttonLayout->addWidget(switchButton);
    buttonLayout->addStretch();
    buttonLayout->addWidget(clearButton);
    buttonLayout->addStretch();
    buttonLayout->addWidget(quitButton);

    //Connect our signals and slots
    connect(quitButton, SIGNAL(clicked()), this, SLOT(accept()));
    connect(clearButton, SIGNAL(clicked()), this, SLOT(Clear()));
    connect(switchButton, SIGNAL(clicked()), this, SLOT(SwitchMode()));
    connect(plainTextInput, SIGNAL(textChanged(const QString&)), this, SLOT(PlainTextChanged(const QString&)));
    connect(cipherTextInput, SIGNAL(textChanged(const QString&)), this, SLOT(CipherTextChanged(const QString&)));
    connect(encryptionKeyInput, SIGNAL(valueChanged(int)), this, SLOT(KeyChanged(int)));
}

/*
  Slot called when the clear button is pressed
  */
void EncryptDialog::Clear() {
    plainTextInput->clear();
    cipherTextInput->clear();
}

/*
  Slot called when the Switch to Encryption/Decryption mode button has been pressed
  */
void EncryptDialog::SwitchMode() {
    switch(state) {
    case STATE_ENCRYPT:
        state = STATE_DECRYPT;
        plainTextInput->setReadOnly(true);
        plainTextInput->setFrame(false);
        cipherTextInput->setReadOnly(false);
        cipherTextInput->setFrame(true);
        cipherTextInput->setFocus();
        switchButton->setText(tr("Switch to Encryption Mode"));
        encryptKeyLabel->setText(tr("Decryption Key"));
        break;
    case STATE_DECRYPT:
        state = STATE_ENCRYPT;
        plainTextInput->setReadOnly(false);
        plainTextInput->setFrame(true);
        plainTextInput->setFocus();
        cipherTextInput->setReadOnly(true);
        cipherTextInput->setFrame(false);
        switchButton->setText(tr("Switch to Decryption Mode"));
        encryptKeyLabel->setText(tr("Encryption Key"));
        break;
    default:
        break;
    }
}

/*
  Slot called when the key spinButton's value has been changed
  */
void EncryptDialog::KeyChanged(int p_key) {
    key = p_key;

    switch(state) {
    case STATE_ENCRYPT:
        PlainTextChanged(plainTextInput->text());
        break;
    case STATE_DECRYPT:
        CipherTextChanged(cipherTextInput->text());
        break;
    }
}

/*
  Slot called when the cipherTextEdit string has changed

  Note about shifting:
  I probably could have been more efficient about this and used
  unicode rather than changing from QString to std::string to char array.
  I learned a lot about string conversions from ascii to unicode this way,
  though.
  */
void EncryptDialog::CipherTextChanged(const QString &string) {
    if(state != STATE_DECRYPT) return;

    QString newString;
    std::string midString;
    midString = string.toStdString();
    char *midderString = (char *)midString.c_str();

    for(unsigned int i = 0; i < midString.length(); ++i) {
        midderString[i] = (midderString[i] - 'a' - key)%26+'a';
        if(midderString[i] < 'a') midderString[i] = 'z'+1-('a'-midderString[i]);
    }

    midString = midderString;
    newString = QString::fromStdString(midString);


    plainTextInput->setText(newString);
}

/*
  Slot called when the plainTextEdit string has changed
  */
void EncryptDialog::PlainTextChanged(const QString &string) {
    if(state != STATE_ENCRYPT) return;
    QString newString;
    std::string midString;
    midString = string.toStdString();
    char *midderString = (char *)midString.c_str();

    for(unsigned int i = 0; i < midString.length(); ++i) {
        midderString[i] = (midderString[i] - 'a' + key)%26+'a';
    }

    midString = midderString;
    newString = QString::fromStdString(midString);

    cipherTextInput->setText(newString);

}
Attached is a screenshot of it running on Windows
Attachments
sshot.PNG
sshot.PNG (9.54 KiB) Viewed 1516 times
User avatar
captjack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 50
Joined: Fri Sep 18, 2009 4:23 pm
Current Project: engine framework
Favorite Gaming Platforms: PC, XBox 360, PS3
Programming Language of Choice: C, C++
Location: Northern Virginia

Re: Falco's QT Programs

Post by captjack »

Has trolltech relaxed their sphincter around their license model? I seem to recall a battle whereby the license was commercial and prevented its inclusion in software covered under the GPL. I haven't touched it since. (Well, that's primarily because I was never interested in what it offered. I may have to re-examine it, now.)


-capt jack
User avatar
hurstshifter
ES Beta Backer
ES Beta Backer
Posts: 713
Joined: Mon Jun 08, 2009 8:33 pm
Favorite Gaming Platforms: SNES
Programming Language of Choice: C/++
Location: Boston, MA
Contact:

Re: Falco's QT Programs

Post by hurstshifter »

I'm really glad you posted this as I've recently begun researching a good toolkit for building gui apps. Has any ever used GTK+ as well as Qt? Any pros or cons for either? I've heard great things about both.
"Time is an illusion. Lunchtime, doubly so."
http://www.thenerdnight.com
K-Bal
ES Beta Backer
ES Beta Backer
Posts: 701
Joined: Sun Mar 15, 2009 3:21 pm
Location: Germany, Aachen
Contact:

Re: Falco's QT Programs

Post by K-Bal »

captjack wrote:Has trolltech relaxed their sphincter around their license model? I seem to recall a battle whereby the license was commercial and prevented its inclusion in software covered under the GPL. I haven't touched it since. (Well, that's primarily because I was never interested in what it offered. I may have to re-examine it, now.)
I think its LGPL since v4.5.
User avatar
M_D_K
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1087
Joined: Tue Oct 28, 2008 10:33 am
Favorite Gaming Platforms: PC
Programming Language of Choice: C/++
Location: UK

Re: Falco's QT Programs

Post by M_D_K »

oh sweet, it's the Caesar cipher aka Caesar shift :)
Gyro Sheen wrote:you pour their inventory onto my life
IRC wrote: <sparda> The routine had a stack overflow, sorry.
<sparda> Apparently the stack was full of shit.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Falco's QT Programs

Post by Falco Girgis »

captjack wrote:Has trolltech relaxed their sphincter around their license model? I seem to recall a battle whereby the license was commercial and prevented its inclusion in software covered under the GPL. I haven't touched it since. (Well, that's primarily because I was never interested in what it offered. I may have to re-examine it, now.)


-capt jack
Yeah, they chilled out. It's LGPL now.
User avatar
captjack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 50
Joined: Fri Sep 18, 2009 4:23 pm
Current Project: engine framework
Favorite Gaming Platforms: PC, XBox 360, PS3
Programming Language of Choice: C, C++
Location: Northern Virginia

Re: Falco's QT Programs

Post by captjack »

GyroVorbis wrote:
captjack wrote:Has trolltech relaxed their sphincter around their license model? I seem to recall a battle whereby the license was commercial and prevented its inclusion in software covered under the GPL. I haven't touched it since. (Well, that's primarily because I was never interested in what it offered. I may have to re-examine it, now.)


-capt jack
Yeah, they chilled out. It's LGPL now.

Nice! I think I might take a stroll through some tutorials.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Falco's QT Programs

Post by Falco Girgis »

I'm not a big fan of GPL myself, I wouldn't be so enthusiastic had they not.
User avatar
imran.hoshimi
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 12
Joined: Mon Dec 01, 2008 4:57 am
Current Project: Nothing. :(
Favorite Gaming Platforms: PC, XBox360, PS2, SNES and almost all of them.
Programming Language of Choice: C/C++
Location: Karachi, Pakistan.
Contact:

Re: Falco's QT Programs

Post by imran.hoshimi »

Can we use the Qt toolkit with VC6 to build the app? I went to their website and found that they also provide their own IDE and designer.
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Falco's QT Programs

Post by avansc »

QT does not even install on OSX Snow Leopard
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Falco's QT Programs

Post by Falco Girgis »

avansc wrote:QT does not even install on OSX Snow Leopard
You've got to be shitting me. Are you serious?
Can we use the Qt toolkit with VC6 to build the app? I went to their website and found that they also provide their own IDE and designer.
Not sure about VC6, but it has project templates for Visual Studio 2008 and Eclipse.
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Falco's QT Programs

Post by avansc »

GyroVorbis wrote:
avansc wrote:QT does not even install on OSX Snow Leopard
You've got to be shitting me. Are you serious?
Can we use the Qt toolkit with VC6 to build the app? I went to their website and found that they also provide their own IDE and designer.
Not sure about VC6, but it has project templates for Visual Studio 2008 and Eclipse.

yeppers. i tried to get it installed. keeps failing at validating packages. its a documented problem.
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
M_D_K
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1087
Joined: Tue Oct 28, 2008 10:33 am
Favorite Gaming Platforms: PC
Programming Language of Choice: C/++
Location: UK

Re: Falco's QT Programs

Post by M_D_K »

It's cause Apple wants you to use Cocoa directly, those assholes.
Gyro Sheen wrote:you pour their inventory onto my life
IRC wrote: <sparda> The routine had a stack overflow, sorry.
<sparda> Apparently the stack was full of shit.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Falco's QT Programs

Post by Falco Girgis »

Just finished my final project in QT (Software Engineering) in CPE353. We were assigned to create a front-end GUI that interacts with a SQL database via QT's SQLite extensions. The database is supposed to be some sort of bank account emulator. Here's the source and a screenshot. Tested on my PC with Windows XP, Kendall's with Windows 7, my Kubuntu box, and the Solaris boxes at the university. Platform independent as hell.

main:

Code: Select all

/*
  Falco Girgis
  CPE353
  Project 05
   11/23/09
 */
#include <QtGui/QApplication>
#include <QtSql>
#include <QTableView>
#include <QDebug>
#include "mainwindow.h"

int main(int argc, char *argv[]) {

    //Load database file
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("bank.db");
    db.setHostName("localhost");

    if(!db.open()) {
        qDebug() << db.lastError();
        qDebug() << "Error: Unable to connect";
    }

    QApplication a(argc, argv);

    BankDialog w;
    w.show();
    return a.exec();
}
maindialog.h

Code: Select all

/*
  Falco Girgis
  CPE353
  Project 05
   11/23/09
 */

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QDialog>
#include <QLabel>
#include <QSpinBox>
#include <QRadioButton>
#include <QLineEdit>
#include <QDateEdit>
#include <QtSql>
#include <QTableView>

class BankDialog: public QDialog {
    Q_OBJECT
public:
    BankDialog();

private:
    QPushButton *submitButton;
    QPushButton *quitButton;
    QLabel      *currentBalance;
    QDateEdit    *dateEdit;
    QRadioButton *depositRadioButton;
    QRadioButton *withdrawRadioButton;
    QLineEdit    *descriptionLineEdit;
    QLineEdit    *amountLineEdit;
    QSqlQueryModel *model;


private slots:
    bool AddTuple();

};

#endif // MAINWINDOW_H
maindialog.cpp

Code: Select all

/*
  Falco Girgis
  CPE353
  Project 05
   11/23/09
 */


#include "mainwindow.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QGroupBox>
#include <QSpinBox>
#include <QDateEdit>
#include <QtSql>
#include <QTableView>
#include <QDebug>

BankDialog::BankDialog() {
    QVBoxLayout *mainLayout;
    QHBoxLayout *controlLayout;
    QHBoxLayout *buttonLayout;
    QTableView *view;
    QSqlQuery *y;

    view = new QTableView();
    buttonLayout = new QHBoxLayout();
    controlLayout = new QHBoxLayout();
    mainLayout = new QVBoxLayout(this);

    setWindowTitle(tr("p05"));

    model = new QSqlQueryModel();
    model->setQuery("SELECT * from accounts");
    view->setModel(model);

    QString balance;
    balance.append("Current Balance is $");
    y = new QSqlQuery("select SUM(amount) FROM accounts");
    if(y->next()) {
        balance.append(y->value(0).toString());
    }
    currentBalance = new QLabel(balance);
    currentBalance->setAlignment(Qt::AlignHCenter);
    //set up mainLayout
    mainLayout->addWidget(view);
    mainLayout->addStretch();
    mainLayout->addWidget(currentBalance);
    mainLayout->addStretch();
    mainLayout->addLayout(controlLayout);
    mainLayout->addStretch();
    mainLayout->addLayout(buttonLayout);

    //set up control layout
    dateEdit = new QDateEdit();
    QHBoxLayout *transactionDateLayout = new QHBoxLayout();
    transactionDateLayout->addWidget(dateEdit);
    QGroupBox *transactionDateGroup = new QGroupBox(tr("Transaction Date"));
    transactionDateGroup->setLayout(transactionDateLayout);
    controlLayout->addWidget(transactionDateGroup);
    controlLayout->addStretch();

    depositRadioButton = new QRadioButton(tr("Deposit"));
    depositRadioButton->setChecked(true);
    withdrawRadioButton = new QRadioButton(tr("Withdrawal"));
    QVBoxLayout *transactionTypeLayout = new QVBoxLayout();
    transactionTypeLayout->addWidget(depositRadioButton);
    transactionTypeLayout->addWidget(withdrawRadioButton);
    QGroupBox *transactionTypeGroup = new QGroupBox(tr("Transaction Type"));
    transactionTypeGroup->setLayout(transactionTypeLayout);
    controlLayout->addWidget(transactionTypeGroup);
    controlLayout->addStretch();

    descriptionLineEdit = new QLineEdit();
    QHBoxLayout *descriptionLayout = new QHBoxLayout();
    descriptionLayout->addWidget(descriptionLineEdit);
    QGroupBox *descriptionGroupBox = new QGroupBox(tr("Description"));
    descriptionGroupBox->setLayout(descriptionLayout);
    controlLayout->addWidget(descriptionGroupBox);
    controlLayout->addStretch();

    amountLineEdit = new QLineEdit();
    amountLineEdit->setValidator(new QRegExpValidator(QRegExp("[1-9]+"), this));
    QHBoxLayout *amountLayout = new QHBoxLayout();
    amountLayout->addWidget(amountLineEdit);
    QGroupBox *amountGroupBox = new QGroupBox(tr("Amount"));
    amountGroupBox->setLayout(amountLayout);
    controlLayout->addWidget(amountGroupBox);

    //set up buttonLayout
    submitButton = new QPushButton(tr("Submit"));
    buttonLayout->addWidget(submitButton);
    buttonLayout->addStretch();
    quitButton = new QPushButton(tr("Quit"));
    buttonLayout->addWidget(quitButton);

    //set up signals and slots
    connect(quitButton, SIGNAL(clicked()), this, SLOT(accept()));
    connect(submitButton, SIGNAL(clicked()), this, SLOT(AddTuple()));

}

/*
  Constructs a query from the given user input and adds an entry to the database.
  The modelview and current balance are both updated.
  Returns 0 if no input has been entered in the description/amount fields.
*/
bool BankDialog::AddTuple() {
   if(descriptionLineEdit->text().length() <= 0) return 0;
   if(amountLineEdit->text().length() <= 0) return 0;

   QString query;
   QSqlQuery q, y;
   query.append("INSERT INTO accounts VALUES('");
   query.append(dateEdit->text());
   query.append("','");
   if(depositRadioButton->isChecked())
   query.append("deposit");
   else query.append("withdrawal");
   query.append("','");
   query.append(descriptionLineEdit->text());
   query.append("',");
   if(withdrawRadioButton->isChecked())
   query.append("-");
   query.append(amountLineEdit->text());
   query.append(")");
   q.exec(query);
   model->setQuery("SELECT * from accounts");

   QString balance;
    balance.append("Current Balance is $");
    y.exec("select SUM(amount) FROM accounts");
    if(y.next()) {
        balance.append(y.value(0).toString());
    }
    currentBalance->setText(balance);


   return 1;
}
and now the rest of the semester (other than studying for finals), I am officially freeeeee!!
Attachments
qtsshot.png
qtsshot.png (14.83 KiB) Viewed 1235 times
User avatar
Innerscope
Chaos Rift Junior
Chaos Rift Junior
Posts: 200
Joined: Mon May 04, 2009 5:15 pm
Current Project: Gridbug
Favorite Gaming Platforms: NES, SNES
Programming Language of Choice: Obj-C, C++
Location: Emeryville, CA
Contact:

Re: Falco's QT Programs

Post by Innerscope »

avansc wrote:QT does not even install on OSX Snow Leopard
I installed it on my machine. (10.6.2)
Although, I do get the warning from "qglobal.h" when I build:

Code: Select all

#  if (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_6)
#    warning "Support for this version of Mac OS X is still preliminary"
#  endif
Current Project: Gridbug
Website (under construction) : http://www.timcool.me
Post Reply