PDA

View Full Version : Custom widgets in layout



Palmik
18th January 2009, 14:10
Hi... I have class called EncrypterBody its parent is QWidget and It contains widgets like QPushButton, QTextEdit, etc defined in its constructor as well as its its own layout. Now I want have two objects of EncrypterBody class been shown in one window one under the other.

Something like this :)


--------------------------------------
| |
--------------------------------------
| |---------|
| |---------|
| |---------|
| | |
-------------------------------------|
--------------------------------------
| |
--------------------------------------
| |---------|
| |---------|
| |---------|
| | |
-------------------------------------|


I also tried to make class "layout" (which parent was QVBoxLayout) in which constructor I created two instances of EncrypterBody and then I tried to add them to the layout via addWidget.

I can easily manage to show two objects of EncryterBody in two separated windows, but to show them in one seems to be too hard for newbie of my caliber :P

rexi
18th January 2009, 15:35
You cannot show a layout only. A layout is something you apply to widgets to tell them how to place their contents.

What you need to do is


create a window, e.g. QDialog
set it's layout using QDialog::setLayout() to QVBoxLayout
add your widgets to this layout (see QWidget::setLayout() for an example of how to do so)


You do not need to create a class that inherits QVBoxLayout.

For more information on layouts you should read the according section from the Qt documentation (http://doc.trolltech.com/4.4/layout.html).

radek.z
18th January 2009, 16:00
Hi,
the main problem is in constructor of you class EncrypterBody
You actually forgot to show your gridLayout. Pass 'this' in constructor of QGridLayout object (line 1 here)


// UspořádánÃ* layoutu
QGridLayout *layoutBody = new QGridLayout(this);
layoutBody->addWidget(keyPublic, 0, 0, 1, 1);
layoutBody->addWidget(openFileName, 1, 0, 1, 1);
layoutBody->addWidget(text, 2, 0, 2, 1);
layoutBody->addLayout(layoutButtons, 2, 1);
layoutBody->setRowMinimumHeight(3, TEXT_H - (3 * BUTT_H + 8));

this solves your problem. So you don't have to do another class Layout (if you really dont want it for some reason). It could be enough to do it in main like this


#include <QApplication>
#include <QtGui>

#include "sifrator.h"

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

QWidget mainWindow;
mainWindow.show();

EncrypterBody *partEncryption = new EncrypterBody(&mainWindow);
EncrypterBody *partDecryption = new EncrypterBody(&mainWindow);

QObject::connect(partEncryption, SIGNAL(clickedTranslate(QString)), partDecryption, SLOT(setText(QString)));

QVBoxLayout *layout = new QVBoxLayout(&mainWindow);

layout->addWidget(partEncryption);
layout->addWidget(partDecryption);

return sifrator.exec();
}

It was working for me.

Tak preji hodne zdaru

ahoj

Palmik
18th January 2009, 17:25
Ok, I tried what you said and It works... for other who might learn from mistakes of mine :)
This is the new code of main.cpp layout.h and layout.cpp exists no more :P


#include <QApplication>
#include <QVBoxLayout>
#include <QDialog>
//#include <QWidget>

#include "sifrator.h"

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

QDialog *window = new QDialog;
EncrypterBody *partEncryption = new EncrypterBody;
EncrypterBody *partDecryption = new EncrypterBody;

QObject::connect(partEncryption, SIGNAL(clickedTranslate(QString)), partDecryption, SLOT(setText(QString)));

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(partEncryption);
layout->addWidget(partDecryption);

window->setLayout(layout);
window->show();

return sifrator.exec();
}


Edit: Radek.z was faster, sorry I did not refreshed the page before posting :D
Thank you guys :)

Palmik
21st January 2009, 12:40
When you helped me to solve my previous problem, second problem occurred.
Since I am writing this program for learning purposes I am trying to put here as much things as possible :P

This problem is connected to signals and slots
I have class EncryptedBody and class Rsa. In Rsa class I have 4 problematic signals


void encryptbarChange(int value);
void encryptbarMaximum(int value);
void decryptbarChange(int value);
void decryptbarMaximum(int value);

those are emitted in two functions


// String čÃ*slic převede na tring znaků
QString Rsa::toCharacters(QString textEncrypted)
{
QString textNormal;
QTextStream out(&textNormal);
int i = (digitsN - 1); // počet čÃ*slic reprezentujÃ*cÃ* jeden znak - 1
int cNumber = 0;
int cDigit;

int size = textEncrypted.size();
emit decryptbarMaximum(size);

for (int o = 0; o < textEncrypted.size(); o++)
{
QChar cChar_ = textEncrypted.data()[o]; // Vezme znak z QString na pozici o a vrátÃ* ho jako QChar
char cChar = cChar_.toLatin1(); // Převede QChar na char
cDigit = atoi(&cChar); // Převede char na int

cNumber += cDigit * pow(10, i); // Např. 123 = (1 * 10 ^ 2) + (2 * 10 ^ 1) + (1 * 10 ^ 0) --> tento cyklus spojÃ* čÃ*slice v čÃ*slo
i--;

if (i == -1) // Pokud je i, které sloužÃ* jako exponent rovno -1 čÃ*slo je hotovo a jedem od začátku
{
cNumber = decryption(cNumber);
textNormal.append(cNumber);
i = (digitsN - 1);
cNumber = 0;
}
emit decryptbarChange(o);
}
return textNormal;
}




