Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.8.0 - Qt Creator : 4.3.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

Un éditeur de factures

Bonjour à tous les développeurs Qt :P
Je désire créer un éditeur de facture qui permettent de gérer l'information de trois manières différentes. ]:D
Je vous explique le topo.
Admettons que l'on dispose déjà d'une interface qui gère la base de donnée clients et également une autre interface qui gère un base de données article (et services).
Le but serrais de créer une troisième interface qui permettent de créer une facture pour des service et des articles présent dans la base article et pour un client également présent dans la base client et de sortir 8) :
1) 1 odf lisible par un open office
2) la même chose mais en PDF.
3) la maj de la base de données des factures bien entendu.

Bon en ce qui concerne la partie base de données pas de soucis je suis rodé.
La ou je nage c'est plutôt pour la mise en forme d'un ODF. 8.(
L'histoire c'est que l'interface que l'on puisse ajouter ou supprimer des articles dans l'interface de création de factures, et que le ODF se génère automatiquement ainsi que le PDF.
Le truc que je ne comprend pas vraiment c'est ceci :

1)commment gérer le nombre de pages avec QTextDoucument
2) la tabulation et QTextDocument (gauche droite et centrée)
3) j'imagine mettre chaque article dans dans QTextBloc
4) Faut-il faire toute la mise en page en HTML ou mettre en page chacun des blocs en HTML et les positionner ensuite à l'aide de QTextCursor
5) comment détecter lorsque on change de page pour répéter l'entête et mettre le pied de page correctement.

8o Mine de rien ça fait déjà pas mal d'infos à gérer et j’aurais bien de qqn qui me donne un fil conducteur histoire que je ne commence pas dans le vide.....

J'attend vos avis avec impatience et m'engage a expliquer chacune des démarches de ce projet pour que les autres utilisateurs puissent en bénéficier O:) .

Merci d'avance pour l'attention que vous porterais à mon projet. :cool:

Gpey

