QtPy und QPrinter, ich komme einfach nicht weiter!

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

lunar hat geschrieben:
klaus66 hat geschrieben:So ist es!
Warum verwendest du dann nicht .setPageMargins()?
Das kann ich Dir sagen. Weil ich erst jetzt in 'python-qt4-doc' die richtige Anleitung und Schreibweise gefunden habe. Hätte mir ja auch schon mal jemand verraten können.

Hauptsache es fluppt jetzt! :lol:
Und so sieht die Druckfunktion jetzt aus:
  • def drucken(self, text, copy):
    p = QPrinter()
    p.setPageMargins(15.0, 15.0, 15.0, 15.0, p.Millimeter)
    p.setPaperSize(p.A5)
    p.setFullPage(True)
    p.setNumCopies(copy)
    doc=QTextDocument(text)
    doc.print_(p)
Nur leider ändert die Anweisung 'setPageMargins' den Ausdruck nur in sofern, dass nur ein minimalern unveränderlicher Rand von ca. 3mm erscheint. Nach meiner Anweisung sollte der Rand ringsumm 15mm betragen.
Mit freundlichem Gruß Klaus

Das Geheimnis des Könnens liegt im Wollen!
Ubuntu 9.10 64Bit, AMD Athlon 64/Opteron 3200+, 1GB RAM, NVIDIA GeForce7, 250GB SATA 80GB USB und Asus Eee PC 4G mit Ubuntu-eee-8.04.1\\
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Es hat vermutlich damit zu tun, dass du ihn 2 Zeilen später anweist, die ganze Seite zu bedrucken.
lunar

snafu hat geschrieben:Es hat vermutlich damit zu tun, dass du ihn 2 Zeilen später anweist, die ganze Seite zu bedrucken.
So wie ich die Doku verstehe, ändert diese Anweisung aber lediglich das interne Koordinatensystem des QPrinter-Exemplars. Die Reihenfolge der Anweisungen zu tauschen, wäre vielleicht einen Versuch wert, schlägt dieser aber fehl, so kann ich nicht mehr helfen. Ich habe mit Qt4 noch nie drucken müssen, und habe daher keine Ahnung vom Drucken ;)
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

snafu hat geschrieben:Es hat vermutlich damit zu tun, dass du ihn 2 Zeilen später anweist, die ganze Seite zu bedrucken.
Die QPrinter Funktion scheint mir noch nicht so richtig ausgereift zu sein. Auf drei verschieden Druckern bekomme ich drei völlig verschiedene Ergebnisse. Der HP Officejet druckt das Ganze, allerdings ohne die setPageMargins Zeile, noch am besten mit ca. 2cm Rand und mit Zeilenumbruch entsprechend dem DINA5 Format. Der Canon iP2500 druckt es ähnlich nur mit breiterem Rand und der Canon iP4300 druckt mit über 3 cm Rand. Wohlgemerkt alle mit exakt dem selben Programm.

Ich glaube ich muß mich mal intensiv mit dem Painter befassen, denn die Printfunktion ist so für mich nicht brauchbar. Es sei denn, irgendwer hat noch die zündende Idee.
Mit freundlichem Gruß Klaus

Das Geheimnis des Könnens liegt im Wollen!
Ubuntu 9.10 64Bit, AMD Athlon 64/Opteron 3200+, 1GB RAM, NVIDIA GeForce7, 250GB SATA 80GB USB und Asus Eee PC 4G mit Ubuntu-eee-8.04.1\\
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

