tft每日頭條

 > 生活

 > pyqt5常用函數pdf

pyqt5常用函數pdf

生活 更新时间:2025-04-07 14:53:08

pyqt5常用函數pdf(PyQt5從零開始制作PDF)1

此前,我已經寫了三篇關于 Ui 界面的文章,分别是:

使用 Pyqt5 制作猜數遊戲 GUI、[Python實戰]你也能寫的計時器程序和[Python實戰]Python制作天氣查詢軟件。這次,我們使用 Python 實現 PDF 閱讀器。

這篇文章,主要介紹如何實現主界面,以及添加、删除圖書封面,後續會不斷完善程序功能。

效果圖

pyqt5常用函數pdf(PyQt5從零開始制作PDF)2

UI 設計

首先使用 Qt Designer 設計出圖形界面:

新建一個 MainWindow 主界面,然後設置一個 toolbar,并在 toolbar 中添加三個 action,并為每個 action 設置好相應圖标。

也可以直接 compile 我制作好的 PyReader.ui 文件,或者導入 Ui_PyReader.py 文件。

pyqt5常用函數pdf(PyQt5從零開始制作PDF)3

依賴要求

  1. Python3
  2. PyQt5
  3. PyMuPDF

主要任務

我們使用 PyMuPDF 來解析 PDF ,來獲取 PDF 文本信息。

  • 安裝

我們隻要在 cmd 中輸入:pip install PyMuPDF,即可安裝 PyMuPDF。

  • 導入

# 導入 PyMuPDF import fitz

在本節中,我們隻需了解以下幾個基本操作:

fitz.open() 函數用來讀取 PDF 文件内容,doc.loadPage() 函數用來獲取具體某一頁的信息。特别的 ,我們使用loadPage(0) 來獲取封面信息。

# 讀取 PDF doc = fitz.open(fname) # 獲取第 n 頁内容 page = doc.loadPage(n)

本節主要的内容就是把封面渲染到主界面中,并完成添加與删除封面的任務。

顯示表格

我們采用 QtWidgets.QTableWidget 表格控件來顯示封面。

首先讓我們設置表格樣式與功能:

其中,我們設置了單元格的縱橫比為 4 : 3,以及其他的一些靜态屬性,并将 self.table 與右鍵菜單綁定,支持點擊單元格調用 self.generateMenu 函數。

def _setTableStyle(self): # 開啟水平與垂直滾軸 self.table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) # 設置 5 行 8 列 的表格 self.table.setColumnCount(8) self.table.setRowCount(5) # 設置标準寬度 self.width = self.screen.width() // 8 # 設置單元格的寬度 for i in range(8): self.table.setColumnWidth(i, self.width) # 設置單元格的高度 # 設置縱橫比為 4 : 3 for i in range(5): self.table.setRowHeight(i, self.width * 4 // 3) # 隐藏标題欄 self.table.verticalHeader().setVisible(False) self.table.horizontalHeader().setVisible(False) # 禁止編輯 self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) # 不顯示網格線 self.table.setShowGrid(False) # 将單元格綁定右鍵菜單 # 點擊單元格,調用 self.generateMenu 函數 self.table.setContextMenuPolicy(Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.generateMenu)

添加封面

首先讓我們來看如何生成 TableWidget 可顯示的 圖像類文件。

我們通過 doc.loadPage(0) 獲取頁面對象,并傳遞給 render_pdf_page() 函數,設置縮放比為 1 : 1。首先構建 QImage 對象,在通過 convertFromImage 函數将 QImage 對象轉化為可顯示對象。

# 顯示 PDF 封面 # page_data 為 page 對象 def render_pdf_page(page_data, for_cover=False): # 圖像縮放比例 zoom_Matrix = fitz.Matrix(4, 4) if for_cover: zoom_matrix = fitz.Matrix(1, 1) # 獲取封面對應的 Pixmap 對象 # alpha 設置背景為白色 pagePixmap = page_data.getPixmap( matrix = zoom_matrix, alpha=False) # 獲取 image 格式 imageFormat = QtGui.QImage.Format_RGB888 # 生成 QImage 對象 pageQImage = QtGui.QImage( pagePixmap.samples, pagePixmap.width, pagePixmap.height, pagePixmap.stride, imageFormat) # 生成 pixmap 對象 pixmap = QtGui.QPixmap() pixmap.convertFromImage(pageQImage) return pixmap