Réponses

  • Si j'avais du temps je ferai bien le projet mais je n'en ai pas suffisamment dsl =/

    En revanche je vais le suivre de près =)
  • Salut ! Alors en vrac :

    Pour ODF, regarder du côté de l'API d'OpenOffice si tu as une librairie quelconque intégrable en C++, ou alors un équivalent des controles COM de Microsoft Office.

    Pour PDF, soit tu fais un template HTML que tu remplis et que tu charges dans une webview, puis tu imprimes ta webview en PDF avec QPrinter, soit tu te renseignes sur l'usage d'une librairie comme Poppler, il me semble que tu peux écrire des PDF avec (lire c'est sûr, mais écrire à revérifier). Ma première option est assez fastidieuse à mettre en oeuvre, mais elle marche (je l'utilise dans un de mes projets, mais je l'ai pas optimisé du tout (manque de temps :$) ).

    Sinon, si ODF peut être créé depuis un HTML, tu peux tout faire en HTML et ensuite choisir de générer soit un ODF soit un PDF ?

    Si jamais tu évolues du côté de la génération de tes fichiers, je pense que tu feras plus d'un heureux en publiant un code de démonstration ici ;)
  • July 2014 modifié
    Merci pour vos réponses. O:)
    @ Loarwenn :

    ce qui me rendrais vraiment service si tu n'as pas trop le temps, c'est que une fois le projet terminé tu me fille un coup de main pour l'optimisation (histoire de pas publier n'importe quoi...)
    Deux cerveaux valent mieux qu'un... :cool:


    @GiveMeMyName

    Je suis entrain d'explorer la technique HTML... car avec QTextDocument et QTextDocumentWriter c'est super facile de générer un ODF et aussi un PDF je pense... j'ai vu un exemple dans les démos de Qt (le petit éditeur de texte) qui me parais vraiment facile à mettre en place. :P

    Mais Voilà... pour mettre mon plan machiavélique à exécution HAHAHAHAHAHAHAh (rire satanique pour ceux (et celles...) qui n’auraient pas compris...) ]:D ]:D ]:D ]:D ]:D ]:D ]:D
    je dois être sur de pouvoir compter les pages, formater les marges et gérer les entêtes et pieds de pages. :D :) :| :( 8.(
    Donc j’espérais un aiguillage dans ce sens la... je pense que les articles en sois seront asse facile à générer en HTML

    Maintenant je vais surement passer pour un bolos.... 8o
    Mais... c'est quoi une API ??????
    tu pourrais m'en dire juste asse pour que je puisse faire des recherches ????? (hey oui je reste un amateur, un amateur acharné mais un amateur quand même.... HAAAAAAAAA mateur... ]:D ).

    Cherchez pas... j'ai les fusibles qui ont grillés a force de me casser les dents la dessus.... 8)

    Merci encore pour vos réponse aussi rapides.

    Gpey
  • Je suis pas sûr d'avoir tout suivi avec le HTML et tout ça, je vois la classe QPdfWriter, est-ce cela que tu utilises pour générer un PDF ?
    Elle dispose des fonctions voulues pour les marges et les nouvelles pages.

    Pour les en-têtes et pied de page, j'image que tu dois les gérer toi même...

    Je n'ai jamais utilisé tout ça donc je ne sais pas mieux te guider, mais ça m'intéresse également de voir où tout ça nous mène :)
  • Je connaissais pas qpdfwriter mais ça semble correspondre à ce qui a été demandé. A creuser, mais je pense que tu vas intéresser de plus en plus de monde :-) sinon pour répondre à ta question une api c'est une bibliothèque, un ensemble d'outils destinés à faciliter les interactions avec un élément particulier.

    Exemple : l'API freebox est un ensemble de fonctions qui permettent d'écrire des programmes pour interagir avec une freebox révolution. Ou encore l'API drop box, qui est un ensemble d'outils qui permettent d'interagir avec des comptes drop box.

    @ ness :

    L'idée du HTML est en fait de faire afficher dans une QWebView ce que l'on veut imprimer en pdf (en faisant un loadContent sur la webview avec le code source HTML correspondant à ce qu'on veut imprimer), puis d'imprimer le contenu de la QWebView avec un QPrinter paramétré pour sortir des documents au format PDF. c'est un peu bricolé mais ça marche plutôt pas mal. Inconvénient, ça ne gère pas les pages nativement. Ce qui du coup renforce mon intérêt pour la classe que tu as mentionné :-) Et je vais sans doute m'y atteler sous peu, sauf si gpey réussit avant à sortir du code :-)
  • Bonsoir tous le monde :D
    Purée je n'imaginais pas faire le buzz à ce point..... :cool:

    Bon alors j'ai pas mal creusé et j'ai déjà quelques réponses.
    Le formatage en HTML sa fonctionne.
    en utilisant QTextCursor, QTextBlockFormat et QPainter (pour les lignes de séparations), sa fonctionne, j’aurais tout bientôt un exemple a proposer, comme ça on pourra en discuter tous ensemble.
    Je dois encore trouver une solution pour la tabulation... mais j'ai deux trois idées... qui devrais marcher avec QTextBlockFormat, a tester.

    Pour ce qui est du PDF ce que vous dite concorde avec mes souvenir.... en fait j'avais fait une fois un test en me basant sur les démo de qt4.8.3, il y avais un éditeur de texte qui permettais de sortir un PDF en genre 2 lignes de code.

    En ce qui concerne le comptage des pages... mon petit doigt me dit que la solution ce trouve Dans QTextCursor... on devrais pouvoir savoir a combien de char on en est dans le document et en extrapoler les pages.... je pense... a tester.

    la ou je nage complètement c'est pour configurer les marges du ODT.... j'arrive bien a générer le document mais par contre il m'est impossible de sortir de la zone de texte du document...
    il vas falloir ce renseigner sur cette API.....

    Bon les gens..... merci encore pour vos réponses....je vous tiens au jus.

    bonne nuit.

    purrée c'est fout ce que j'écris mal quand je suis fatigué. 8)
    bonne nuit
  • gpey said:

    ce qui me rendrais vraiment service si tu n'as pas trop le temps, c'est que une fois le projet terminé tu me fille un coup de main pour l'optimisation (histoire de pas publier n'importe quoi...)
    Avec plaisir =)
  • Si j'essaie de résumer, en partant d'un QTextDocument:

    QTextDocument -> toHtml
    -> toPlainText
    -> QTextDocumentWriter -> ODF
    -> print(QPrinter *) -> Papier
    -> PDFCreator
    -> print(QPdfWriter* ) -> PDF directement
    Il faudrait voir comment ça se passe en pratique, mais je pense que les 3 dernières solutions devraient gérer les pages.

    Edit: pour l'indentation c'est raté :p
  • @ Loarwenn O:)

    Merci bien,
    je bosse à fond dessus.

    @ness ;)
    Merci bien pour ces infos.

    En ce qui concerne le formatage de documents je suis encore entrain de faire des recherches... c'est un peut plus compliqué que ça... mais j'ai trouvé des tas d'outils pour le formatage de documents...
    En effet c'est la stratégie que tu propose que je compte adopter mais la mise en page en plus.

    Sinon en ce qui concerne le comptage des page... j'ai trouvé dans la doc la classe suivante : QAbstractTextDocumentLayout.

    QAbstractTextDoxumentLayout Qt 5.3 ]:D

    a creuser.... je fait encore des tests et espère avoir un premier jet a vous présenter bientôt.

    Merci encore pour votre attention. :cool:
    et vos commentaires :P

    @+

    Gpey
  • Rebonjour tous !

    Concernant la partie génération PDF, j'ai fait ça (très vite fait ^^ ) : Test PDF Qt

    C'est sûrement améilorable, et d'ailleurs si quelqu'un veut prendre le temps d'optimiser / améliorer le truc, n'hésitez pas ^^ Je n'ai pas regardé du côté de l'ODF mais je suis la discussion de près pour la suite ! Gpey, on croit en toi \o/
  • Ca m'a l'air bien. y'a plein de commentaire partout ! :o

    Je l'ai mis de coter =)
  • Je déteste le code sans commentaire donc je me force à en tartiner un peu partout ^^ Si jamais tu l'améliores je veux bien ton retour :)
  • Si on rajoute des lignes pour dépasser une page ça m'imprime dans le pdf à travers tout (j'ai du texte entre les deux page)

    J'ai alors essayé de charge le texte dans QTextDocument, puis de l'imprimer; là la pagination est respectée, les marges et tout
    Par contre le html est mal interprété et le formattage déconne :p
  • Justement je suis tombé sur un truc ce matin : l'attribut @page en css. Je me dis qu'en appliquant une taille style 210 mm * 297 mm ( == A4 Portrait) et des margin, ça peut aider ? En rajoutant aussi dans le style du modèle HTML un "page break after " sur le body ça pourrait peut être le faire, pour le texte entre les pages. Dès que j'ai quelques minutes je teste mes dires :)

    Si quelqu'un a essayé les QPdfWriter, qu'il se fasse connaitre aussi :)
  • Bonjour Tout le monde :lol:
    J'ai pas mal avancé dans la mise en page voici comment je m'y suis pris :
    QTextBlockFormat pour créer des block de text
    QTextCharFormat pour la police la taille etc... on peut y mettre un QFont.
    QTextDoucument.pageCont() pour compter les pages.
    Et bien entendu QTextCursor pour naviguer dans le documents... insérer les trucs etc.....
    Le truc qui serais bonnard de vérifier c'est si c'est formaté correctement avec le pdfwriter......
    je trouve encore deux trois trucs genre j'imagine entrer mes article dans un QTextTableFormat pour aligner dans chacunes des cellules genre lu prix unitaire, la quantités et le prix final etc.... ce qui évite le problème de la tabulation...
    dès que j'ai finni l'entête de ma lettre je vous envoie le code..... comme ça on es tous sur la même longueur d'onde....
    Ha oui.... j'utiliser aussi QPainter pour créer une ligne noire (en fait poir créer une image de linge noir.... et ensuite je l'insert avec QTextDocument->insertImage(maQImage);....

    je vous tiens au jus je pense encore ce soir sinon demain.

    Merci pour vos comms et vos solutions.

    @+

    Gpey
  • Bonjour à vous les développer.
    Je rencontre un soucis avec les tableau dans un ODF........ :(
    c'est comme si le QTextDocumentWriter ne créais pas correctement l'odf... ]:D
    J'ai créer un post ici qui explique mieux le problème et aussi avec quelques photos de mes résultats....
    Dès que aurais résolut ce problème je devrais avoir du concret.

    Donnez moi vis avis et vos solutions merci

    Gpey
  • Bonjours a tous les développeurs Qt :|
    Suite au mauvais résultats de mise en page... pense changer de stratégie.... je vous explique. :/ :( 8.(
    QTextDocumentWriter ne gère pas correctement le formatage de texte. il n'est donc pas possible de générer correctement un ODT....
    En fait le but de créer un fichier .ODT c'était de pouvoir modifier la facture indépendamment du système de génération de facture....
    Du coup je me suis dit la chose suivante.... si plutôt de créer un fichier .odt, on créait un autre format genre .abc (en réalité du html) mais qui s’ouvrirait avec un éditeur créer par nous genre l'éditeur démo de Qt mais modifié a notre sauce (sinon j'ai aussi vu que Loarwenn en avais fait un)...
    Qu'en pensez-vous.
    Je vais créer un post dans la rubrique C++ pour avoir de l'info sur la création d'un nouveau format et l'ouverture par défaut.
    En attendant voici le code de ce que j'ai déjà fait..... peut être qu'il pourra servira qqn.

    #include <QApplication>
    #include <QtGui>
    #include <QString>
    #include <QTextEdit>
    #include <QPrinter>
    #include <QPrintDialog>

    int main(int c, char **v)
    {



    QApplication app(c,v);




    // Création de l'éditeur de texte
    QTextEdit monEdit;

    //création du document
    QTextDocument *monDocument = new QTextDocument(&monEdit);
    monEdit.setDocument(monDocument);


    //création du curseur lié au document
    QTextCursor *monCurseur = new QTextCursor(monDocument);





    //création des différents format de blocks de la facture

    QTextBlockFormat bfRaisonSociale;
    QTextBlockFormat bfDestinatiare;
    QTextBlockFormat bfNumFacture;
    QTextBlockFormat bfDateRef;
    QTextBlockFormat bfTrait;
    QTextBlockFormat bfEnteteArticles;



    //Création des Tables
    QTextTable *ttTableTest;



    //Création de format de table
    QTextTableFormat tfTableTest;



    //Formattage du texte de la raison sociale
    QTextCharFormat cfRaisonSociale;
    cfRaisonSociale.setFont(QFont("Calibri",9,QFont::Normal));



    //formatage du texte du dsetinataire
    QTextCharFormat cfDestinataire;
    cfDestinataire.setFont(QFont("Calibri",11,QFont::Normal));



    //formattage de texte du bloc numéros de factures
    QTextCharFormat cfNumFacture;
    QFont fontNumFacture("Calibri",11,QFont::Bold);
    fontNumFacture.setItalic(true);
    cfNumFacture.setFont(fontNumFacture);



    //Formatge du texte de bloc bfDateRef
    QTextCharFormat cfDateRef;
    cfDateRef.setFont(QFont("Calibri",9,QFont::Normal));


    //création de la variable texte de la raison sociale
    QString strRaisonSociale;
    strRaisonSociale += "Rte des Route 88 \n";
    strRaisonSociale += "CH - 1820 Montreux \n";
    strRaisonSociale += "Tél : +41 (0)21 021 21 21 \n";
    strRaisonSociale += "Mob : +41 (0)79 079 79 79 \n";
    strRaisonSociale += "abcd@1234.ch";



    //Création du destinataire
    QString strDestinataire;
    strDestinataire += "Société \n";
    strDestinataire += "Mon Super Client Sàrl \n";
    strDestinataire += "Rue du pognon 6 \n";
    strDestinataire += "1800 Vevey";



    //Création de la chaine de charactère du numéros de facture
    QString strNumFacture;
    strNumFacture += " Facture n°: abcd1234";



    //Création de la variable QString de DateRef
    QString strDateRef;
    strDateRef += " Date : 10.07.2014 \n";
    strDateRef += " Réf : VI \n";




    //création de la ligne noire de séparation
    QImage imgTrait(642,1, QImage::Format_RGB16);
    QPainter painter(&imgTrait);
    QPen myPen(Qt::black, 1600, Qt::SolidLine);

    painter.setPen(myPen);
    painter.drawLine(0,0,0,800);




    //Mise en forme du document
    //formatage et insertion de l'image de la raison sociale

    monCurseur->insertImage("logo2.bmp");



    //formatage du bloc 'entete
    //bfRaisonSociale.setBackground(Qt::cyan);
    // monCurseur->setBlockFormat(bfRaisonSociale);

    monCurseur->insertBlock(bfRaisonSociale);
    monCurseur->insertText(strRaisonSociale,cfRaisonSociale);



    //formattage du blocl destinataire
    //bfDestinatiare.setBackground(Qt::yellow);
    bfDestinatiare.setLeftMargin(380);
    monCurseur->insertBlock(bfDestinatiare);
    monCurseur->insertText(strDestinataire,cfDestinataire);



    //formatage du block de numéros de facture
    bfNumFacture.setTopMargin(50);
    bfNumFacture.setBottomMargin(0);
    monCurseur->insertBlock(bfNumFacture);
    monCurseur->insertText(strNumFacture,cfNumFacture);


    /*
    //formatage du bloc trait
    //bfTrait.setBackground(Qt::green);
    bfTrait.setBottomMargin(10);
    monCurseur->insertBlock(bfTrait);
    monCurseur->insertImage(imgTrait);

    */

    bfTrait.setBottomMargin(10);
    monCurseur->insertHtml("<hr>");
    monCurseur->insertBlock(bfTrait);
    //Formatage du block bfDateRef
    monCurseur->insertBlock(bfDateRef);
    monCurseur->insertText(strDateRef,cfDateRef);

    //formatage de QTextTableformat
    tfTableTest.setAlignment(Qt::AlignHCenter);
    tfTableTest.setBackground(QColor("#e0e0e0"));
    tfTableTest.setCellPadding(2);
    tfTableTest.setCellSpacing(4);
    tfTableTest.setBorder(2);
    tfTableTest.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);

    //création du tableau de contrainte pour la taille des colonnes
    QVector<QTextLength> contraintes;
    contraintes << QTextLength(QTextLength::FixedLength, 30)
    << QTextLength(QTextLength::FixedLength, 60)
    << QTextLength(QTextLength::FixedLength, 120);
    tfTableTest.setColumnWidthConstraints(contraintes);

    //insertion de la table
    ttTableTest = monCurseur->insertTable(1,3,tfTableTest);



    //pour Compter le nombre de pages.
    //monCurseur->insertText("\nLe nombre de pages : " + QString::number(monDocument->pageCount()) + "\n")

    //Création de l'odf
    QTextDocumentWriter myFinalDoc("test.txt");
    myFinalDoc.write(monDocument);

    //affichage de QTextEdit
    monEdit.show();

    // impression papier
    QPrinter printer(QPrinter::HighResolution);
    QPrintDialog *dlg = new QPrintDialog(&printer);
    if (monEdit.textCursor().hasSelection())
    dlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
    dlg->setWindowTitle("Print Document");
    if (dlg->exec() == QDialog::Accepted) {
    monEdit.print(&printer);
    }
    delete dlg;

    return app.exec();

    }

    Donnez moi vos avis sur la solution que je propose.
    Merci encore pour toute l'attention que vous m'avez accordé. O:)

    Je ne lâche pas l'affaire faut juste trouver le moyen de retomber sur ces pattes. :cool:

    @+
    Gpey
  • Rebonjour à tous les développeurs Qt.
    Je suis entrain de coder en ce moment la partie graphique du projet :D et je rencontre un problème au niveau de l'impression :D :) :/ :| :( 8.( .
    En effet j'ai fait un petit éditeur vite fait qui permet d'entrer le client et les articles.... bref.
    le rendu est correcte sur le QTextEdit, mais lors de l'impression le rendu n'est pas identique a ce que l'on voit dans le QTextEdit..... auriez vous une idée ?
    De plus, la sortie d'application Qt Creator me donne ce message :

    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    QPrinter::metric: Invalid metric command
    Et il y as un petit chiffre 1 en bas a droite de la page (alors que je ne l'ai pas mis là moi...)
    Le résultats en image cis dessous :
    l'image de l'éditeur avec la mise en page correcte :
    image


    et là l'image du scan de la feuille imprimée...avec la mise en page explosée.
    image
  • Bonsoir à tous les développer Qt :P
    Purée ce post devient un monologue 8o
    J'ai résolut tous seul comme un grand mon problème d'impression. 8.( :( :/ :| :) :D :cool: ]:D
    j’aurais bien aimé vos avis par rapport à l'optimisation de ce code....

    alors tout d'abord le problème de la différence entre le résultat l'écran et le résultat imprimé :
    j'avais mis ceci

    this->m_qprPrinter = new QPrinter(QPrinter::HighResolution);
    Et en fait la valeur des marges (en pixel je pense... ) varie en fonction de la résolution...
    Le code suivant fonctionne et j’aurais aimé votre avis sur lequel est le meilleur dans un esprit de portabilité du programme.

    this->m_qprPrinter = new QPrinter(QPrinter::ScreenResolution);

    // ou bien

    this->m_qprPrinter = new QPrinter();
    Je tien aussi à dire que j'ai un peut galéré pour les marges donc, voici comment je m'y suis pris 8)
    Mais avant je vous explique le problème :
    les marges du QTextDocument par défaut à l'impression étaient vraiment trop grandes et sa fait super moche
    j'ai donc redimensionné la page du document avec le code suivant

    this->m_qteFacture->document()->setPageSize(QSizeF(this->m_qprPrinter->pageRect().size()));
    m_qteFacture étant mon textedit.

    Voila j’espère que ce code servira à qqn et que l'un d'entre vous nous débriefera sur l'optimisation de tout .

    Voici ma méthode imprimer au cas ou.

    // impression papier

    // Création de QPrinter et de QPrintDialog
    this->m_qprPrinter = new QPrinter(QPrinter::ScreenResolution);
    this->m_qpdPrintDlg = new QPrintDialog(this->m_qprPrinter,this);

    //Paramétrage de QPrinter a ma sauce (encore merci @GiveMeMyName qui m'a inspiré avec son exemple pdf)
    m_qprPrinter->setColorMode (QPrinter::Color);
    m_qprPrinter->setDoubleSidedPrinting(false);
    m_qprPrinter->setFromTo(0,0);
    m_qprPrinter->setFullPage(true);
    m_qprPrinter->setNumCopies(1);
    m_qprPrinter->setOrientation(QPrinter::Portrait);
    m_qprPrinter->setPageOrder(QPrinter::FirstPageFirst);
    m_qprPrinter->setPageSize(QPrinter::A4);
    m_qprPrinter->setPaperSource(QPrinter::Auto);
    m_qprPrinter->setPrintRange(QPrinter::AllPages);
    m_qprPrinter->setPageMargins(15,10,15,15,QPrinter::Millimeter);



    if (this->m_qteFacture->textCursor().hasSelection())
    this->m_qpdPrintDlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
    this->m_qpdPrintDlg->setWindowTitle("Document à Imprimer");
    if (this->m_qpdPrintDlg->exec() == QDialog::Accepted) {

    //pour paraméter les marge du document comme celle de l'imprimante.m_qteFacture étant mon QTextEdit
    this->m_qteFacture->document()->setPageSize(QSizeF(this->m_qprPrinter->pageRect().size()));
    this->m_qteFacture->document()->print(this->m_qprPrinter);
    }
    delete this->m_qprPrinter;
    delete this->m_qpdPrintDlg;
    Meci d'avance pour votre attetion et merci à ceux qui ont activement participé. O:)
    Vous tiens au courant de l'avancement 8)
    Bonne soirée {)
    Gpey
  • Je suis content que ça t'aie aidé :) Dès que tu auras un code d'essai pour l'export, n'hésite pas à le poster pour qu'on débate dessus :) Garde la foi :)
  • July 2014 modifié
    Bonjour à tous.
    Désolé de la réponse tardive... le Montreux Jazz n'a pas aidé. ]:D
    Je posterais mon code dès que j’aurais trouvé une solution. O:)
    On pourra débattre ]:D

    La je coince juste sur un pu**** de détail.
    J'arrive a insérer une QTextTable dans mon document.... :D mais j'arrive pas a positionner le curseur après la table une fois que je l'ai insérée... 8.( 8o
    des idées ?

    merci encore à tous pour la participation.

    GPEY
  • Pas d'idée, mais on crois en toi ! :)
  • Bonjour à tous les Qteur :lol:

    j'ai trouvé pour mon problème de curseur... c'était tout bête... voila comment j'ai fait.

    //moncurseur est le curseur du document
    //this->m_qtdDocument est mon document
    monCurseur->setPosition(this->m_qtdDocument->lastBlock().position());

    monCurseur->insertText("pouet");
    //pouet s'écris au début de la ligne en dessous de la Table.
    Voila ;)
    Bonne journée à tous
    Gpey
  • Ca avance ! Courage :D
    On te suit de près :)
  • July 2014 modifié
    Bonjour à tous :)
    Bonjour GiveMeMyName :D
    En effet, j'avance bien (en tous cas, du mieux que je peux!) 8)
    J'ai résolut quasiment tous les problèmes auxquels j'ai été confronté et là, je suis entrain de coder la méthode d'insertion de l'article.
    dès que c'est terminé (je pense entre ce soir et demain si je ne rencontre pas de problèmes auxquels je n'ai pas pensé) je vous donne un feedback pour que l'on puisse en discuter tous ensemble.

    Ensuite viendra les deux derniers problèmes à savoir :
    1) l'entête et le pied de page
    2) gérer la taille des page en fonctions de la taille et du nombre d'articles inséré histoire de savoir quand passer à la page suivante (saut de page etc...)

    Une fois la solution trouvée pour ces deux problèmes, normalement tout devrait fonctionner picco bello.
    Alors n'hésitez pas à suivre mon travail et à imaginer des solutions pour les deux points cité précédemment, car j'y serrais confronté tôt ou tard et malgré les recherches effectuées, je n'ai pas encore trouvé de solutions valables.

    Bonne soirée à tous :lol:
  • Voilà :D
    La mise en page est gérée!
    Voici un aperçu de ce que ça donne et le code ( pas encore optimisé) ]:D

    image

    et voici le code

    d'abord le fichier d’entête

    #ifndef EDITEURFACTURE_H
    #define EDITEURFACTURE_H
    #include <QtWidgets>
    #include <QtGui>
    #include <QPrinter>
    #include <QPrintDialog>
    #include <QPrintPreviewDialog>
    #include <QStringList>
    #include <QDebug>
    class EditeurFacture : public QWidget
    {
    Q_OBJECT
    public:
    EditeurFacture();
    ~EditeurFacture();

    // Méthode qui permet d'ajouter le client sur la facture.
    void ajouterClient();

    //Méthode qui permet d'ajouter des articles sur la factur.
    void ajouterArticle();

    //Méthode pour Imprimer la facture.
    void imprimer();

    //Méthode pour enregistrer la facture en PDF.
    void enregistrerPDF();

    //Méthode pour quitter le programme.
    void quitter();

    public slots:

    // slot qui appelle la méthode this->ajouterClient()
    void slotAjouterClient();

    void slotAjouterArticle();

    //slot qui appelle la méthode this->imprimer();
    void slotImprimer();
    private :

    /**< Attributs concernant le client*/
    QComboBox *m_qcbClientStatut;
    QLineEdit *m_qleClientNom;
    QLineEdit *m_qleClientPrenom;
    QLineEdit *m_qleClientAdresse;
    QLineEdit *m_qleClientNpaVille;
    QPushButton *m_qpbAjouterClient;

    /**< Attributs concernant l'article*/
    QLineEdit *m_qleArticleNum;
    QLineEdit *m_qleArticleDenom;
    QLineEdit *m_qleArticleQty;
    QLineEdit *m_qleArticlePrix;
    QTextEdit *m_qteArticleDet;
    QPushButton *m_qpbAjouterArticle;

    /**< Attributs concernant la facture*/
    QTextEdit *m_qteFacture;
    QTextDocument *m_qtdDocument;
    QTextCursor *m_qtcMonCurseur;

    /**< Atributs de mise en page de la fenêtre.*/
    QPushButton *m_qpbImprimer;
    QPushButton *m_qpbQuitter;
    QPrinter *m_qprPrinter;
    QPrintDialog *m_qpdPrintDlg;
    QPainter *m_qpaPainter;
    QGroupBox *m_qgbClient;
    QGroupBox *m_qgbArticle;
    QGroupBox *m_qgbFacture;
    QGridLayout *m_qglLayoutPrincipal;
    QFormLayout *m_qflLyoutClient;
    QFormLayout *m_qflLayoutArticle;
    QVBoxLayout *m_qvblLayoutCliArt;
    QVBoxLayout *m_qvblLayoutFactBout;

    };

    #endif // EDITEURFACTURE_H

    et ensuite le .cpp

    #include "EditeurFacture.h"


    EditeurFacture::EditeurFacture()
    {
    // Initialisation des attributs de la classe
    this->m_qcbClientStatut = new QComboBox();
    this->m_qleClientNom = new QLineEdit();
    this->m_qleClientPrenom = new QLineEdit();
    this->m_qleClientAdresse = new QLineEdit();
    this->m_qleClientNpaVille = new QLineEdit();
    this->m_qpbAjouterClient = new QPushButton("Insérer");
    this->m_qleArticleDenom = new QLineEdit();
    this->m_qleArticleNum = new QLineEdit();
    this->m_qleArticlePrix = new QLineEdit();
    this->m_qleArticleQty = new QLineEdit();
    this->m_qteArticleDet = new QTextEdit();
    this->m_qpbAjouterArticle = new QPushButton("Insérer");
    this->m_qteFacture = new QTextEdit();
    this->m_qpbImprimer = new QPushButton("Imprimer");
    this->m_qpbQuitter = new QPushButton("Quitter");
    this->m_qpaPainter = new QPainter();
    this->m_qgbArticle = new QGroupBox("Article");
    this->m_qgbClient = new QGroupBox("Client");
    this->m_qgbFacture = new QGroupBox("Facture");
    this->m_qglLayoutPrincipal = new QGridLayout();
    this->m_qflLayoutArticle = new QFormLayout();
    this->m_qflLyoutClient = new QFormLayout();
    this->m_qvblLayoutCliArt = new QVBoxLayout();
    this->m_qvblLayoutFactBout = new QVBoxLayout();
    this->m_qtdDocument = new QTextDocument();
    this->m_qtcMonCurseur = new QTextCursor(this->m_qtdDocument);

    //Paramétrage du document
    this->m_qteFacture->setDocument(this->m_qtdDocument);

    //remplissage des champs du combobox;
    QStringList status;
    status << "Monsieur" << "Madame" << "Société";
    this->m_qcbClientStatut->addItems(status);
    this->m_qcbClientStatut->setCurrentIndex(2);



    //Configuration du layout formulaire client.
    this->m_qflLyoutClient->addRow("Status",this->m_qcbClientStatut);
    this->m_qflLyoutClient->addRow("Nom :",this->m_qleClientNom);
    this->m_qflLyoutClient->addRow("Prénom :",this->m_qleClientPrenom);
    this->m_qflLyoutClient->addRow("Adresse :",this->m_qleClientAdresse);
    this->m_qflLyoutClient->addRow("NPA/Localité : ",this->m_qleClientNpaVille);
    this->m_qflLyoutClient->addWidget(this->m_qpbAjouterClient);
    this->m_qflLyoutClient->setFormAlignment(Qt::AlignLeft);


    //Configuration du layout formulaire article
    this->m_qflLayoutArticle->addRow("Num : ",this->m_qleArticleNum);
    this->m_qflLayoutArticle->addRow("Dénomination :", this->m_qleArticleDenom);
    this->m_qflLayoutArticle->addRow("Quantité :",this->m_qleArticleQty);
    this->m_qflLayoutArticle->addRow("PrixUnitaire :",this->m_qleArticlePrix);
    this->m_qflLayoutArticle->addRow("Détails : ", this->m_qteArticleDet);
    this->m_qflLayoutArticle->addWidget(this->m_qpbAjouterArticle);

    //Configuration du layout de la facture.

    this->m_qteFacture->setMinimumWidth(700);
    this->m_qteFacture->setContentsMargins(0,0,0,0);

    this->m_qvblLayoutFactBout->addWidget(this->m_qteFacture);
    this->m_qvblLayoutFactBout->addWidget(this->m_qpbImprimer);

    //Configuration du QGroupBox Client
    this->m_qgbClient->setLayout(this->m_qflLyoutClient);


    //Configuration de QGroupBox Article
    this->m_qgbArticle->setLayout(this->m_qflLayoutArticle);

    //Configuration du QGroupBox Facture
    this->m_qgbFacture->setLayout(this->m_qvblLayoutFactBout);


    //Configuraiton du grid layout
    this->m_qglLayoutPrincipal->addWidget(this->m_qgbClient,0,0,3,3);
    this->m_qglLayoutPrincipal->addWidget(this->m_qgbArticle,3,0,3,3);
    this->m_qglLayoutPrincipal->addWidget(this->m_qgbFacture,0,3,6,100);


    //Configuration de la fenêtre
    this->setWindowTitle("Générateur de facture");
    this->setLayout(this->m_qglLayoutPrincipal);

    //connection au evenements
    this->connect(this->m_qpbAjouterClient,SIGNAL(clicked()),this,SLOT(slotAjouterClient()));
    this->connect(this->m_qpbImprimer,SIGNAL(clicked()),this,SLOT(slotImprimer()));
    this->connect(this->m_qpbAjouterArticle,SIGNAL(clicked()),this,SLOT(slotAjouterArticle()));

    }

    void EditeurFacture::ajouterClient()
    {

    //création des différents format de blocks de la facture
    QTextBlockFormat bfRaisonSociale;
    QTextBlockFormat bfDestinatiare;
    QTextBlockFormat bfNumFacture;
    QTextBlockFormat bfDateRef;
    QTextBlockFormat bfTrait;
    QTextBlockFormat bfEnteteArticles;



    //Création des Tables
    QTextTable *ttTableTest;



    //Création de format de table
    QTextTableFormat tfTableTest;



    //Formattage du texte de la raison sociale
    QTextCharFormat cfRaisonSociale;
    cfRaisonSociale.setFont(QFont("Calibri",9,QFont::Normal));



    //formatage du texte du dsetinataire
    QTextCharFormat cfDestinataire;
    cfDestinataire.setFont(QFont("Calibri",11,QFont::Normal));



    //formattage de texte du bloc numéros de factures
    QTextCharFormat cfNumFacture;
    QFont fontNumFacture("Calibri",11,QFont::Bold);
    fontNumFacture.setItalic(true);
    cfNumFacture.setFont(fontNumFacture);



    //Formatge du texte de bloc bfDateRef
    QTextCharFormat cfDateRef;
    cfDateRef.setFont(QFont("Calibri",9,QFont::Normal));


    //Formatage de texte de Table de l'entete des article
    QTextCharFormat cfEnteteArticle;
    QFont fontEnteteArticle("Calibri",9,QFont::Bold);
    fontEnteteArticle.setItalic(true);
    cfEnteteArticle.setFont(fontEnteteArticle);
    cfEnteteArticle.setLayoutDirection(Qt::RightToLeft);


    //création de la variable texte de la raison sociale
    QString strRaisonSociale;
    strRaisonSociale += "\nAdresse raison social \n";
    strRaisonSociale += "CH - NPA \n";
    strRaisonSociale += "Tél : +41 (0)21 921 21 21 \n";
    strRaisonSociale += "Mob : +41 (0)79 779 79 79 \n";
    strRaisonSociale += "lemail@delamortquitue.ch";



    //Création du destinataire
    QString strDestinataire;
    strDestinataire += this->m_qcbClientStatut->currentText() + " \n";
    strDestinataire += this->m_qleClientNom->text() + " " + this->m_qleClientPrenom->text() + "\n";
    strDestinataire += this->m_qleClientAdresse->text()+ "\n";
    strDestinataire += this->m_qleClientNpaVille->text()+ "\n";



    //Création de la chaine de charactère du numéros de facture
    QString strNumFacture;
    strNumFacture += " Facture n°: abcd1234";



    //Création de la variable QString de DateRef
    QString strDateRef;
    strDateRef += "Date : 10.07.2014 \n";
    strDateRef += "Réf : VI \n";




    //création de la ligne noire de séparation
    QImage imgTrait(660,1, QImage::Format_RGB16);
    QPainter painter(&imgTrait);
    QPen myPen(Qt::black, 1320, Qt::SolidLine);

    painter.setPen(myPen);
    painter.drawLine(0,0,0,660);








    //formatage du bloc 'entete
    //bfRaisonSociale.setBackground(Qt::cyan);
    // this->m_qtcMonCurseur->setBlockFormat(bfRaisonSociale);
    this->m_qtcMonCurseur->beginEditBlock();
    bfRaisonSociale.setLeftMargin(40);
    this->m_qtcMonCurseur->insertBlock(bfRaisonSociale);
    this->m_qtcMonCurseur->insertImage("logo2.bmp");
    this->m_qtcMonCurseur->insertText(strRaisonSociale,cfRaisonSociale);
    this->m_qtcMonCurseur->endEditBlock();



    //formattage du blocl destinataire
    this->m_qtcMonCurseur->beginEditBlock();
    bfDestinatiare.setLeftMargin(420);
    this->m_qtcMonCurseur->insertBlock(bfDestinatiare);
    this->m_qtcMonCurseur->insertText(strDestinataire,cfDestinataire);
    this->m_qtcMonCurseur->endEditBlock();


    //formatage du block de numéros de facture
    this->m_qtcMonCurseur->beginEditBlock();
    bfNumFacture.setTopMargin(50);
    bfNumFacture.setLeftMargin(20);
    this->m_qtcMonCurseur->insertBlock(bfNumFacture);
    this->m_qtcMonCurseur->insertText(strNumFacture,cfNumFacture);
    this->m_qtcMonCurseur->endEditBlock();

    //formatage du bloc trait
    this->m_qtcMonCurseur->beginEditBlock();
    bfTrait.setBackground(Qt::green);
    bfTrait.setLeftMargin(20);
    bfTrait.setBottomMargin(7);
    this->m_qtcMonCurseur->insertBlock(bfTrait);
    this->m_qtcMonCurseur->insertImage(imgTrait);
    this->m_qtcMonCurseur->endEditBlock();



    //Formatage du block bfDateRef
    this->m_qtcMonCurseur->beginEditBlock();
    bfDateRef.setLeftMargin(60);
    bfDateRef.setBottomMargin(5);
    this->m_qtcMonCurseur->insertBlock(bfDateRef);
    this->m_qtcMonCurseur->insertText(strDateRef,cfDateRef);
    this->m_qtcMonCurseur->endEditBlock();



    //formatage de QTextTableformat
    tfTableTest.setAlignment(Qt::AlignLeft);
    //tfTableTest.setBackground(QColor("#e0e0e0"));
    tfTableTest.setLeftMargin(60);
    tfTableTest.setBorder(0);
    tfTableTest.setBorderStyle(QTextFrameFormat::BorderStyle_None);

    //création du tableau de contrainte pour la taille des colonnes
    QVector<QTextLength> contraintes;
    contraintes << QTextLength(QTextLength::FixedLength, 70)
    << QTextLength(QTextLength::FixedLength,250)
    << QTextLength(QTextLength::FixedLength, 30)
    << QTextLength(QTextLength::FixedLength, 60)
    << QTextLength(QTextLength::FixedLength, 60);
    tfTableTest.setColumnWidthConstraints(contraintes);


    //fortmatage du bloc qui gère l'intéreur de cetaines cellules
    QTextBlockFormat testBlockForamt;
    testBlockForamt.setAlignment(Qt::AlignCenter);


    //insertion de la table
    ttTableTest = this->m_qtcMonCurseur->insertTable(1,5,tfTableTest);




    //selection d'une cellule et Remplissage avec des valeures pour le tableau d'entete des articles
    *this->m_qtcMonCurseur = ttTableTest->cellAt(0,0).firstCursorPosition();
    this->m_qtcMonCurseur->insertText("Art n°",cfEnteteArticle);
    *this->m_qtcMonCurseur = ttTableTest->cellAt(0,1).firstCursorPosition();
    this->m_qtcMonCurseur->insertText("Déscriptif",cfEnteteArticle);
    ttTableTest->cellAt(0,2).firstCursorPosition().setBlockFormat(testBlockForamt);
    *this->m_qtcMonCurseur = ttTableTest->cellAt(0,2).firstCursorPosition();
    this->m_qtcMonCurseur->insertText("Q",cfEnteteArticle);
    ttTableTest->cellAt(0,3).firstCursorPosition().setBlockFormat(testBlockForamt);
    *this->m_qtcMonCurseur =ttTableTest->cellAt(0,3).firstCursorPosition();
    this->m_qtcMonCurseur->insertText("PU",cfEnteteArticle);
    ttTableTest->cellAt(0,4).firstCursorPosition().setBlockFormat(testBlockForamt);
    *this->m_qtcMonCurseur = ttTableTest->cellAt(0,4).firstCursorPosition();
    this->m_qtcMonCurseur->insertText("Montant",cfEnteteArticle);


    // sortie du curseur de la table pour le mettre en dessous
    this->m_qtcMonCurseur->setPosition(this->m_qtdDocument->lastBlock().position());

    //insertion d'un nouveau bloc de trait (bloc déja formaté)
    this->m_qtcMonCurseur->insertBlock(bfTrait);
    this->m_qtcMonCurseur->insertImage(imgTrait);






    //pour Compter le nombre de pages.
    //this->m_qtcMonCurseur->insertText("\nLe nombre de pages : " + QString::number(monDocument->pageCount()) + "\n")

    //Création de l'odf

    this->m_qteFacture->update();

    //delete monDocument;
    }

    void EditeurFacture::ajouterArticle()
    {
    //ajout d'un article

    //test de comptage de ligne

    /* int i = this->m_qteArticleDet->document()->blockCount();
    QString recup;
    for(int j = 1;j<= i;j++)
    {
    recup += this->m_qteArticleDet->document()->findBlockByNumber(j-1).text() + "\n";
    }

    this->m_qteArticleDet->setText(recup + QString::number(i));
    */

    //Création des formats de textes pour la ligne principale du tableau
    QTextCharFormat cfLignePrincipale;
    cfLignePrincipale.setFont(QFont("Calibri",10,QFont::Normal));


    //char format pour la description
    QTextCharFormat cfLigneDescription;
    QFont fontLigneDescription("Calibri",8,QFont::Normal);
    fontLigneDescription.setItalic(true);
    cfLigneDescription.setFont(fontLigneDescription);



    //Création du format de block permettant la mise en page de la cellule Q
    QTextBlockFormat bfCelluleQ;
    bfCelluleQ.setAlignment(Qt::AlignCenter);


    //Création du format de block pour la cellule PU
    QTextBlockFormat bfCellulePU;
    bfCellulePU.setAlignment(Qt::AlignRight);

    //Création du format de block pour la cellule Montant
    QTextBlockFormat bfCelluleMontant;
    bfCelluleMontant.setAlignment(Qt::AlignRight);


    //Création du tableau de contraintes pour la longure des cellules
    QVector<QTextLength> contraintesArticle;
    contraintesArticle << QTextLength(QTextLength::FixedLength, 70)
    << QTextLength(QTextLength::FixedLength,250)
    << QTextLength(QTextLength::FixedLength, 30)
    << QTextLength(QTextLength::FixedLength, 60)
    << QTextLength(QTextLength::FixedLength, 60);

    //Création et paramétrage de format de table des article.
    QTextTableFormat tfTableArticle;
    tfTableArticle.setAlignment(Qt::AlignLeft);
    tfTableArticle.setLeftMargin(60);
    tfTableArticle.setTopMargin(10);
    tfTableArticle.setBottomMargin(5);
    tfTableArticle.setBorder(1);
    tfTableArticle.setCellSpacing(0);
    tfTableArticle.setBorderStyle(QTextFrameFormat::BorderStyle_None);
    tfTableArticle.setColumnWidthConstraints(contraintesArticle);

    //calcul du nombre de ligne de la table

    int nbrLignes = this->m_qteArticleDet->document()->blockCount();
    nbrLignes += 1;




    //calcul du montant
    double montant = this->m_qleArticleQty->text().toDouble() * this->m_qleArticlePrix->text().toDouble();

    //Création et insertion de la table de la table
    QTextTable *ttTableArticle = new QTextTable(this->m_qtdDocument);
    ttTableArticle = this->m_qtcMonCurseur->insertTable(nbrLignes,5,tfTableArticle);

    //remplissage des cellules
    *this->m_qtcMonCurseur = ttTableArticle->cellAt(0,0).firstCursorPosition();
    this->m_qtcMonCurseur->insertText(this->m_qleArticleNum->text(),cfLignePrincipale);
    *this->m_qtcMonCurseur = ttTableArticle->cellAt(0,1).firstCursorPosition();
    this->m_qtcMonCurseur->insertText(this->m_qleArticleDenom->text(),cfLignePrincipale);
    ttTableArticle->cellAt(0,2).firstCursorPosition().setBlockFormat(bfCelluleQ);
    *this->m_qtcMonCurseur = ttTableArticle->cellAt(0,2).firstCursorPosition();
    this->m_qtcMonCurseur->insertText(this->m_qleArticleQty->text(),cfLignePrincipale);
    ttTableArticle->cellAt(0,3).firstCursorPosition().setBlockFormat(bfCellulePU);
    *this->m_qtcMonCurseur = ttTableArticle->cellAt(0,3).firstCursorPosition();
    this->m_qtcMonCurseur->insertText(this->m_qleArticlePrix->text(),cfLignePrincipale);
    ttTableArticle->cellAt(0,4).firstCursorPosition().setBlockFormat(bfCelluleMontant);
    *this->m_qtcMonCurseur = ttTableArticle->cellAt(0,4).firstCursorPosition();
    this->m_qtcMonCurseur->insertText(QString::number(montant,'f',2));

    // insertion du détail
    for(int j = 0;j < nbrLignes - 1; j++)
    {
    //this->m_qteArticleDet->document()->findBlockByNumber(j-1).text()
    *this->m_qtcMonCurseur = ttTableArticle->cellAt(j+ 1,1).firstCursorPosition();
    this->m_qtcMonCurseur->insertText(this->m_qteArticleDet->document()->findBlockByNumber(j).text(),cfLigneDescription);
    }


    //placement du curseur après la table
    this->m_qtcMonCurseur->setPosition(this->m_qtdDocument->lastBlock().position());




    }

    void EditeurFacture::imprimer()
    {
    // impression papier
    this->m_qprPrinter = new QPrinter(QPrinter::ScreenResolution);
    this->m_qpdPrintDlg = new QPrintDialog(this->m_qprPrinter,this);

    //m_qprPrinter->setCreator("CREATEUR PDF");
    //m_qprPrinter->setOutputFormat(QPrinter::A4); //pour imprimer directement au format PDF

    this->m_qprPrinter->setColorMode (QPrinter::Color);
    this->m_qprPrinter->setDoubleSidedPrinting(false);
    this->m_qprPrinter->setFromTo(0,0);
    this->m_qprPrinter->setFullPage(true);
    this->m_qprPrinter->setNumCopies(1);
    this->m_qprPrinter->setOrientation(QPrinter::Portrait);
    this->m_qprPrinter->setPageOrder(QPrinter::FirstPageFirst);
    this->m_qprPrinter->setPageSize(QPrinter::A4);
    this->m_qprPrinter->setPaperSource(QPrinter::Auto);
    this->m_qprPrinter->setPrintRange(QPrinter::AllPages);
    this->m_qprPrinter->setPageMargins(15,10,15,15,QPrinter::Millimeter);



    if (this->m_qteFacture->textCursor().hasSelection())
    this->m_qpdPrintDlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
    this->m_qpdPrintDlg->setWindowTitle("Document à Imprimer");
    if (this->m_qpdPrintDlg->exec() == QDialog::Accepted) {

    //pour donner un format de page au document et enlever les marges.....
    this->m_qteFacture->document()->setPageSize(QSizeF(this->m_qprPrinter->pageRect().size()));
    this->m_qteFacture->document()->print(this->m_qprPrinter);
    }
    delete this->m_qprPrinter;
    delete this->m_qpdPrintDlg;
    }

    void EditeurFacture::quitter()
    {

    }

    void EditeurFacture::slotAjouterClient()
    {
    this->ajouterClient();
    }

    void EditeurFacture::slotAjouterArticle()
    {
    this->ajouterArticle();
    }
    void EditeurFacture::slotImprimer()
    {
    this->imprimer();
    }
    EditeurFacture::~EditeurFacture()
    {

    }

    voila, je dois encore créer le bloc qui fait le total de la facture, et aussi qqch qui sépare la main d'oeuvre de la marchandise avec des sous totaux séparé mais ça c'est pour moi....
    Ha oui... je n'ai pas mis de champ pour la date... là c'est manuel mais c'est un détail.... vite rajouté ou calculer la date du jour automatiquement...
    bref.

    Comme d'hab, je vous tiens au courant. O:)

    PS: il n'y a que moi qui suis assé stupide pour programmer le vendredi soir plutôt que d'aller draguer les nanas ?????? 8o

    Bonne soirée à tous.
    Gpey

  • il n'y a que moi qui suis assé stupide pour programmer le vendredi soir plutôt que d'aller draguer les nanas ??????
    Euh non mais il faut bien un avantage à être marié :-)
  • Ca m'a l'air pas mal :D Plus qu'à décortiquer ça et je te donne mes impressions après :D
  • bonjour,

    as tu garder ton programme complet ?
Connectez-vous ou Inscrivez-vous pour répondre.