Насчет формирования суммы прописью, отдаю свою как есть. Только писал давно, зеленый был, ногами сильно не бить )))
QString CModDocs::priceToText(double price)
{
    if(price > 20000000) return tr("Не могу посчитать такие большие деньги ...");
    unsigned long int rub = (int)price;
    int kop = int(price*100) - rub*100;
    if(rub == 0) return tr("Ноль рублей %1 коп.").arg(kop);
    QString ret("");
    QStringList sotni;
    sotni.append(tr(""));
    sotni.append(tr("сто "));
    sotni.append(tr("двести "));
    sotni.append(tr("триста "));
    sotni.append(tr("четыреста "));
    sotni.append(tr("пятьсот "));
    sotni.append(tr("шестьсот "));
    sotni.append(tr("семьсот "));
    sotni.append(tr("восемьсот "));
    sotni.append(tr("девятьсот "));
    QStringList desatki;
    desatki.append(tr(""));
    desatki.append(tr("десять "));
    desatki.append(tr("двадцать "));
    desatki.append(tr("тридцать "));
    desatki.append(tr("сорок "));
    desatki.append(tr("пятьдесят "));
    desatki.append(tr("шестьдесят "));
    desatki.append(tr("семьдесят "));
    desatki.append(tr("восемьдесят "));
    desatki.append(tr("девяносто "));
    QStringList edinic;
    edinic.append(tr(""));
    edinic.append(tr("один "));
    edinic.append(tr("два "));
    edinic.append(tr("три "));
    edinic.append(tr("четыре "));
    edinic.append(tr("пять "));
    edinic.append(tr("шесть "));
    edinic.append(tr("семь "));
    edinic.append(tr("восемь "));
    edinic.append(tr("девять "));
    QStringList edinic_10;
    edinic_10.append(tr("десять "));
    edinic_10.append(tr("одиннадцать "));
    edinic_10.append(tr("двенадцать "));
    edinic_10.append(tr("тринадцать "));
    edinic_10.append(tr("четырнадцать "));
    edinic_10.append(tr("пятнадцать "));
    edinic_10.append(tr("шестнадцать "));
    edinic_10.append(tr("семнадцать "));
    edinic_10.append(tr("восемнадцать "));
    edinic_10.append(tr("девятнадцать "));
    int r[9], i;	// в r индексы - номера разрядов
    for(i=0; i<9; i++) if(rub>0)
            {
                r[i] = rub%10; rub = rub/10;
            }else r[i]=0;
    if(r[8]>0 || r[7]>0 || r[6]>0){
        ret += sotni[r[8]];
        if( r[7]==1 ) ret += edinic_10[r[6]] + tr("милионов ");
        else{
            ret += desatki[r[7]] + edinic[r[6]];
            if(r[6] == 1) ret += tr("милион ");
            else if(r[6]==2 || r[6]==3 || r[6]==4) ret += tr("милиона ");
            else ret += tr("милионов ");
        }
    }
    if(r[5]>0 || r[4]>0 || r[3]>0){
        ret += sotni[r[5]];
        if(r[4] == 1) ret += edinic_10[r[3]] + tr("тысяч ");
        else{
            ret += desatki[r[4]];
            if(r[3] == 1) ret += tr("одна тысяча ");
            else if( r[3]==2 ) ret += tr("две тысячи ");
            else{
                ret += edinic[r[3]];
                if( r[3]==3 || r[3]==4) ret += tr("тысячи "); else ret += tr("тысяч ");
            }
        }
    }
    ret += sotni[r[2]];
    if( r[1]==1 ) ret += edinic_10[r[0]] + tr("рублей ");
    else{
        ret += desatki[r[1]] + edinic[r[0]];
        if(r[0] == 1) ret += tr("рубль ");
        else if(r[0]==2 || r[0]==3 || r[0]==4) ret += tr("рубля ");
        else ret += tr("рублей ");
    }
    ret += tr(" %1 коп.").arg(kop);
    ret[0] = ret[0].toUpper();
    return ret;
}