QtPy und QPrinter, ich komme einfach nicht weiter!

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
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 :(.
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Nein, der Druck hat eigentlich wie erwartet funktionerit. Die krummen Werte sind bei mir nur im Dialog, nicht im "printer" Objekt.

ich habe allerdings jetzt auch nicht ausprobiert was passiert, wenn man die Werte im Dialog manuell setzt und nicht im Programm
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Puh, müßte man mal in den Sourcecode schauen, was die da eigentlich machen. Demnach übernimmt er nur geänderte Werte. Der PrintDialog scheint zumindest nicht der Qt-Leute liebstes Kind zu sein ;)
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Hab das gleiche Programm jetzt mal in C++ geschrieben. Konnte es noch nicht 100% testen, weil ich grad keinen zugriff auf den entsprechenden Drucker habe, aber der Dialog sieht deutlich besser aus. In den Advanced Properties bekomme ich jetzt auch was angezeigt. In der Python Version ist der Tab ausgegraut

Ich schätze mal, hier gibt es noch ein paar Defizite in den PyQt Bindings von Qt4.5 und Python 2.6
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Vllt. hast Du ja Lust, das ausgiebiger zu testen (mit Werteübergabe etc.) und das Fehlverhalten von Qt-C++ vs. PyQt zu dokumentieren. Da PyQt noch nicht final für Qt 4.5 erschienen ist, kann Riverbank evtl. noch nachbessern.

Falls ich Zeit finde, würd ich auch nochmal drüberschauen...

Grüße, Jerch
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

Ist ja interessant, wie sich der thread weiterentwickelt hat.
Ich war einige Tage außer Betrieb, im Krankenhaus wegen Rippenbruch, und staune jetzt, dass ich mit dem Druckerproblem offensichtlich doch nicht so ganz alleine dastand. :)
Ich werde mich in den nächsten Tagen nochmal mit dem Thema befassen.
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\\
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

jerch hat geschrieben:Vllt. hast Du ja Lust, das ausgiebiger zu testen (mit Werteübergabe etc.) und das Fehlverhalten von Qt-C++ vs. PyQt zu dokumentieren.
Wirklich Zeit, das zu testen, hab ich leider nicht. Aber ich kann die beiden Programme mal aufräumen und posten.

Aber für Jaunty kommt das wohl so oder so zu spät. Selbst wenn das Problem behoben wird landet es wohl nicht mehr in den Paketen
Benutzeravatar
klaus66
User
Beiträge: 51
Registriert: Mittwoch 11. März 2009, 09:26
Wohnort: Bergisch Gladbach-Bensberg

[quote="burli"]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 )

Hi, burli,
meine Rippen sind soweit abgeheilt, dass ich wieder am PC hocken kann. :wink:

Aus gegebenem Anlass muss ich mich leider auch nochmal mit dem Druck befassen. Deine Druckfunktion hab ich mal getestet, kann aber keinerlei Einfluß der Margin-Einstellungen im Programm auf den Ausdruck feststellen. Einzig und allein die Einstellungen im Druckdialog werden tatsächlich verwendet! Das ist natürlich Blödsinn! Ich kann dem Benutzer nicht zumuten, dass er bei jedem Ausdruck im Dialog die Margins einstellen muß.
Es muss doch eine Möglichkeit geben, die Ränder auf einen anderen als den default-Wert einzustellen. Trotz aller Rumsucherei und Probiererei bin ich noch nicht fündig geworden. Für die Testphase werde ich deshalb den Dialog drinlassen. :cry:

Wenn irgendwer noch eine Idee hat, wie mann das Problem lösen kann, bitte ganz schnell melden!
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

So klappt die Drucker Funktion, wie ich es haben wollte! :lol:

Code: Alles auswählen

def drucken(self, text, copy):
        printer=QPrinter() 
        printer.setFullPage(False) 
        printer.setResolution(300) 
        printer.setOrientation(QPrinter.Portrait) 
        size=QSizeF(148.0, 210.0) 
        printer.setPaperSize(size, QPrinter.Millimeter) 
        printer.setPageMargins(5.0, 5.0, 5.0, 5.0, QPrinter.Millimeter) 
        printer.setNumCopies(copy)
        QTextDocument(text).print_(printer)
Er druckt das DINA5 Dokument mit 5 mm Rand ringsum. Genau so wollte ich es haben, auch ohne Druckdialog!
Vielen Dank an alle, die sich an dieser Diskussion beteiligt und mir damit geholfen haben.
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\\
Antworten