Falco's QT Programs
Posted: Mon Sep 21, 2009 9:58 am
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
encryptdialog.h
encryptdialog.cpp
Attached is a screenshot of it running on Windows
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();
}
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
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);
}