上一篇文章中,我們實現了 PDF 閱讀器的初始介面。這一次,新增了閱讀功能,可以實現基本的翻頁以及縮放等操作。不過,暫時只可以同時閱讀一本書。
下圖為效果圖:
下面我來介紹下,這次主要新增的功能:
選項卡
QTabWidget 可以允許我們在一個視窗顯示多個頁面。對於書庫的這個選項卡,頁面顯示為 self。table ,即初始介面
self。table(QTableWidget) -> self。tabwidget(QTabWidge)。
# Python高效程式設計# 初始化選項卡self。tabwidget = QTabWidget()# 新增書庫選項卡self。tabwidget。addTab(self。table, ‘書庫’)self。setCentralWidget(self。tabwidget)# 設定選項卡可以關閉self。tabwidget。setTabsClosable(True)# 點選選項卡叉號時,執行 removeTabab 操作self。tabwidget。tabCloseRequested[int]。connect(self。remove_tab)
新建選項卡:每次開始閱讀時,新建一個選項卡,名稱為檔名。
def read_book(self, fname): # self。close() # 記憶體有可能洩露 self。doc = fitz。open(fname) # metadata = doc。metadata title = fname。split(‘/’ or ‘\\’)[-1]。replace(‘。pdf’, ‘’) vbox = self。book_area(self。doc。loadPage(0)) self。book_add_tab(title, vbox)
其中,我們要求主選項卡,即書庫選項卡是不可以關閉的。
def remove_tab(self, index): if index: # 當前頁數 self。current_page = 0 self。tabwidget。removeTab(index) # 正在閱讀的書 self。read_list。pop(index)
閱讀介面的選項卡對應的頁面區域為 QScrollArea ,QScrollArea 支援滾輪操作。也就是說,如果我們縮放 PDF 頁面大小超過 QScrollArea 的大小,那麼就會自動出現滾輪,以便我們瀏覽頁面。其中,MyArea 類是對 QScrollArea 的過載,綁定了快捷鍵以支援翻頁以及縮放等操作。
Pixmap -> label -> area(MyArea) -> vbox(QVBoxLayout) -> tab(QWidget) -> self。tabwidget(QTabWidge)。
def book_add_tab(self, title, vbox): tab = QWidget() tab。setLayout(vbox) # tab 為頁面,title 為標籤名稱 self。tabwidget。addTab(tab, title) def book_area(self, page): label = self。page_pixmap(page) # area = QScrollArea() area = MyArea(self) area。init(self) area。setWidget(label) vbox = QVBoxLayout() vbox。addWidget(area) return vbox
下面我們來看看, MyArea 這個類該如何定義:
MyArea(QScrollArea)
這裡,我們定義了 init 方法,用來接受 Reader 主類 的 self 引數, 即透過 self。widget 呼叫 Reader 類的例項方法。
在 init_action 函式中,我們新建了四個 QShortCut 例項,分別支援快捷鍵實現縮小、放大、下一頁、上一頁的操作。
class MyArea(QScrollArea): def init(self, widget): self。widget = widget self。init_action() def init_action(self): zoom_minus = QShortcut(QKeySequence(“Ctrl+-”), self) zoom_minus。activated。connect(self。minus) zoom_plus = QShortcut(QKeySequence(“Ctrl+=”), self) zoom_plus。activated。connect(self。plus) switch_left = QShortcut(QKeySequence(Qt。Key_Left), self) switch_left。activated。connect(self。left) switch_right = QShortcut(QKeySequence(Qt。Key_Right), self) switch_right。activated。connect(self。right) def plus(self): self。widget。zoom_book(plus=True) def minus(self): self。widget。zoom_book(plus=False) def right(self): self。widget。switch_page(right=True) def left(self): self。widget。switch_page(right=False)
下面,我們來介紹縮放與翻頁功能的具體實現:
縮放功能
self。size 用來儲存頁面大小,self。page 正是根據 self。size 來實現縮放功能。
def zoom_book(self, plus=True): a, b = self。size if plus: a += 0。4 b += 0。4 self。size = (a, b) self。set_page() elif not plus and a > 0: if a >= 1: a -= 0。4 b -= 0。4 self。size = (a, b) self。set_page()
Pixmap -> label -> area(MyArea) -> vbox(QVBoxLayout) -> tab(QWidget) -> self。tabwidget(QTabWidge)。
tab 獲取 tab 物件,layout 獲取 vbox 物件,widget 獲取 area 物件,直接更改 area 上 label 控制元件。
def set_page(self): # 載入頁面 page = self。doc。loadPage(self。current_page) # 獲取當前 Widget tab = self。tabwidget。currentWidget() # 獲取當前的 Layout layout = tab。layout() # 獲取 Layout 上的控制元件 widget = layout。itemAt(0)。widget() # 獲取已經繪製好的 label 物件 label = self。page_pixmap(page) # 將 widget 的內容更改為現在的 label 物件 widget。setWidget(label)
接著我們介紹如何實現翻頁功能
翻頁功能
這次,我們實現的 PDF 閱讀器只能同時閱讀一本書,所以翻頁功能只需由 self。current_page 控制就行。
self。doc。pageCount 為總頁數,當前頁數不能為負數或者大於總頁數。更改完 self。current_page 之後,就可以執行 self。set_page 操作,直接更改 area 上的 label 控制元件。
def set_current_page(self, right): if right and self。current_page < self。doc。pageCount - 1: self。current_page += 1 elif not right and self。current_page > 0: self。current_page -= 1 def switch_page(self, right=True): self。set_current_page(right) self。set_page()
點選連結,獲取原始碼。