Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Калькулятор из книги Макса Шлее


Автор: Greiv 22.9.2010, 23:10
Всем привет.

В общем проблема в следующем. Просто вводя код калькулятора из книги выше упомянутого автора с небольшими своими изменениями(не чего серьёзного), код запускается но не считает и вообще работает как то коряво в общем, кнопок не слушает вообще, замучился разбирать косяк найти не могу может знатоки помогут вот коды исходных файлов моих.

main.cpp
Код


#include <QApplication>
//#include
#include "calculatorform.h"
#include<QtGui>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    calculatorform Calculatorform;

    Calculatorform.setWindowTitle("Calculator");
    Calculatorform.resize(230, 200);

    Calculatorform.show();
    return app.exec();
}


calculatorform.h

Код

#ifndef CALCULATORFORM_H
#define CALCULATORFORM_H
#include <QObject>
#include <QWidget>
#include <QStack>
#include <QLCDNumber>
#include <QPushButton>
class QLCDm_plcdder;
class QPushButton;

//++++++++++++++++++++++++++++++++++++++++++

class calculatorform : public QWidget {
    Q_OBJECT
private:
    QLCDNumber*  m_plcd;
    QStack <QString> m_stk;
    QString m_strDisplay;

public:

    calculatorform (QWidget* pwgt=0);

    QPushButton* createButton(const QString& str);
    void calculate ();

public slots:
    void slotButtonClicked();
};

#endif //CALCULATORFORM_H


calculatorform.cpp

Код

#include "calculatorform.h"
#include<QGridLayout>
#include <QRegExp>
calculatorform::calculatorform(QWidget*pwgt/*=0*/):QWidget(pwgt)
{
m_plcd= new QLCDNumber(12);
m_plcd->setSegmentStyle(QLCDNumber::Flat);
        m_plcd->setMinimumSize(150, 50);

        QChar aButtons [4][4]={{'7', '8', '9','/'},
                               {'4', '5', '6', '*'},
                               {'1', '2', '3', '-'},
                               {'0', '.', '=', '+'}
        };

        //Layout setup
        QGridLayout* ptorLayout = new QGridLayout;
        ptorLayout->addWidget(m_plcd , 0, 0, 1, 4);
        ptorLayout->addWidget(createButton("CE"), 1, 3);

        for(int i=0; i<4; ++i){
            for (int j=0; j<4; ++j){
                ptorLayout->addWidget(createButton(aButtons[i][j]), i+2, j);

            }
        }
        setLayout(ptorLayout);
    }
QPushButton*calculatorform::createButton(const QString& str)
{
QPushButton* pcmd=new QPushButton(str);
pcmd->setMinimumSize(40, 40);
connect (pcmd , SIGNAL(clicked()), SLOT(slotButtonClicked()));
return pcmd;
}
void calculatorform::calculate ()
{
    double dOperand1 =m_stk.pop().toDouble();
    QString strOperand = m_stk.pop();
    double dOperand2 = m_stk.pop().toDouble();
    double dResult=0;

    if(strOperand=="+"){
        dResult=dOperand1+dOperand2;
    }
    if(strOperand=="-"){
        dResult=dOperand1-dOperand2;
    }
    if(strOperand=="/"){
        dResult=dOperand1/dOperand2;
    }
    if(strOperand=="*"){
        dResult=dOperand1*dOperand2;
    }
    m_plcd->display(dResult);
}

void calculatorform::slotButtonClicked()
{
QString str =((QPushButton*)sender())->text();

if (str=="CE")
{
    m_stk.clear();
    m_strDisplay="";
    m_plcd->display("0");
    return;
}
if (str.contains(QRegExp("[0-9]")))
{
    m_strDisplay+=str;
    m_plcd->display(m_strDisplay.toDouble());
}
else if (str ==".")
{
    m_strDisplay+= str;
    m_plcd->display (m_strDisplay);
}
else{
    if (m_stk.count()>=2)
    {
   m_stk.push(QString().setNum(m_plcd->value()));
    calculate();
    m_stk.clear();
    m_stk.push(QString().setNum(m_plcd->value()));
    if(str!="=")
    {
        m_stk.push(str);
}
}
else{
    m_stk.push(QString().setNum(m_plcd->value()));
    m_strDisplay="";
    m_plcd->display("0");
}
}
}


И ещё пожалуйста объясните 2 момента для чего здесь стоит звёздочка?
Код
QPushButton*calculatorform::createButton(const QString& str) 