// String znaků převede na string čÃ*slic (jeden znak je pak pořadÃ* x čÃ*slic, kde x je počet čÃ*slic v N), zachovává bÃ*lé znaky
QString Rsa::toDigits(QString textNormal)
{
QString textEncrypted;
QTextStream out(&textEncrypted);
int size = textNormal.size();

emit encryptbarMaximum(size);

for (int i = 0; i < size; i++)
{
QChar cChar = textNormal.data()[i];
ulong cNumber = encryption(cChar.unicode()); // Převede znak na čÃ*slo a zaÅ¡ifruje ho.... encryption(cChar.unicode())

for (uint o = 1; o < digitsN; o++)
{
if (cNumber < pow(10, o))
{
textEncrypted.append('0');
}
}
out << cNumber;

emit encryptbarChange(i);
}
return textEncrypted;
}


I am connecting this signals in EncryptedBody class to two slots


void EncrypterBody::textDecryption()
{
ulong n = keyNumber(key_1->text());
uint d = keyNumber(key_2->text());

/*if (x > y)
{
uint n = x;
uint e = y;
//Rsa encryption = Rsa(false, n, d);
}
else
{
uint n = y;
uint e = x;
//Rsa encryption = Rsa(false, n, d);
}*/

Rsa *decryption = new Rsa(0, false, n, d);

QString textEncrypted = text->toPlainText();
QString textNormal = decryption->toCharacters(textEncrypted);

QObject::connect(decryption, SIGNAL(decryptbarMaximum(int)), this, SLOT(setProgressBarMaximum(int)));
QObject::connect(decryption, SIGNAL(decryptbarChange(int)), this, SLOT(setProgressBarValue(int)));
emit clickedTranslate(textNormal);
}




void EncrypterBody::textEncryption()
{
ulong n = keyNumber(key_1->text());
uint e = keyNumber(key_2->text());

/*if (x > y)
{
uint n = x;
uint e = y;
//Rsa encryption = Rsa(true, n, e);
}
else
{
uint n = y;
uint e = x;
//Rsa encryption = Rsa(true, n, e);
}*/

Rsa *encryption = new Rsa(0, true, n, e);

QString textNormal = text->toPlainText();
QString textEncrypted = encryption->toDigits(textNormal);

QObject::connect(encryption, SIGNAL(encryptbarMaximum(int)), this, SLOT(setProgressBarMaximum(int)));
QObject::connect(encryption, SIGNAL(encryptbarChange(int)), this, SLOT(setProgressBarValue(int)));
emit clickedTranslate(textEncrypted);
}


and finaly in main.cpp I have this


EncrypterBody *partEncryption = new EncrypterBody(0, true);
EncrypterBody *partDecryption = new EncrypterBody(0, false);

QObject::connect(partEncryption, SIGNAL(clickedTranslate(QString)), partDecryption, SLOT(setText(QString)));
QObject::connect(partDecryption, SIGNAL(clickedTranslate(QString)), partEncryption, SLOT(setText(QString)));

I have no problems with calling setText(QString) via clickedTranslate(QString) signal, but I have problems with setting max value a current value of progress bar which is shown, but it does not update when I click Translate button, which should emit clickedTranslated() which calls textEncryption() / textDecryption() in EncryptedBody class and those (textEncryption() /textDecryption()) use functions from Rsa class for encryption decryption and this functions should be emitting decryptbarChange(int), encryptbarChange(int), decryptbarMaximum(int), encryptbarChange(int)

radek.z
22nd January 2009, 14:36
Hi,

what is an encryption, which you connecting in line 177 and 178 of your sifrator.cpp file. Is it a member?
(also decryption in line 206,207 in sifrator.cpp )

radek

Palmik
22nd January 2009, 15:10
It is object of class Rsa... I am creating it on line 176 (the same applies for decryption object of Rsa class on line 205).

Rsa *encryption = new Rsa(0, true, n, e);
When I run it from console it does not say that those signals or slots do not exist. Weird

rexi
22nd January 2009, 22:48
Do I understand you correctly that your problem is that the progress bar is not updating? If you are doing calculations in the GUI thread that take some time, you should call QCoreApplication::processEvents() once in a while to give Qt a chance to update the GUI.

Palmik
23rd January 2009, 05:33
Yeah, you understood it correctly, ty, will try that :)

radek.z
24th January 2009, 10:32
Hi,
did you figure out smthing?
I was looking at this.
in your fnc QString Rsa::toDigits(QString textNormal) I have tried to use

int rec = QObject::receivers(SIGNAL(encryptbarMaximum(int))) ;
qDebug()<<rec;
just after emiting this signal to see if it is connected to slots, and it show 0.
I think you should connect the Rsa object in different way. I tried it in constructor of your EncrypterBody class and it worked, but of course there is a problem with inicialiazing the parametrs of Rsa object, so this you shoudl figure out.

Radek

Palmik
24th January 2009, 17:37
Hi Radek.
With informations you provided I was able to do it :) I have to thank you again :)
Now I just have to figure out why mine power and modulo thing ((x pow y) mod z)) is returning wrong numbers. And also comment the code better as well as do some stylish editing of the code :)
Then I will surely came up with some other feature I would like to implement which wont work of course and then I will have kindly ask you to help me again :D

Btw if you have any advice of improving the code, let me know :)

Code is provided in attachment

radek.z
26th January 2009, 12:08
Hi,
so now the fun work starting, right? ;) .
I dont really feel like to be good in advice for improving code. I just saw that you use czech language for comments so it was easier for me then for smbdy else to help you.
So I wish you good luck and of course you welcome to ask me if some problem will come up. I will try to help you in case I will be able to.