lunar hat geschrieben:
snafu hat geschrieben:Es hat vermutlich damit zu tun, dass du ihn 2 Zeilen später anweist, die ganze Seite zu bedrucken.
So wie ich die Doku verstehe, ändert diese Anweisung aber lediglich das interne Koordinatensystem des QPrinter-Exemplars. Die Reihenfolge der Anweisungen zu tauschen, wäre vielleicht einen Versuch wert, schlägt dieser aber fehl, so kann ich nicht mehr helfen. Ich habe mit Qt4 noch nie drucken müssen, und habe daher keine Ahnung vom Drucken ;)
Das kann schon sein, aber es muss doch eine Möglichkeit geben, den Ausdruck auf dem Blatt zu verschieben, sonst ist das Teil für mich nicht brauchbar. Mein Programm soll später auf den unterschiedlichsten Systemen mit unterschiedlichen Druckern laufen, ohne dass ich irgendwas anpassen muss.
Mit freundlichem Gruß Klaus

Das Geheimnis des Könnens liegt im Wollen!
Ubuntu 9.10 64Bit, AMD Athlon 64/Opteron 3200+, 1GB RAM, NVIDIA GeForce7, 250GB SATA 80GB USB und Asus Eee PC 4G mit Ubuntu-eee-8.04.1\\
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Vielleicht einfach mal auf das nächste Release von PyQt warten (Qt 4.5 ist ja schon raus, nur eben noch keine Python-Bindings) und hoffen, dass es dort besser ist. Ansonsten kann ich auch nicht mehr viel dazu sagen.
lunar

Mmmh, wenn ich morgen Zeit habe, werde ich QPrinter mal bei mir ausprobieren ...
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Mhm, ich will demnächst auch mal was drucken, aber aus dem GraphicsView. Da bin ich ja mal gespannt
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@klaus66
Ich werde die Drucksache mal beim Herrn Summerfield nachschlagen. Vllt schaffe ich es bis heut abend und werde das Ergebnis hier posten.

Nur soviel schonmal hierzu: Will man den Printout sehr stark modifizieren, so schlägt er den Weg über QPainter() vor.
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

jerch hat geschrieben:@klaus66
Ich werde die Drucksache mal beim Herrn Summerfield nachschlagen. Vllt schaffe ich es bis heut abend und werde das Ergebnis hier posten.

Nur soviel schonmal hierzu: Will man den Printout sehr stark modifizieren, so schlägt er den Weg über QPainter() vor.
An dem Weg knabber ich inzwischen auch schon. Ich bin überzeugt davon, dass diese Gestaltung des Ausdruckes, wie sie mir vorschwebt nur mit QPainter und Konsorten möglich ist. Erste Übungen habe ich schon erfolgreich abgeschlossen, idem ich es geschafft habe mein Logo und Adresse mit Painter in mein Bildschirm-Formular einzubauen. :wink:
Jetzt werde ich meine Texte, die ausgedruckt werden sollen, erstmal in einem Widget auf dem Bildschirm aufbauen (bereits fertig) und dann versuchen dieses quasi per Hardcopy zu Papier zu bringen.
Schaun wir mal. Ich werde berichten!
Mit freundlichem Gruß Klaus

Das Geheimnis des Könnens liegt im Wollen!
Ubuntu 9.10 64Bit, AMD Athlon 64/Opteron 3200+, 1GB RAM, NVIDIA GeForce7, 250GB SATA 80GB USB und Asus Eee PC 4G mit Ubuntu-eee-8.04.1\\
lunar

Hast du eigentlich mal versucht, ".setFullPage(True)" wegzulassen, und nur ".setPageMargins(15, 15, 15, 15, QPrinter.Millimeter)" aufzurufen?

Wenn du ".setFullPage(True)" nutzt, bezieht sich das Koordinaten-System wohl auf die gesamte Seite, so dass ".setPageMargins" gar nichts bewirkt. Das sieht man zumindest, wenn man einen virtuellen Drucker nutzt, der keine Hardware-Beschränkungen hat. ".setFullPage(True)" führt dann dazu, dass der Text ohne Beachtung der an .setPageMargin() übergebenen Werte direkt am Seitenrand steht.

