My first attempt to create a calculator as a novice in Qt programming
-
- QDialog is a specialized case of QWidget. You don't have to subclass it if you don't use its features (which you don't seem to). In this case QWidget would be enough (but change it in both .h and .cpp if you do).
- You don't use any of special QDialog features so it doesn't matter.
- No, It means you provided a default argument in the constructor implementation in the .cpp file. Default arguments go only in the header:
//the header: My_First_Calculator(const QStringList& texts ,QWidget* parent = 0); //the implementation: My_First_Calculator::My_First_Calculator(const QStringList& texts, QWidget* parent) : QDialog(parent) //no = 0 here
- The signal mapper looks to be hooked up correctly, but you don't connect anything to the
clicked()
signal of your class so nothing will actually happen.
-
you don't connect anything to the clicked() signal of your class so nothing will actually happen.
Yes, you are right. Nothing happens.
But I've used the followingconnect
inMy_First_Calculator.cpp
. Don't you mean this?connect(signalMapper, SIGNAL(mapped(QString)), this, SIGNAL(clicked(QString)));
-
Yes, when signal mapper emits
mapped
your widget emitsclicked
and that's it. No one is connected to that signal so nothing happens.
I think what you meant to do is to hook the signal mapper to ashow_number
slot://header private slots: void show_number(const QSring& text); //cpp void My_First_Calculator::show_number(const QSring& text) { lineEdit -> setText(text); }
and connect it like this:
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(show_number(QString)));
-
@Chris-Kawa
Thank you. It works as is expected now.I also removed
signals: void clicked(const QString& text);
in .h file because I though it was useless.
Another question. (Please excuse me for asking those many questions)
Do I need to essentially inherit from QDialog, that is, can't I remove it this way:class My_First_Calculator { Q_OBJECT
?
-
can't I remove it this way
No, you can't. You need a window that you can show, You need to be able to put widgets in it, you need a layout etc. All those things are functions of a QWidget (QDialog is a subclass of QWidget).
Look in themain()
function. There'smyCal.show();
.show()
is a method of a QWidget. Look in the constructor. There'ssetLayout(layout);
.setLayout()
is a method of QWidget. There's alsoconnect(...
.connect()
is also a method of QWidget. There are more examples but the answer is no, you need to at least inherit from QWidget. -
Hello guys, I'm back to this thread. :)
I had a very little time for Qt (I'm involving many aspects of CS and scheduled my works :)) using which I went a few steps on the process of developing my fist app the way I mentioned in the first post of this thread.
Anyway, Thanks for your patient and we will go to the game!
The changes I make (just using the experience I have on C++) are as follows:
My_First_Calculator.h
#ifndef MY_FIRST_CALCULATOR_H #define MY_FIRST_CALCULATOR_H #include <QDialog> #include <QSignalMapper> #include <QStringList> class QLineEdit; class My_First_Calculator : public QDialog { Q_OBJECT public: My_First_Calculator(const QStringList& texts ,QWidget* parent = 0); private slots: void show_number(const QString&); void reset(); private: QLineEdit* lineEdit; QSignalMapper* signalMapper; QString temp_text; }; #endif // MY_FIRST_CALCULATOR_H
My_First_Calculator.cpp
:#include <QtWidgets> #include "my_first_calculator.h" My_First_Calculator::My_First_Calculator(const QStringList& texts, QWidget* parent) : QDialog(parent) { lineEdit = new QLineEdit; QPushButton* quit = new QPushButton(tr("Close")); QPushButton* clear = new QPushButton(tr("C")); signalMapper = new QSignalMapper(this); QGridLayout* gridLayout = new QGridLayout; for(int i=0; i<texts.size(); ++i) { QPushButton* button = new QPushButton(texts[i]); connect(button, SIGNAL(clicked(bool)), signalMapper, SLOT(map())); signalMapper -> setMapping(button, texts[i]); gridLayout -> addWidget(button, i/3, i%3); } connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(show_number(QString))); connect(quit, SIGNAL(clicked(bool)), this, SLOT(close())); connect(clear, SIGNAL(clicked(bool)), this, SLOT(reset())); QVBoxLayout* layout = new QVBoxLayout; layout -> addWidget(lineEdit); layout -> addLayout(gridLayout); layout -> addWidget(quit); layout -> addWidget(clear); setLayout(layout); } //**************************** void My_First_Calculator::show_number(const QString& text) { if(text == "C") temp_text.clear(); else temp_text.append(text); lineEdit -> setText(temp_text); } //***************************************** void My_First_Calculator::reset() { emit show_number("C"); }
main.cpp
:#include <QApplication> #include "my_first_calculator.h" int main(int argc , char* argv[]) { QApplication app(argc, argv); QStringList texts; texts << "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"; My_First_Calculator myCal(texts); myCal.show(); return app.exec(); }
At any given time, I try to add some more features to the app. but now two questions:)
1- Is there any weak part in the code that should be replaced?
2- Apparently since I didn't use the Designer for it, I can't change the form my mouse! Is it true? If so, what nifty means is there to change the shape of the form? I mean buttons, sizes, or whatsoever?ThankX!
-
Hi
All is debatable but my points would be :
You are using good variable names but Im not crazy with underscores.
Seen code where used a lot and it very hard to read.
Not issue here but now its mentioned.
Also , choose a style for variable naming and use it all over.
QLineEdit* lineEdit; <<< qt style
QSignalMapper* signalMapper; << qt style
QString temp_text; << other styleAlso
void My_First_Calculator::reset()
why send a "c" to show_number to reset?
Why not directlyvoid My_First_Calculator::reset()
{
temp_text.clear();
lineEdit -> setText("");
}- 2- Apparently since I didn't use the Designer
Well if you do not use UI files, then you just adjust from code.
with resize or setGeometry.
However, for app like yours, one would use layout to make it auto scale the buttons to any size if dialog is resized.
http://doc.qt.io/qt-5/layout.html
- 2- Apparently since I didn't use the Designer
-
@mrjj said in My first attempt to create a calculator as a novice in Qt programming:
Hi
All is debatable but my points would be :
You are using good variable names but Im not crazy with underscores.
Seen code where used a lot and it very hard to read.Hi. :)
You are right. It's hard for reading. I will put enough white spaces and comments when it is finished. :)
And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )Not issue here but now its mentioned.
Also , choose a style for variable naming and use it all over.
QLineEdit* lineEdit; <<< qt style
QSignalMapper* signalMapper; << qt style
QString temp_text; << other styleHow to choose a style please?
Also
void My_First_Calculator::reset()
why send a "c" to show_number to reset?
Why not directlyvoid My_First_Calculator::reset()
{
temp_text.clear();
lineEdit -> setText("");
}Yeah, very handy, thanks. I applied it. :)
- 2- Apparently since I didn't use the Designer
Well if you do not use UI files, then you just adjust from code.
with resize or setGeometry.
However, for app like yours, one would use layout to make it auto scale the buttons to any size if dialog is resized.
http://doc.qt.io/qt-5/layout.html
Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
- 2- Apparently since I didn't use the Designer
-
Hi :)
And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )
Means, I don't like so much. ( reading it )
How to choose a style please?
Well, Thats is mostly what you like. Sometimes in teams , we must agree but if you are
working solo then just choose one and stick to it.
Its mostly about if you write it like
SomeName
someName
somename
some_nameso the important part is just to name it the same way each time and not mixing it.
- Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
Those are fine and should make it scale all when you resize the window.
- Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
-
@mrjj said in My first attempt to create a calculator as a novice in Qt programming:
Hi :)
And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )
Means, I don't like so much. ( reading it )
How to choose a style please?
Well, Thats is mostly what you like. Sometimes in teams , we must agree but if you are
working solo then just choose one and stick to it.
Its mostly about if you write it like
SomeName
someName
somename
some_nameso the important part is just to name it the same way each time and not mixing it.
- Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
Those are fine and should make it scale all when you resize the window.
Thank you :)
I put some other widgets as well, like another lineEdit for the results and so on.
Now I come across two other questions. :)1- Assume I have a button like this:
QPushButton* two = new QPushButton(tr("2"))
How do I send that string ("2") to the
show_number(const QString& text)
so that it will be shown by thelineEdit
in theform
when running the program? I mean without using asignalMapper
? Apparently I can't use parameters inconnect
to send for that function. :(2- Consider I want to store the contents the
lineEdit
into a vector of char (so that I will be able to calculate the contents later). How to do it lease?EDITED!
- Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
-
- In the slot:
QString s = reinterpret_cast<QPushButton*>(sender())->text();
- Why? If user enters number 123, why do you want to store this number in a vector like ['1', '2', '3']? It is actually a vector of strings. For that you can split the string, see http://doc.qt.io/qt-5/qstring.html#split
-
@jsulm said in My first attempt to create a calculator as a novice in Qt programming:
- In the slot:
QString s = reinterpret_cast<QPushButton*>(sender())->text();
- Why? If user enters number 123, why do you want to store this number in a vector like ['1', '2', '3']? It is actually a vector of strings. For that you can split the string, see http://doc.qt.io/qt-5/qstring.html#split
Because the user types something like "123+256" so it con't be seemingly stored as a (vector of) int.
Guys, I think the program is much more complicated than these items. The app should be able to separate the operands from operators. And also it should be able to observe the priority of the operators, for example:
2+3*4 to be 14 not 20.What methods would you generally use for each step?
I'm thinking of two tools: first the Dijkstra's algorithm to make the statement a Reverse Polish Notation and then use a stack for calculating. Do you agree?
-
@tomy said in My first attempt to create a calculator as a novice in Qt programming:
Because the user types something like "123+256" so it con't be seemingly stored as a (vector of) int.
But it can be stored as a vector of strings: ["123", "+", "256"] - that's what I said.
Vector of char would be: ['1', '2', '3', '+', '2', '5, '6'] -
@jsulm said in My first attempt to create a calculator as a novice in Qt programming:
@tomy said in My first attempt to create a calculator as a novice in Qt programming:
Because the user types something like "123+256" so it con't be seemingly stored as a (vector of) int.
But it can be stored as a vector of strings: ["123", "+", "256"] - that's what I said.
Vector of char would be: ['1', '2', '3', '+', '2', '5, '6']Buttons send each number as a string; "1", "3", "+" and so on. When the user types "123+256" a string containing "123+256" will be shown on lineEdit. Hence, I should somehow parse to make operators and operands detached. That was why (at the time) I thought of a vector of chars.
But anyway, I'm thinking of a good algorithm to cover expressions like this, that is when we input all of this line once, it makes a correct result:
2+30-12/3+(4^8-1)+sqrt(65)*2.12 -
Hi all,
It's done. :) :) :)
The app is finished and it works fine. Please download it from here:
http://www.4shared.com/file/H5brsoaPce/My_First_Calculator.htmlIt needs only a few .dll files for to be run.
I have some question please:
1- How to change the title of the window from "My_First_Calculator" to "A Qt Calculator!"?
2- I want to design the buttons better from the size, position end etc. How can I do this?
3- Is it possible to make it appear like a professional app? -
@tomy said in My first attempt to create a calculator as a novice in Qt programming:
But anyway, I'm thinking of a good algorithm to cover expressions like this, that is when we input all of this line once, it makes a correct result:
Reverse polish notation is what you're probably searching for. See here.
-
This is a infix to postfix conversion for the 4 basic operations and parenthesis I wrote some time ago. it works just for integers but it's a start. once you have the string in postfix (i.e. reverse polish) the calculation is very easyEdit
Ignore my sh*ty code, see http://rosettacode.org/wiki/Parsing/Shunting-yard_algorithm#C for an idea of converting infix to postfix. thanks @kshegunov for talking some sense into me
-
Thank you guys but the work is done!
I appreciate your reactions so much.
Please help me on these questions:@tomy said in My first attempt to create a calculator as a novice in Qt programming:
Hi all,
It's done. :) :) :)
The app is finished and it works fine. Please download it from here:
http://www.4shared.com/file/H5brsoaPce/My_First_Calculator.htmlIt needs only a few .dll files for to be run.
I have some question please:
1- How to change the title of the window from "My_First_Calculator" to "A Qt Calculator!"?
2- I want to design the buttons better from the size, position end etc. How can I do this?
3- Is it possible to make it appear like a professional app? -
@tomy said in My first attempt to create a calculator as a novice in Qt programming:
How to change the title of the window from "My_First_Calculator" to "A Qt Calculator!"?
You can use
QWidget::setText
on the main window. That should work.I want to design the buttons better from the size, position end etc. How can I do this?
I haven't downloaded the code as I haven't the time to check it out just now, but putting the widgets in layouts should arrange them well.
Is it possible to make it appear like a professional app?
Well, you could polish the look a bit with a stylesheet, look up the docs on them.