flet-pdfview 0.1.2__py3-none-any.whl → 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flet_pdfview/main.py +102 -38
- {flet_pdfview-0.1.2.dist-info → flet_pdfview-0.2.1.dist-info}/METADATA +22 -6
- flet_pdfview-0.2.1.dist-info/RECORD +6 -0
- flet_pdfview-0.1.2.dist-info/RECORD +0 -6
- {flet_pdfview-0.1.2.dist-info → flet_pdfview-0.2.1.dist-info}/WHEEL +0 -0
- {flet_pdfview-0.1.2.dist-info → flet_pdfview-0.2.1.dist-info}/top_level.txt +0 -0
flet_pdfview/main.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from flet import Column,Image,ScrollMode,BoxFit
|
|
1
|
+
from flet import Column,Image,ScrollMode,BoxFit,InteractiveViewer
|
|
2
2
|
import asyncio , os,pymupdf,gc
|
|
3
3
|
from typing import Optional
|
|
4
4
|
class PdfColumn(Column):
|
|
@@ -15,7 +15,8 @@ def main(page:Page):
|
|
|
15
15
|
src="you/pdf/path",
|
|
16
16
|
expand=True,
|
|
17
17
|
dpi=300,
|
|
18
|
-
fitImage=BoxFit.FILL
|
|
18
|
+
fitImage=BoxFit.FILL,
|
|
19
|
+
enable_zoom=True
|
|
19
20
|
)
|
|
20
21
|
)
|
|
21
22
|
run(main)
|
|
@@ -23,7 +24,7 @@ run(main)
|
|
|
23
24
|
|
|
24
25
|
make sure if the path do not end with .pdf or the path not exists the PdfColumn will do not show anything !
|
|
25
26
|
"""
|
|
26
|
-
def __init__(self,src:str="",widht:Optional[int]=None,height:Optional[int]=None,spacing:Optional[int]=None,expand_loose:Optional[bool]=False,expand:Optional[bool]=False,scroll:ScrollMode=ScrollMode.ADAPTIVE,dpi:int=150,fitImage:BoxFit=BoxFit.FILL,visible:Optional[bool]=True):
|
|
27
|
+
def __init__(self,src:str="",enable_zoom:Optional[bool]=False,max_zoom:float=2.5,min_zoom:float=0.8,trackpad_scroll_causes_scale:Optional[bool]=True,widht:Optional[int]=None,height:Optional[int]=None,spacing:Optional[int]=None,expand_loose:Optional[bool]=False,expand:Optional[bool]=False,scroll:ScrollMode=ScrollMode.ADAPTIVE,dpi:int=150,fitImage:BoxFit=BoxFit.FILL,visible:Optional[bool]=True):
|
|
27
28
|
super().__init__()
|
|
28
29
|
self._src=src
|
|
29
30
|
self.expand=expand
|
|
@@ -36,57 +37,120 @@ make sure if the path do not end with .pdf or the path not exists the PdfColumn
|
|
|
36
37
|
self._fitImage=fitImage
|
|
37
38
|
self._dpi=dpi
|
|
38
39
|
self.visible=visible
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
self.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
pdf_pages = pymupdf.open(path)
|
|
45
|
-
|
|
46
|
-
for pdf_page in pdf_pages:
|
|
47
|
-
if self.src==path:
|
|
48
|
-
pix = pdf_page.get_pixmap(dpi=dpi)
|
|
49
|
-
|
|
50
|
-
# pix.save(filename="file.png",output=ram)
|
|
51
|
-
self.controls.append(
|
|
52
|
-
Image(
|
|
53
|
-
expand=self.expand,
|
|
54
|
-
expand_loose=self.expand_loose,
|
|
55
|
-
width=self.widht,
|
|
56
|
-
height=self.height,
|
|
57
|
-
src=pix.tobytes(),
|
|
58
|
-
fit=self.fitImage
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
self.update()
|
|
64
|
-
gc.collect()
|
|
65
|
-
await asyncio.sleep(0.3)
|
|
66
|
-
else:
|
|
67
|
-
break
|
|
68
|
-
|
|
40
|
+
self._enable_zoom=enable_zoom
|
|
41
|
+
self._min_zoom=min_zoom
|
|
42
|
+
self._max_zoom=max_zoom
|
|
43
|
+
self._trackpad_scroll_causes_scale=trackpad_scroll_causes_scale
|
|
44
|
+
# self.page.run_task
|
|
69
45
|
|
|
46
|
+
async def __start_converte(self,path:str="",dpi:int=150):
|
|
47
|
+
try:
|
|
48
|
+
self.controls.clear()
|
|
49
|
+
if os.path.exists(path) and path.endswith(".pdf"):
|
|
50
|
+
|
|
51
|
+
pdf_pages = pymupdf.open(path)
|
|
52
|
+
|
|
53
|
+
for pdf_page in pdf_pages:
|
|
54
|
+
if self.src==path:
|
|
55
|
+
pix = pdf_page.get_pixmap(dpi=dpi)
|
|
56
|
+
|
|
57
|
+
# pix.save(filename="file.png",output=ram)
|
|
58
|
+
self.controls.append(
|
|
59
|
+
InteractiveViewer(
|
|
60
|
+
expand=self.expand,
|
|
61
|
+
expand_loose=self.expand_loose,
|
|
62
|
+
width=self.widht,
|
|
63
|
+
height=self.height,
|
|
64
|
+
content=Image(
|
|
65
|
+
expand=self.expand,
|
|
66
|
+
expand_loose=self.expand_loose,
|
|
67
|
+
width=self.widht,
|
|
68
|
+
height=self.height,
|
|
69
|
+
src=pix.tobytes(),
|
|
70
|
+
fit=self.fitImage
|
|
71
|
+
),
|
|
72
|
+
scale_enabled=self._enable_zoom,
|
|
73
|
+
trackpad_scroll_causes_scale=self._trackpad_scroll_causes_scale,
|
|
74
|
+
max_scale=self._max_zoom,
|
|
75
|
+
min_scale=self._min_zoom
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
self.update()
|
|
80
|
+
gc.collect()
|
|
81
|
+
del pix
|
|
82
|
+
del pdf_page
|
|
83
|
+
await asyncio.sleep(0.3)
|
|
84
|
+
else:
|
|
85
|
+
break
|
|
86
|
+
except :
|
|
87
|
+
self.start_function.cancel()
|
|
88
|
+
finally:
|
|
89
|
+
# تنظيف الذاكرة في كل الأحوال
|
|
90
|
+
if 'pdf_pages' in locals():
|
|
91
|
+
pdf_pages.close()
|
|
92
|
+
def did_mount(self):
|
|
93
|
+
if self._src:
|
|
94
|
+
self.start_function = asyncio.create_task(self.__start_converte(self._src, self._dpi))
|
|
95
|
+
def will_unmount(self):
|
|
96
|
+
if self.start_function:
|
|
97
|
+
self.start_function.cancel()
|
|
70
98
|
@property
|
|
71
99
|
def src(self):
|
|
72
100
|
return self._src
|
|
73
101
|
@src.setter
|
|
74
102
|
def src(self,new_src):
|
|
75
103
|
self._src=new_src
|
|
76
|
-
asyncio.create_task(self.__start_converte(new_src,))
|
|
104
|
+
self.start_function = asyncio.create_task(self.__start_converte(new_src,))
|
|
77
105
|
@property
|
|
78
106
|
def fitImage(self):
|
|
79
107
|
return self._fitImage
|
|
80
108
|
@fitImage.setter
|
|
81
109
|
def fitImage(self,new_fitImage):
|
|
82
110
|
self._fitImage=new_fitImage
|
|
83
|
-
for
|
|
84
|
-
if isinstance(
|
|
85
|
-
image.
|
|
111
|
+
for parent_image in self.controls:
|
|
112
|
+
if isinstance(parent_image,InteractiveViewer):
|
|
113
|
+
image = parent_image.content
|
|
114
|
+
if isinstance(image,Image):
|
|
115
|
+
image.fit=new_fitImage
|
|
86
116
|
@property
|
|
87
117
|
def dpi(self):
|
|
88
118
|
return self._dpi
|
|
89
119
|
@dpi.setter
|
|
90
120
|
def dpi(self,new_dpi):
|
|
91
121
|
self._dpi=new_dpi
|
|
92
|
-
asyncio.create_task(self.__start_converte(self.src,))
|
|
122
|
+
self.start_function = asyncio.create_task(self.__start_converte(self.src,))
|
|
123
|
+
@property
|
|
124
|
+
def enable_zoom(self):
|
|
125
|
+
return self._enable_zoom
|
|
126
|
+
@enable_zoom.setter
|
|
127
|
+
def enable_zoom(self, value: bool):
|
|
128
|
+
self._enable_zoom = value
|
|
129
|
+
for viewer in self.controls:
|
|
130
|
+
if isinstance(viewer, InteractiveViewer):
|
|
131
|
+
viewer.scale_enabled = value
|
|
132
|
+
self.update()
|
|
133
|
+
@property
|
|
134
|
+
def trackpad_scroll_causes_scale(self):
|
|
135
|
+
return self._trackpad_scroll_causes_scale
|
|
136
|
+
@trackpad_scroll_causes_scale.setter
|
|
137
|
+
def trackpad_scroll_causes_scale(self, value: bool):
|
|
138
|
+
for viewer in self.controls:
|
|
139
|
+
if isinstance(viewer, InteractiveViewer):
|
|
140
|
+
viewer.trackpad_scroll_causes_scale = value
|
|
141
|
+
@property
|
|
142
|
+
def max_zoom(self):
|
|
143
|
+
return self._max_zoom
|
|
144
|
+
@max_zoom.setter
|
|
145
|
+
def max_zoom(self, value: float):
|
|
146
|
+
for viewer in self.controls:
|
|
147
|
+
if isinstance(viewer, InteractiveViewer):
|
|
148
|
+
viewer.max_scale = value
|
|
149
|
+
@property
|
|
150
|
+
def min_zoom(self):
|
|
151
|
+
return self._min_zoom
|
|
152
|
+
@min_zoom.setter
|
|
153
|
+
def min_zoom(self, value: float):
|
|
154
|
+
for viewer in self.controls:
|
|
155
|
+
if isinstance(viewer, InteractiveViewer):
|
|
156
|
+
viewer.min_scale = value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flet_pdfview
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Flet pdf view for all platforms
|
|
5
5
|
Author: Mostafa Kessassi
|
|
6
6
|
Author-email: mustaphakessassi76@gmail.com
|
|
@@ -28,6 +28,7 @@ Dynamic: summary
|
|
|
28
28
|
### ✨ Features
|
|
29
29
|
|
|
30
30
|
* 🧩 **Native PDF rendering** inside Flet layouts.
|
|
31
|
+
* 🔍 **Interactive Zoom**: Support for zooming in and out with configurable limits.
|
|
31
32
|
* 📐 **High-resolution** rendering with custom DPI.
|
|
32
33
|
* 🖼️ **Flexible image fitting** using `BoxFit`.
|
|
33
34
|
* 📱 **Fully responsive** (via `expand=True`).
|
|
@@ -54,18 +55,33 @@ def main(page: Page):
|
|
|
54
55
|
src="path/to/your/file.pdf",
|
|
55
56
|
expand=True,
|
|
56
57
|
dpi=300,
|
|
57
|
-
fitImage=BoxFit.FILL
|
|
58
|
+
fitImage=BoxFit.FILL,
|
|
59
|
+
enable_zoom=True
|
|
58
60
|
)
|
|
59
61
|
)
|
|
60
62
|
|
|
61
63
|
run(main)
|
|
62
64
|
```
|
|
63
|
-
###
|
|
65
|
+
### 🔍 Zoom Control
|
|
66
|
+
You can now fully control the viewing experience with the following properties:
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
min_zoom: Sets the minimum scale allowed (Default : 0.8).
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
max_zoom: Sets the maximum scale allowed to ensure quality and performance (Default : 2.5).
|
|
71
|
+
### ⚠️ Important Behavior & Performance
|
|
72
|
+
**1. Silent Failure**
|
|
73
|
+
|
|
74
|
+
PdfColumn will not render anything if the provided path does not exist or does not end with .pdf.
|
|
75
|
+
|
|
76
|
+
No exceptions ❌
|
|
77
|
+
|
|
78
|
+
No error dialogs ❌
|
|
79
|
+
|
|
80
|
+
No UI interruption ❌
|
|
81
|
+
|
|
82
|
+
**2. Technical Performance Warning**
|
|
83
|
+
|
|
84
|
+
[!WARNING] Resource Management: Be cautious when performing intensive property updates on the PdfColumn object after its initial call. If changes involve high values or frequent updates, it may cause a brief delay when closing the application as the component finishes processing tasks to ensure a stable exit.
|
|
69
85
|
|
|
70
86
|
> [!IMPORTANT]
|
|
71
87
|
> **This behavior is intentional:**
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
flet_pdfview/__init__.py,sha256=uxLtdoexxWnULjF0YXDF3bTUuoizSUearqHxcs-n-dY,27
|
|
2
|
+
flet_pdfview/main.py,sha256=tsgwmdw8TvZ9Ou8XO0ker0G8JrBz9ye9UpSyLb38wXQ,6035
|
|
3
|
+
flet_pdfview-0.2.1.dist-info/METADATA,sha256=x8OTXCanJpsa_ozHVsrZWXNozTU7qgDQZe1aJTzZX6w,3115
|
|
4
|
+
flet_pdfview-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
+
flet_pdfview-0.2.1.dist-info/top_level.txt,sha256=e-e9EU2FfrodvbFGo3DJapANzBRZgjcvCeG4d-jdnGM,13
|
|
6
|
+
flet_pdfview-0.2.1.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
flet_pdfview/__init__.py,sha256=uxLtdoexxWnULjF0YXDF3bTUuoizSUearqHxcs-n-dY,27
|
|
2
|
-
flet_pdfview/main.py,sha256=LscccGNDfx0-t6lnumqKthuxPT5Ki19V7ftlOKSiw_A,3040
|
|
3
|
-
flet_pdfview-0.1.2.dist-info/METADATA,sha256=Qh_mA-seEwXK0k9dtACldjpzbBYxeF7--rPG8-lnCBY,2310
|
|
4
|
-
flet_pdfview-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
-
flet_pdfview-0.1.2.dist-info/top_level.txt,sha256=e-e9EU2FfrodvbFGo3DJapANzBRZgjcvCeG4d-jdnGM,13
|
|
6
|
-
flet_pdfview-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|