欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實(shí)現(xiàn)跨平臺(tái)表格數(shù)據(jù)分頁打印預(yù)覽處理詳解

 更新時(shí)間:2025年03月12日 08:32:25   作者:伍華聰  
這篇文章主要為大家詳細(xì)介紹了如何使用PySide6/PyQt6實(shí)現(xiàn)Python跨平臺(tái)表格數(shù)據(jù)分頁打印預(yù)覽處理,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

我曾經(jīng)在前面使用WxPython開發(fā)跨平臺(tái)應(yīng)用程序的時(shí)候,寫了一篇《WxPython跨平臺(tái)開發(fā)框架之列表數(shù)據(jù)的通用打印處理》,介紹在WxPython下實(shí)現(xiàn)表格數(shù)據(jù)分頁打印處理的過程,在Windows下和MacOS測試效果表現(xiàn)一致。然后在WxPython跨平臺(tái)的基礎(chǔ)上,我利用類似WxPhon的程序框架,使用PySide6/PyQt6實(shí)現(xiàn)了另一套跨平臺(tái)的程序開發(fā),功能上更是比WxPython的實(shí)現(xiàn)更加細(xì)致和完善了,本篇隨筆介紹使用PySide6/PyQt6實(shí)現(xiàn)Python跨平臺(tái)表格數(shù)據(jù)分頁打印預(yù)覽處理。

1、回顧WxPython的列表數(shù)據(jù)的通用打印處理

WxPython實(shí)現(xiàn)數(shù)據(jù)的表格預(yù)覽和打印處理,主要是利用wx.PrintPreview、wx.Printer 和 wx.Printout 等 wxPython 提供的用于打印功能的核心類來處理。

一般列表界面,如下所示。

我們打印模塊的處理,需要把這些列表的記錄顯示在打印預(yù)覽界面上,并決定是否繼續(xù)打印即可。

打印預(yù)覽入口,在列表界面上右鍵,彈出打印菜單,如下界面所示。

打印預(yù)覽界面如下所示。

 其打印的邏輯,主要就是調(diào)用MyPrintOut的自定義對(duì)象,然后調(diào)用PrintPreview進(jìn)行打印預(yù)覽窗體的顯示即可。具體的邏輯還是在自定義的 MyPrintout 類里面。

2、使用PySide6/PyQt6實(shí)現(xiàn)Python跨平臺(tái)表格數(shù)據(jù)分頁打印處理

而使用PySide6/PyQt6實(shí)現(xiàn)Python跨平臺(tái)表格數(shù)據(jù)分頁打印預(yù)覽處理,邏輯上有所不同,這里沒有PrintOut對(duì)象來處理了。需要根據(jù)表格的TableModel對(duì)象來進(jìn)行數(shù)據(jù)的分頁打印。

在開始介紹實(shí)現(xiàn)邏輯前,我們先來看看PySide6/PyQt6實(shí)現(xiàn)打印預(yù)覽的效果。

同樣我們是在表格展示上給出通用的打印菜單入口,如上圖所示,作為答應(yīng)預(yù)覽的統(tǒng)一入口。

而由于數(shù)據(jù)打印的時(shí)候,表格列字段可能有些多有些少,因此最好能夠根據(jù)表格列選擇那些可以打印,那些忽略。而選擇后,可以進(jìn)一步選擇橫向或者豎向等信息,因此在彈出打印預(yù)覽前,我們讓用戶確認(rèn)一下答應(yīng)的信息,我訂做了一個(gè)打印預(yù)覽前的設(shè)置對(duì)話框,如下所示。

這樣我們可以定制打印的相關(guān)信息,也方便我們對(duì)打印的格式精細(xì)化控制。

對(duì)于模型數(shù)據(jù)很多,這需要考慮到分頁的處理,我們需要再實(shí)現(xiàn)打印預(yù)覽的時(shí)候,實(shí)現(xiàn)分頁顯示的邏輯,分頁打印預(yù)覽的界面如下所示。

了解了PySide/PyQt的打印預(yù)覽界面后,我們來分析下實(shí)現(xiàn)打印的邏輯處理。

打印預(yù)覽和打印的時(shí)候,我們需要考慮顯示器和實(shí)際打印設(shè)備之間的顯示尺寸是不同的,有時(shí)候顯示器設(shè)置顯示為200%或其他偏大的數(shù)據(jù),如果不注意尺寸的調(diào)整,很可能打印預(yù)覽得到的是一個(gè)很小區(qū)域的顯示內(nèi)容。