Ohne ".setFullPage(True)" dagegen werden die Werte für ".setPageMargin()" korrekt beachtet. Allerdings gilt das für einen virtuellen PDF-Drucker, bei einem echten Drucker muss man natürlich auch die Einschränkungen der Hardware beachten. Nicht jeder Drucker kann wirklich randlos drucken.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

So ganz ist mir Dein Problem immer noch nicht klar. Mit dem folgenden Code kann ich alles einstellen, was ich aus Deinen Posts an Anforderungen herauslese:

Code

Ich hab die Sache mit print-to-PDF getestet, sogar das Bildchen hat er mitgedruckt. Alles, was an Rand dann bei einem physischen Drucker bleibt, müßte dessen Harwarebeschränkung sein.

Wie mir scheint, ist QTextDocument auch zum Drucken von Bildern geeignet, wie weit hier die HTML-Unterstützung geht, weiß ich allerdings nicht (zur Not gäbe es da ja auch noch QWebKit). Sollte Dein Problem in nicht allzu exotischem HTML darstellbar sein, ist der Weg über QTextDocument sicher der einfachste. (Vllt. kannst Du ja einen Dummyausdruck posten, so, wie er am Ende aussehen soll)

zum Randproblem:
Assoziiere doch mal den Drucker mit dem QPainter, laß Dir den Viewport ausgeben, und zeichne da mal ein leeres Rechteck in Viewportgröße. So müßtest Du für alle Drucker den Rand finden können.
Irgendwie so:

Code: Alles auswählen

painter = QPainter(<QPrinter-Instanz>)
rect = painter.viewport()
# zeichne Rechteck in rect-Größe usw.
Opensuse zeigt den bedruckbaren Bereich eines CUPS-Druckers mit einer Testseite an, was natürlich einfacher wäre.
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

Hallo lunar,

habe ich alles probiert in allen nur denkbaren Variationen!

Aber jetzt hab ich es geschaft mit folgender Druck Routine :

Code: Alles auswählen

def drucken(self, text, copy):      # Param = Text und Anzahl Kopien
        self.printer = QPrinter()
        dialog = QtGui.QPrintDialog(self.printer, self)
        if dialog.exec_():
            self.printer.setNumCopies(copy)
            doc = QTextDocument(text)
            doc.print_(self.printer)
Das ist zwar nicht ganz das, was ich wollte, aber es funktionier sauber. :lol:
Ich werd mal noch ein wenig experimentieren, um auf den Dialog verzichten zu können.
Mit freundlichem Gruß Klaus

Das Geheimnis des Könnens liegt im Wollen!
Ubuntu 9.10 64Bit, AMD Athlon 64/Opteron 3200+, 1GB RAM, NVIDIA GeForce7, 250GB SATA 80GB USB und Asus Eee PC 4G mit Ubuntu-eee-8.04.1\\
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

jerch hat geschrieben:So ganz ist mir Dein Problem immer noch nicht klar. Mit dem folgenden Code kann ich alles einstellen, was ich aus Deinen Posts an Anforderungen herauslese:
Hallo jerch,

ich habe mir mal die Beispielprogramme, die in python-qt4-doc dabei sind, näher angeschaut und eine ganze Menge gelernt. :)
Meine jetzige Druckroutine (Siehe Post an lunar) benutzt den QPrintDialog, in dem ich alles einstellen kann. Der Ausdruck ist dann tatsächlich nur mit dem minmalst möglichen Rand versehen.

Und das ist das, was ich wollte. :!:
Mit freundlichem Gruß Klaus

Das Geheimnis des Könnens liegt im Wollen!
Ubuntu 9.10 64Bit, AMD Athlon 64/Opteron 3200+, 1GB RAM, NVIDIA GeForce7, 250GB SATA 80GB USB und Asus Eee PC 4G mit Ubuntu-eee-8.04.1\\
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Freut mich, das es geklappt hat.
Ich werd mal noch ein wenig experimentieren, um auf den Dialog verzichten zu können.
Also ich finds gut, den Drucker auswählen zu dürfen ;)

