wxPython / ReportLab: как создать и открыть файл .pdf при нажатии кнопки

Добрый день, В течение примерно трех дней я изо всех сил старался обойти это! У меня отлично работает wxFrame, а также отлично работает сценарий PDF ReportLab. См. Ниже файлы кода (Примечание: data1.py – это графический интерфейс, в то время как data2.py – это исполняемый сценарий pdf). Мои проблемы: – 1) Я хочу, чтобы скрипт pdf запускался только после нажатия кнопки «Сохранить в PDF». 2) Значение поля имени (как хранится в переменной «NameString») должно быть добавлено в сгенерированный PDF-файл файл.

На данный момент, если я запускаю скрипт (data2.py), он создает, но Frame и файл PDF (без включения «NameString») одновременно. Это не то, что я хочу, я хочу, чтобы PDF открылся и включил «NameString» только после того, как я нажал / нажал кнопку «Сохранить в PDF».

Спасибо заранее за ваше время.

data1.py

class MyFrame1 ( wx.Frame ): def __init__( self, parent ): wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 250,150 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.TAB_TRAVERSAL ) self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize ) DataBox = wx.BoxSizer( wx.HORIZONTAL ) gSizer2 = wx.GridSizer( 0, 2, 0, 0 ) self.NameLabel = wx.StaticText( self, wx.ID_ANY, u"Name", wx.DefaultPosition, wx.DefaultSize, 0 ) self.NameLabel.Wrap( -1 ) self.NameLabel.SetFont( wx.Font( 13, 70, 90, 90, False, wx.EmptyString ) ) gSizer2.Add( self.NameLabel, 0, wx.ALL, 5 ) self.NameField = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) gSizer2.Add( self.NameField, 1, wx.ALL, 5 ) self.SaveToPDF = wx.Button( self, wx.ID_ANY, u"Save To PDF", wx.DefaultPosition, wx.DefaultSize, 0 ) gSizer2.Add( self.SaveToPDF, 0, wx.ALL, 5 ) DataBox.Add( gSizer2, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5 ) self.SetSizer( DataBox ) self.Layout() self.Centre( wx.BOTH ) # Connect Events self.SaveToPDF.Bind( wx.EVT_BUTTON, self.SaveToPDF_Function ) def __del__( self ): pass # Virtual event handlers, overide them in your derived class def SaveToPDF_Function( self, event ): event.Skip() 

data2.py

 #!/usr/bin/python # -*- coding: utf-8 -*- import wx from data1 import MyFrame1 from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A3 from reportlab.lib.pagesizes import landscape import os import tempfile import threading class MyFrame2(MyFrame1): def __init__(self, parent): MyFrame1.__init__ (self, parent) def SaveToPDF_Function( self, event ): NameString = self.NameField.GetValue() print NameString file_not_fount = "Selected file doesn't exist!" class Launcher(threading.Thread): def __init__(self,path): threading.Thread.__init__(self) self.path = 'myFile.pdf' def run(self): self.open_file(self.path) def open_file(self,path): if os.path.exists(path): if os.name == 'posix': subprocess.call(["xdg-open", path]) #os.popen("evince %s" % path) else: os.startfile(path) else: wx.MessageBox(self.file_not_fount, self.title, wx.OK|wx.ICON_INFORMATION) # NameString = raw_input("Enter ur text: ") c = canvas.Canvas("myFile.pdf", pagesize=landscape(A3)) c.drawCentredString(600, 800, 'I want this to open only after I clicked the “Save To PDF” button. Also, the text field value (NameString variable) should appear here =>' + 'NameString' ) c.save() Launcher('myFile.pdf').start() app = wx.App(0) MyFrame2(None).Show() app.MainLoop() 

2 Solutions collect form web for “wxPython / ReportLab: как создать и открыть файл .pdf при нажатии кнопки”

Вот простое рабочее решение, которое я придумал для автоматического открытия pdf-файла, созданного с помощью ReportLab.

Импортируйте подпроцесс и модули ReportLab, как обычно. Затем привяжите эту функцию к вашему событию (магическая часть кода является подпроцессом. Открываем …..)

 def SaveToPDF_Function( self, event ): NameString = self.NameField.GetValue() try: c = canvas.Canvas("myFile.pdf", pagesize=landscape(A3)) c.drawCentredString(600, 800, 'OPENED... Welcome to ReportLab! This is my FIRST App...' + NameString ) c.save() subprocess.Popen(['myFile.pdf'], shell=True) except IOError: print 'The file is already OPENED!' 

Надеюсь, что это поможет кому-то в будущем поиске.

Прежде всего, я бы создал модуль reportlab, чтобы вы могли называть его. Поскольку он в настоящее время реализован, он будет немедленно создавать PDF-файл при каждом запуске. Вам нужно поместить весь код reportlab в какую-то функцию. Поскольку это действительно простой сценарий reportlab, я просто объединил его с кодом wxPython и удалил часть потока, чтобы вы могли увидеть один простой способ сделать это:

 import wx from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A3 from reportlab.lib.pagesizes import landscape class MyFrame1 ( wx.Frame ): def __init__( self ): wx.Frame.__init__ ( self, None, size = wx.Size( 250,150 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.TAB_TRAVERSAL ) self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize ) DataBox = wx.BoxSizer( wx.HORIZONTAL ) gSizer2 = wx.GridSizer( 0, 2, 0, 0 ) self.NameLabel = wx.StaticText( self, wx.ID_ANY, u"Name", wx.DefaultPosition, wx.DefaultSize, 0 ) self.NameLabel.Wrap( -1 ) self.NameLabel.SetFont( wx.Font( 13, 70, 90, 90, False, wx.EmptyString ) ) gSizer2.Add( self.NameLabel, 0, wx.ALL, 5 ) self.NameField = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) gSizer2.Add( self.NameField, 1, wx.ALL, 5 ) self.SaveToPDF = wx.Button( self, wx.ID_ANY, u"Save To PDF", wx.DefaultPosition, wx.DefaultSize, 0 ) gSizer2.Add( self.SaveToPDF, 0, wx.ALL, 5 ) DataBox.Add( gSizer2, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5 ) self.SetSizer( DataBox ) self.Layout() self.Centre( wx.BOTH ) # Connect Events self.SaveToPDF.Bind( wx.EVT_BUTTON, self.SaveToPDF_Function ) self.Show() #---------------------------------------------------------------------- def create_pdf(self): """""" nameString = str(self.NameField.GetValue()) c = canvas.Canvas("myFile.pdf", pagesize=landscape(A3)) txt = """'I want this to open only after I clicked the "Save To PDF" button. Also, the text field value (NameString variable) should appear here =>' + %s """ % nameString c.drawCentredString(600, 800, txt) c.save() # Virtual event handlers, overide them in your derived class def SaveToPDF_Function( self, event ): self.create_pdf() if __name__ == "__main__": app = wx.App(False) frame = MyFrame1() app.MainLoop() 

Я рекомендую прочитать следующие статьи о потоках и wxPython:

Чтобы добавить потоки обратно, я бы создал класс потоков, например, Launcher. Однако я бы поставил ВСЕ код reportlab внутри этого класса, и когда вы создаете экземпляр класса Thread, вы должны передать имя namedString :

 class Launcher(threading.Thread): def __init__(self,path, namedString): threading.Thread.__init__(self) self.path = 'myFile.pdf' self.namedString = namedString 

Надеюсь, это поможет!

  • Получить значение слайдера wxpython под щелчком мыши
  • Сортировка по столбцам в wxpython?
  • установить выравнивание текста с расширенным текстом ctrl
  • Динамически изменять выбор в wx.ComboBox ()
  • wx.PyTextDataObject с перетаскиванием приводит к дополнительным символам
  • Как добавить контур границы к виджету?
  • Как создать эффект зависания на StaticBitmap в wxpython?
  • Как я могу захватить все исключения из приложения wxPython?
  • Python - лучший язык программирования в мире.