在 PySide6 /PyQt6 中,如果你想實(shí)現(xiàn) QTableView 打印功能并確保兼容不同操作系統(tǒng)(如 macOS 和 Windows)的尺寸變化,你可以使用 QPrinter 和 QPrintDialog 來處理打印。要確保尺寸適應(yīng)變化,你可以根據(jù)打印內(nèi)容自動(dòng)調(diào)整頁面布局。

我編寫了一個(gè)函數(shù),用于計(jì)算縮放比例,如下函數(shù)所示。

def calculateScale(self, printer: QPrinter, painter: QPainter) -> float:
        """計(jì)算每毫米的邏輯單位"""

        # 獲取打印機(jī)的 DPI
        ppiPrinterX = printer.resolution()
        ppiPrinterY = ppiPrinterX  # 假設(shè) X 和 Y 方向的 DPI 相同

        # 獲取屏幕的 DPI
        screen = QApplication.primaryScreen()
        ppiScreenX = screen.logicalDotsPerInchX()
        ppiScreenY = screen.logicalDotsPerInchY()

        # 計(jì)算縮放比例,
        self.logScale = logScale = float(ppiPrinterX) / float(ppiScreenX)

        # 可根據(jù) DPI 比例調(diào)整字體大小
        print(f"縮放比例: {logScale}")

        # 獲取頁面大小和繪制區(qū)域大小
        pageRect = printer.pageRect(QPrinter.Unit.DevicePixel)  # 頁面大?。ㄏ袼兀?
        paintRect = painter.viewport()  # 繪制區(qū)域大?。ㄏ袼兀?

        # 計(jì)算縮放比例
        scale = logScale * float(paintRect.width()) / float(pageRect.width())

        # 設(shè)置 QPainter 的縮放比例
        painter.scale(scale, scale)

        # 計(jì)算每毫米的邏輯單位
        logUnitsMM = float(ppiPrinterX) / (logScale * 25.4)
        print(f"每毫米的邏輯單位: {logUnitsMM}")
        return logUnitsMM

打印預(yù)覽的處理,主要就是根據(jù)設(shè)置對(duì)話框,獲得橫向還是縱向,以及頁面大小、標(biāo)題等信息,然后實(shí)現(xiàn)QPreviewDialog里面的paintRequest事件即可,如下預(yù)覽邏輯處理代碼。

def print_preview(self, setting: PrintSetting) -> None:
        """打印預(yù)覽"""

        # print(setting.__dict__)
        printer = QPrinter()  # QPrinter.PrinterMode.HighResolution

        # 打印的處理
        printer.setPageSize(setting.page_size)
        printer.setPageOrientation(setting.page_orientation)
        self.print_cols = setting.print_cols  # 打印指定列的索引列表
        self.print_title = setting.print_title  # 打印標(biāo)題
        self.settings = setting  # 保存打印設(shè)置

        preview_dialog = QPrintPreviewDialog(printer)
        <strong>preview_dialog.paintRequested.connect(self.print_preview_paint)</strong>
        preview_dialog.exec()

打印預(yù)覽的處理邏輯,主要就是需要根據(jù)縮放的尺寸獲得對(duì)應(yīng)的打印區(qū)域大小,并根據(jù)頁面的大小和實(shí)現(xiàn)打印的內(nèi)容顯示,計(jì)算好尺寸,也就是一般按每頁放置多少行,或者每行的高度來計(jì)算,如果需要分頁,則標(biāo)識(shí)一下即可。

def print_preview_paint(self, printer: QPrinter) -> None:
        """打印預(yù)覽繪制"""
        self.painter = painter = QPainter(printer)

        # 計(jì)算每毫米的邏輯單位
        self.logUnitsMM = self.calculateScale(printer, painter)

        # 獲取頁面大小
        # unit 參數(shù)的可選值有:
        # QPrinter.Unit.Point:點(diǎn)(1 點(diǎn) = 1/72 英寸)
        # QPrinter.Unit.Millimeter:毫米(常用)
        # QPrinter.Unit.Inch:英寸
        # QPrinter.Unit.Pixel:像素

        # 獲取頁面的可打印區(qū)域
        page_rect = printer.pageRect(QPrinter.Unit.Millimeter)
        self.page_height = page_height = page_rect.height() * self.logUnitsMM
        self.page_width = page_width = page_rect.width() * self.logUnitsMM

如果內(nèi)容需要分頁才能展示完,那么你要使用printer.newPage()來告訴打印機(jī)進(jìn)行分頁。

# 分頁打印
        print(f"總行數(shù): {total_rows}, 總頁數(shù): {total_pages}")
        for page in range(total_pages):
            if page > 0:  # 非第一頁,需要換頁
                printer.newPage()
            self.print_page(page, rows_per_page, self.print_cols)

        self.painter.end()