Mein Vorschlag hierzu:
Einen einmal eingerichteten Drucker direkt über einen "Schnell Drucken"-Button ansprechen, ist da nix konfiguriert (beim ersten Mal z.B.), poppt halt der Dialog auf. Zusätzlich irgendwo unter "Einstellungen" die Drucker-Konfiguration erreichbar machen, um auch einen konfigurierten Drucker wieder ändern zu können. Persistent speichern kannst Du das Variablengedöns des Druckers mittels QSettings(), so daß auch nach dem Programmneustart die Einstellungen noch da sind.
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Ich grabe das Thema nochmal aus, weil ich gerade selbst am Drucken mit PyQt sitze. Folgendes Programm habe ich geschrieben und tut soweit (sorry für import *. Ich war zu faul )

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Form(QDialog):
    def __init__(self, parent=None):
        super(Form,  self).__init__(parent)
        printer=QPrinter()
        printer.setPrinterName("Dymo-Label-Printer")
        printer.setFullPage(False)
        printer.setResolution(300)
        printer.setOrientation(QPrinter.Landscape)
        size=QSizeF(32.0, 57.0)
        printer.setPaperSize(size, QPrinter.Millimeter)
        printer.setPageMargins(1.0, 1.0, 1.0, 1.0, QPrinter.Millimeter) 
        printer.setNumCopies(10)
        print printer.pageRect()
        print printer.paperRect()
        dialog=QPrintDialog(printer,  self)
        html=u"""<p align="center"><u><font size="2">Some HTML Text</font></u></p>
        <p align="center"><b>MoreText<br>Even more<br>Guess what</b></p>"""
        
        if dialog.exec_():
            doc = QTextDocument()
            doc.setHtml(html)
            doc.print_(printer) 

if __name__=="__main__":
    app=QApplication(sys.argv)
    form=Form()
    form.show()
    app.exec_()
Wenn ich das Programm starte öffnet er mir den Druckdialog und wählt auch den richtigen Drucker aus. Auch der Ausdruck funktioniert.

Er gibt mir für paperRect() und pageRect() auch die richtigen Werte aus
PyQt4.QtCore.QRect(12, 12, 355, 651)
PyQt4.QtCore.QRect(0, 0, 378, 673)
Wenn ich im Druckdialog allerdings auf die Properties von dem Drucker gehe bekomme ich völlig krumme Werte

Bild

Hat jemand eine Idee, womit das zusammenhängen kann?
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Ich habe den Code nochmal aktualisiert. Der Ausdruck funktioniert jetzt wie gewünscht. Die krummen Werte im Dialog sind aber noch da.

setNumCopies() wirkt sich zwar auf den Drucker Dialog aus, aber es wird trotzdem nur ein Exemplar gedruckt.

Ergänzend sollte ich sagen: ich verwende Qt4.5 und Python 2.6.1, das ganze unter Xubuntu 9.04.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@burli:
Selbes Phämomen hier, unter Qt 4.5 Deine komischen Werte, unter 4.4 funktionierts.

Komisch...
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Hm, da stellt sich die Frage, ob es ein Problem von Qt4.5 ist oder ob es an unvollständigen PyQt Bindings liegt.

Ich werde es bald wissen. Werde das gleiche mal von C++ aus probieren
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Hm, da scheint doch einiges mit dem PrintDialog im Argen zu liegen. Mal abgesehen davon, das er die Margins komplett ignoriert, habe ich dies hier gefunden:

https://www.qtsoftware.com/developer/ta ... &id=217816

Womöglich haben die Qt-Leute mit der Reparatur des einen Fehlers die Sache in Version 4.5 verschlimmbessert.

Hast Du den Druck denn mal probiert? Offensichtlich "übersieht" der Dialog einfach ein paar vorher gesetzte Einstellungen und zeigt dann Standardwerte an. Das Problem ist halt, daß er diese Standardwerte dann auch an den Printer weitergibt :(.
Antworten