И для чего нужно вот это 
Код
calculatorform Calculatorform

Автор: RedDigger 24.9.2010, 23:51
Цитата(Greiv @ 22.9.2010,  23:10)
Всем привет.

В общем проблема в следующем. Просто вводя код калькулятора из книги выше упомянутого автора с небольшими своими изменениями(не чего серьёзного), код запускается но не считает и вообще работает как то коряво в общем, кнопок не слушает вообще, замучился разбирать косяк найти не могу может знатоки помогут вот коды исходных файлов моих.
Код

void calculatorform::slotButtonClicked()
{
QString str =((QPushButton*)sender())->text();

if (str=="CE")
{
    m_stk.clear();
    m_strDisplay="";
    m_plcd->display("0");
    return;
}
if (str.contains(QRegExp("[0-9]")))
{
    m_strDisplay+=str;
    m_plcd->display(m_strDisplay.toDouble());
}
else if (str ==".")
{
    m_strDisplay+= str;
    m_plcd->display (m_strDisplay);
}
else{
    if (m_stk.count()>=2)
    {
   m_stk.push(QString().setNum(m_plcd->value()));
    calculate();
    m_stk.clear();
    m_stk.push(QString().setNum(m_plcd->value()));
    if(str!="=")
    {
        m_stk.push(str);
}
}
else{
    m_stk.push(QString().setNum(m_plcd->value()));
    m_strDisplay="";
    m_plcd->display("0");
}
}
}


И ещё пожалуйста объясните 2 момента для чего здесь стоит звёздочка?
Код
QPushButton*calculatorform::createButton(const QString& str) 

И для чего нужно вот это 
Код
calculatorform Calculatorform

Проблема у тебя в невнимательности... В функции void slotButtonClicked(); в самом конце где вносится первое значения для подсчета - значение вносится только тогда когда ты нажимаешь на какойлибо знак арифметического действия. Но при  это знак не сохраняешь.. в результате у тебя к подсчету приходит только два числа без знака на что та не знает что делать.. для решения следует применить следующее
Код

else{
    m_stk.push(QString().setNum(m_plcd->value()));
    m_strDisplay="";
    m_stk.push(str);
    m_plcd->display("0");
}


Ответы на вопросы тобою заданные - 
1. 
Код
QPushButton*calculatorform::createButton(const QString& str) 

Эта "звездочка" или "спецификатор памяти" если точнее требуется для того чтобы функция возвращала указатель на объект класса QPushButton
в случае если не указывать "звездочку" то объект получается статическим. Память под него выделяется при старте программы а не при вызове дерективы new.
Создание динамического объекта
Код

QPushButton * button = new QPushButton(parentWidget, ButtonName)

Их можно использовать как массивы.

2. 
Код
calculatorform Calculatorform

В данном случае ты создаешь статический объект класса calculatorform.
Нужно это чтобы твой калькулятор работал.. если данной строки не будет то никогда не отработает конструктор а следовательно все что будет в блоке calculatorform::calculatorform() - можно забыть... 
в общем у тебя ничего не будет.. 


PS RTFM - http://sbp-program.ru/SBP-C-Pointer-Example.htm (в примере терминология страдает но основные понятия открыты великолепно.)

Автор: Greiv 25.9.2010, 00:38
Да спасибо большое за такой исчерпывающий ответ, но так как я только начинаю программировать то естественно я работаю с книгой, и вот в чём дело в книге последний обзац этого кода где у меня ошибка выглядит именно так
Код

else{
    m_stk.push(QString().setNum(m_plcd->value()));
    m_strDisplay="";
    m_plcd->display("0");
}
 
без этого стека который вы мне указали. Брутальная опечатка, видимо редакция одна из первых.

Автор: RedDigger 25.9.2010, 00:43
Цитата(Greiv @ 25.9.2010,  00:38)
Да спасибо большое за такой исчерпывающий ответ, но так как я только начинаю программировать то естественно я работаю с книгой, и вот в чём дело в книге последний обзац этого кода где у меня ошибка выглядит именно так
Код

else{
    m_stk.push(QString().setNum(m_plcd->value()));
    m_strDisplay="";
    m_plcd->display("0");
}
 
без этого стека который вы мне указали. Брутальная опечатка, видимо редакция одна из первых.

Возможно опечатка... Возможно народ специально не поставил данную строку туда, чтоб читатель сам попытался ответить.. В любом случае мы этого думаю не узнаем. Рад что смог помочь. Обращайся если что

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)