打印的時(shí)候,我們打印列頭和每列內(nèi)容,都是根據(jù)實(shí)際的列寬進(jìn)行一定比例的處理,讓它能夠兼容打印最佳效果。

打印表頭的時(shí)候,如下代碼。

index = 0  # 用來計(jì)算遞增的列數(shù)
        for col in range(self.columnCount()):
            if print_cols and col not in print_cols:
                continue
            header_text = self.GetColLabelValue(col)
            self.painter.drawText(
                int(x_offset + sum(col_widths[:index])),  # 累計(jì)不同的列寬
                y_offset,
                header_text,
            )
            index += 1

打印表格每列的內(nèi)容,處理規(guī)則也是類似,如下代碼所示

# 繪制表格內(nèi)容
        for row in range(
            page * rows_per_page, min((page + 1) * rows_per_page, self.total_rows)
        ):
            y_offset += self.row_height
            index = 0  # 用來計(jì)算遞增的列數(shù)
            for col in range(self.columnCount()):
                if print_cols and col not in print_cols:
                    continue
                # 獲取單元格數(shù)據(jù)
                text = self.GetValue(row, col)
                # 繪制單元格內(nèi)容
                self.painter.drawText(
                    int(x_offset + sum(col_widths[:index])),  # 累計(jì)不同的列寬
                    y_offset,
                    text,
                )
                index += 1

其他如標(biāo)題,橫線、頁碼等信息,根據(jù)顯示規(guī)則繪制即可。

以上就是Python實(shí)現(xiàn)跨平臺(tái)表格數(shù)據(jù)分頁打印預(yù)覽處理詳解的詳細(xì)內(nèi)容,更多關(guān)于Python表格數(shù)據(jù)分頁打印的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • pandas將DataFrame的幾列數(shù)據(jù)合并成為一列

    pandas將DataFrame的幾列數(shù)據(jù)合并成為一列

    本文主要介紹了pandas將DataFrame的幾列數(shù)據(jù)合并成為一列,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Python Websockets庫的使用指南

    Python Websockets庫的使用指南

    python websockets庫是一個(gè)用于創(chuàng)建WebSocket服務(wù)器和客戶端的Python庫,它提供了一種簡單的方式來實(shí)現(xiàn)實(shí)時(shí)通信,支持異步和同步操作,并且易于使用,本文給大家介紹了Python Websockets庫的使用指南,需要的朋友可以參考下
    2025-04-04
  • pytorch 計(jì)算ConvTranspose1d輸出特征大小方式

    pytorch 計(jì)算ConvTranspose1d輸出特征大小方式

    這篇文章主要介紹了pytorch 計(jì)算ConvTranspose1d輸出特征大小方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • 使用python創(chuàng)建股票的時(shí)間序列可視化分析

    使用python創(chuàng)建股票的時(shí)間序列可視化分析

    這篇文章主要為大家詳細(xì)介紹了python創(chuàng)建股票的時(shí)間序列可視化分析,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Python的Flask框架中使用Flask-Migrate擴(kuò)展遷移數(shù)據(jù)庫的教程

    Python的Flask框架中使用Flask-Migrate擴(kuò)展遷移數(shù)據(jù)庫的教程

    Flask-Migrate可以幫助Flask應(yīng)用程序通過預(yù)設(shè)的Python腳本完成數(shù)據(jù)庫遷移操作,這里我們就來看一下Python的Flask框架中使用Flask-Migrate擴(kuò)展遷移數(shù)據(jù)庫的教程,需要的朋友可以參考下
    2016-06-06
  • Django與遺留的數(shù)據(jù)庫整合的方法指南

    Django與遺留的數(shù)據(jù)庫整合的方法指南

    這篇文章主要介紹了Django與遺留的數(shù)據(jù)庫整合的方法指南,Django是最具人氣的Python開發(fā)框架,需要的朋友可以參考下
    2015-07-07
  • Python request中文亂碼問題解決方案

    Python request中文亂碼問題解決方案

    這篇文章主要介紹了Python request中文亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 利用python實(shí)現(xiàn)可視化大屏

    利用python實(shí)現(xiàn)可視化大屏

    這篇文章主要介紹了利用python實(shí)現(xiàn)可視化大屏,文章圍繞主題展開對(duì)如何利用python實(shí)現(xiàn)可視化大屏,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)和工作有所幫助
    2022-03-03
  • Numpy數(shù)組的切片索引操作

    Numpy數(shù)組的切片索引操作

    本文主要介紹了Numpy數(shù)組的切片索引操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Python中星號(hào)的五種用法小結(jié)

    Python中星號(hào)的五種用法小結(jié)

    本文主要介紹了Python中星號(hào)的五種用法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02

最新評(píng)論