接着,我們就要想單元格中添加封面圖片:

我們使用工具欄中的 号來添加 PDF 封面。

self.addbar.triggered.connect(self.open),當點擊 時,就會調用 self.open 函數。

我們通過 getOpenFileName() 函數來獲取文件地址,self 後面的三個參數分别是窗口名稱,文件默認路徑以及支持的文件類型。這個函數返回文件的地址。

filter_book() 函數用來确保不會重複顯示同一本書的封面。

def getfile(self): # 打開單個文件 fname, _ = QFileDialog.getOpenFileName(self, 'Open files', './', '(*.pdf)') return fname def open(self): # 打開文件 fname = self.getfile() if self.filter_book(fname): self.setIcon(fname) # 獲取無重複圖書的地址 def filter_book(self, fname): if not fname: return False if fname not in self.booklist: self.booklist.append(fname) return True return False

然後,我們就要将 PDF 封面渲染到主界面上:

label.setScaledContents(True) 使得圖片可以充滿 label。self.table.setCellWidget(self.x, self.y, label) 用來設置标簽的行與列。最後确保每八個元素換行,換行後将列數清零。

def setIcon(self, fname): # 打開 PDF doc = fitz.open(fname) # 加載封面 page = doc.loadPage(0) # 生成封面圖像 cover = render_pdf_page(page, True) label = QLabel(self) # 設置圖片自動填充 label label.setScaledContents(True) # 設置封面圖片 label.setPixmap(QPixmap(cover)) # 設置單元格元素為 label self.table.setCellWidget(self.x, self.y, label) # 删除 label 對象,防止後期無法即時刷新界面 # 因為 label 的生存周期未結束 del label # 設置當前行數與列數 self.crow, self.ccol = self.x, self.y # 每 8 個元素換行 if (not self.y % 7) and (self.y): self.x = 1 self.y = 0 else: self.y = 1

右鍵菜單

上面我們已經提到,如何将單元格與右鍵菜單綁定。

pyqt5常用函數pdf(PyQt5從零開始制作PDF)4

本次教程中,右鍵菜單隻有兩項,分别為開始閱讀(暫未實現),以及删除圖書。

def generateMenu(self, pos): row_num = col_num = -1 # 獲取選中的單元格的行數以及列數 for i in self.table.selectionModel().selection().indexes(): row_num = i.row() col_num = i.column() # 若選取的單元格中有元素,則支持右鍵菜單 if (row_num < self.crow) or (row_num == self.crow and col_num <= self.ccol): menu = QMenu() # 添加選項 item1 = menu.addAction('開始閱讀') item2 = menu.addAction('删除圖書') # 獲取選項 action = menu.exec_(self.table.mapToGlobal(pos)) if action == item1: pass # 點擊選項二,調用 self.delete_book 删除圖書 elif action == item2: self.delete_book(row_num, col_num)

接下來,讓我們看如何删除圖書:

首先維護一個 self.booklist ,裡面儲存無重複 PDF 文件地址。首先獲取圖書在 booklist 中的索引,在 booklist 中删除該元素。接着清空選中單元格之後(包含選中單元格)的所有單元格的内容。最後将 booklist 中 index 之後的圖書地址重新顯示到 table 上。簡單地說,就是删除選中單元格,并将之後單元格向前挪一位。

# 删除圖書 def delete_book(self, row, col): # 獲取圖書在列表中的位置 index = row * 8 col self.x = row self.y = col if index >= 0: self.booklist.pop(index) i, j = row, col while 1: # 移除 i 行 j 列單元格的元素 self.table.removeCellWidget(i, j) # 一直删到最後一個有元素的單元格 if i == self.crow and j == self.ccol: break if (not j % 7) and j: i = 1 j = 0 else: j = 1 # 如果 booklist 為空,設置當前單元格為 -1 if not self.booklist: self.crow = -1 self.ccol = -1 # 删除圖書後,重新按順序顯示封面圖片 for fname in self.booklist[index:]: self.setIcon(fname)

pyqt5常用函數pdf(PyQt5從零開始制作PDF)5

點擊下面鍊接,獲取源碼。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved