Python: PDF: как читать из формы с помощью радиокнопок - PullRequest
1 голос
/ 23 апреля 2019

Я создал форму с несколькими переключателями, следуя примерам из Создание интерактивных форм PDF в ReportLab с Python

Вот пример кода esp.для радиостанций:

simple_radios.py

from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfform
from reportlab.lib.colors import magenta, pink, blue, green

def create_simple_radios():
    c = canvas.Canvas('simple_radios.pdf')

    c.setFont("Courier", 20)
    c.drawCentredString(300, 700, 'Radio demo')
    c.setFont("Courier", 14)
    form = c.acroForm

    c.drawString(10, 650, 'Dog:')
    form.radio(name='radio1', tooltip='Field radio1',
               value='value1', selected=False,
               x=110, y=645, buttonStyle='check',
               borderStyle='solid', shape='square',
               borderColor=magenta, fillColor=pink, 
               textColor=blue, forceBorder=True)
    form.radio(name='radio1', tooltip='Field radio1',
               value='value2', selected=True,
               x=110, y=645, buttonStyle='check',
               borderStyle='solid', shape='square',
               borderColor=magenta, fillColor=pink, 
               textColor=blue, forceBorder=True)    

    c.drawString(10, 600, 'Cat:')
    form.radio(name='radio2', tooltip='Field radio2',
               value='value1', selected=True,
               x=110, y=595, buttonStyle='cross',
               borderStyle='solid', shape='circle',
               borderColor=green, fillColor=blue, 
               borderWidth=2,
               textColor=pink, forceBorder=True)
    form.radio(name='radio2', tooltip='Field radio2',
               value='value2', selected=False,
               x=110, y=595, buttonStyle='cross',
               borderStyle='solid', shape='circle',
               borderColor=green, fillColor=blue, 
               borderWidth=2,
               textColor=pink, forceBorder=True)

    c.drawString(10, 550, 'Pony:')
    form.radio(name='radio3', tooltip='Field radio3',
               value='value1', selected=False,
               x=110, y=545, buttonStyle='star',
               borderStyle='bevelled', shape='square',
               borderColor=blue, fillColor=green, 
               borderWidth=2,
               textColor=magenta, forceBorder=False)
    form.radio(name='radio3', tooltip='Field radio3',
               value='value2', selected=True,
               x=110, y=545, buttonStyle='star',
               borderStyle='bevelled', shape='circle',
               borderColor=blue, fillColor=green, 
               borderWidth=2,
               textColor=magenta, forceBorder=True)

    c.save()

if __name__ == '__main__':
    create_simple_radios()

Моя проблема / вопрос с этим кодом: 1.) Радиостанции всегда находятся в «нажатом» состоянии.Как я могу их оттолкнуть?2.) Можно ли сгруппировать их так, чтобы только ОДНА (1) радиокнопка была нажата в соответствии с группой 3.) Как я мог позже прочитать состояние кнопок программно, например, через PyPDF2?

Спасибо,Проф.

Версии: Python: 3.7.3 Reportlab: 3.5.19 Подушка: 6.0.0 PyPDF2: 1.26.0

ОС: Windows10 v1809

1 Ответ

0 голосов
/ 23 апреля 2019

1.) Радиостанции всегда находятся в «нажатом» состоянии.Как я могу снять их?

Кнопки нажимаются, если form.radio(... selected=True)

2.) Можно ли сгруппировать, так что только ОДИН (1) переключательвыдвигается в соответствии с группой?

Атрибут name связан с именем группы.

То есть form.radio(... name="group1") является одной группой form.radio(... name="group2") второй группой. Вы можете выбрать только одну радиостанцию ​​в каждой группе.

Итак, для первых двух вопросов я создал простой пример с двумя разными группами.
Первый group содержит Fruits а вторая группа содержит Cars:

from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfform
from reportlab.lib.colors import magenta, pink, blue, green, orange, yellow

def create_radios():
    c = canvas.Canvas('radios.pdf')

    c.setFont("Courier", 20)
    c.drawCentredString(300, 800, 'Radio demo')
    form = c.acroForm

    #GROUP ONE, name='group1'
    c.setFont("Courier", 16)
    c.drawString(10, 680, 'Fruits:')
    c.setFont("Courier", 12)
    c.drawString(10, 650, 'Apple:')
    form.radio(name='group1', tooltip='Apple',
               value='apple', selected=False,
               x=110, y=650, buttonStyle='check',
               borderStyle='solid', shape='square',
               borderColor=blue, fillColor=magenta, 
               textColor=blue, forceBorder=True)

    c.drawString(10, 600, 'Banana:')
    form.radio(name='group1', tooltip='Banana',
               value='banana', selected=False,
               x=110, y=600, buttonStyle='check',
               borderStyle='solid', shape='square',
               borderColor=blue, fillColor=yellow, 
               textColor=blue, forceBorder=True)

    c.drawString(10, 550, 'Orange:')
    form.radio(name='group1', tooltip='Orange',
               value='orange', selected=False,
               x=110, y=550, buttonStyle='check',
               borderStyle='solid', shape='square',
               borderColor=blue, fillColor=orange, 
               textColor=blue, forceBorder=True)

    #GROUP TWO, name='group2'
    c.setFont("Courier", 16)
    c.drawString(210, 680, 'Cars:')
    c.setFont("Courier", 12)
    c.drawString(210, 650, 'Tesla:')
    form.radio(name='group2', tooltip='Apple',
               value='tesla', selected=False,
               x=310, y=650, buttonStyle='circle',
               borderStyle='solid', shape='circle',
               borderColor=blue, fillColor=magenta, 
               textColor=blue, forceBorder=False)

    c.drawString(210, 600, 'Mercedes-Benz:')
    form.radio(name='group2', tooltip='Banana',
               value='mercedes', selected=False,
               x=310, y=600, buttonStyle='circle',
               borderStyle='solid', shape='circle',
               borderColor=blue, fillColor=magenta, 
               textColor=blue, forceBorder=False)

    c.drawString(210, 550, 'Toyota:')
    form.radio(name='group2', tooltip='Orange',
               value='toyota', selected=False,
               x=310, y=550, buttonStyle='circle',
               borderStyle='solid', shape='circle',
               borderColor=blue, fillColor=magenta, 
               textColor=blue, forceBorder=False)

    c.save()



if __name__ == '__main__':
    create_radios()

3.) Как я могу позже прочитать состояние кнопок программно, например, через PyPDF2?

Я нашел более простой подход, чем использование PyPDF2 возвращенных данных поля ...

Использование pdfminer хорошо справится с проблемой.

После того, как я создал radios.pdf, я изменил значения, используя Adobe, и сохранил его как новый файл radios_checked.pdf, также вы можете изменить один атрибут selected для каждой группы.

import sys
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdftypes import resolve1

filename = "radios_checked.pdf"

with open(filename, 'rb') as pdf_file:
    parser = PDFParser(pdf_file)
    doc = PDFDocument(parser)
    fields = resolve1(doc.catalog['AcroForm'])['Fields']
    for i in fields:
        field = resolve1(i)
        name = str(field.get('T'), 'utf-8')

        value = field.get('V') #will return PSLiteral :/ 

        # transform PSLiteral to string
        if value != None:
            value = str(value)
            if value[0] == r"/":
                value = value[2:-1]
                value = str(value)

        print("Group Name: {0},  checked value: {1} ".format(name , value))

Это позволит отфильтровать все объекты группы и распечатать выбранное имя группы и выбранное значение.

Подсказка: откройте pdf в texteditor и проверьте общую структуру.

...