主頁 > 後端開發 > 用 PyQt 打造具有專業外觀的GUI(上)

用 PyQt 打造具有專業外觀的GUI(上)

2020-12-10 18:02:47 後端開發

PyQt的布局管理器layout managers提供了一種用戶友好且高效的方式,可以在GUI上排列圖形組件或小部件,正確布置視窗小部件將使您的GUI應用程式看起來更加優美和專業,學習有效地做到這一點是您使用Python和PyQt進行GUI應用程式開發和運行的一項基本技能,

在本教程中,您將學習:

  • 使用PyQt的layout managers有什么好處

  • 如何使用PyQt的layout managers在GUI上以編程方式布置視窗小部件

  • 如何為您的GUI應用程式選擇正確的layout manager

  • 如何在基于主視窗和基于對話框的應用程式中布置小部件

有了這些知識和技能,您就可以使用Python和PyQt創建具有專業外觀的GUI應用程式,

在GUI上布置圖形元素

在創建圖形用戶界面(GUI)應用程式時,一個常見的問題是如何使圖形組件(按鈕,選單,工具列,標簽等)一致地放置在表單和視窗上,此程序稱為GUI布局(GUI layout,),這是創建GUI應用程式的重要步驟,

之前如果要在視窗上布置圖形組件或視窗小部件,則可以采用以下方法之一:

  • 為視窗上的每個小部件確定并手動設定靜態大小和位置,

  • 動態計算并設定每個小部件的大小和位置,

第一種方法相當直接,但是至少具有以下缺點:

  • 您的視窗將無法調整大小,以不同的螢屏解析度顯示它們時可能會導致問題,

  • 您的標簽可能不能正確地支持本地化,因為給定文本的長度在不同語言之間會發生變化,

  • 您的視窗小部件在不同平臺上的顯示方式將有所不同,這使得撰寫看起來不錯的多平臺應用程式變得困難,

第二種方法更靈活,但是,它也有缺點:

  • 您必須進行大量手動計算才能確定每個小部件的正確大小和位置,

  • 您必須做一些額外的計算才能正確回應視窗大小調整,

  • 每當您修改視窗布局時,都必須重做所有計算,

即使您仍然可以使用這兩種方法中的任何一種來布局GUI,大多數時候您可能還是希望使用由最先進的GUI框架或工具包實作的第三種且更方便的方法:布局管理器layout managers,注意:在某些GUI框架(例如Tkinter)中,布局管理器也稱為geometry managers

layout managers會根據您的特定需求自動在GUI上排列小 部件,它避免了第一種方法的兼容性缺點以及第二種方法的復雜計算,

在以下各節中,您將了解PyQt的內置布局管理器以及如何使用它們有效地布局GUI應用程式的圖形組件,

多樣的PyQt布局形式

在PyQt中,小部件是用作GUI應用程式構建塊的圖形組件,將一堆小部件放在視窗上以創建GUI時,需要給它們一些順序,您需要設定視窗小部件的大小和在視窗上的位置,還需要定義當用戶調整基礎視窗大小時它們的行為,

注意:PyQt5的官方檔案中有一些不完整的部分,要解決此問題,您可以查看PyQt4檔案,Qt for Python檔案或原始Qt檔案,

要在PyQt的視窗或表單上排列小部件,可以使用以下技術:

  • 在小部件上使用.resize().move()來提供絕對大小和位置,

  • 重新實作.resizeEvent()并動態計算小部件的大小和位置,

  • 使用布局管理器,讓他們為您做所有的計算和辛苦的作業,

這些技術通常對應于上一節中介紹的用于布局GUI的三種不同方法,

再說一次,動態計算尺寸和位置可能是個好方法,但是大多數時候,使用布局管理器會更好,在PyQt中,布局管理器是提供所需功能以自動管理布局中小部件的大小,位置和調整大小行為的類,

使用布局管理器,您可以自動在任何母部件、容器、小部件內排列子部件,使用布局管理器將確保您充分利用GUI上的可用空間,并確保當用戶調整視窗大小時,應用程式仍然可用,

布局管理器充當小部件和其他布局的容器時,要將小部件添加到布局管理器,請在當前布局上呼叫.addWidget(),要將布局添加到另一個布局,請在當前布局上呼叫.addLayout(),您將在“嵌套布局以構建復雜的GUI”一節中更深入地了解嵌套布局,

將所有必需的小部件添加到布局管理器后,即可使用.setLayout()在給定的小部件上設定布局管理器,您可以在QWidget的任何子類(包括視窗或表單)上設定布局管理器,

注意:QMainWindow是一個PyQt類,可用于創建main widow–style applications.,此類具有其自己的內置布局管理器,因此,如果您使用的是QMainWindow,則通常不需要在主視窗物件上設定布局管理器,

布局中的所有視窗小部件都會自動設定為安裝布局的視窗小部件的子級,而不是布局本身,這是因為視窗小部件只能將其他視窗小部件(而不是布局)作為其父級,

PyQt的布局管理器提供了一些很酷的功能,可以使您在創建美觀的GUI應用程式時更加輕松:

  • 處理小部件的大小和位置,無需任何計算

  • 當用戶調整基礎視窗的大小時,處理視窗小部件的大小調整和重新定位

  • 調整標簽大小以更好地支持國際化

  • 為多平臺應用程式提供本機視窗布局

從長遠來看,使用布局管理器還將極大地提高您的生產率并改善代碼的可維護性,

PyQt提供了四個通用布局管理器類:

  • QHBoxLayout在水平框中排列小部件,

  • QVBoxLayout在垂直框中排列小部件,

  • QGridLayout將小部件排列在網格中,

  • QFormLayout將小部件安排在兩列中,

在接下來的幾節中,您將學習如何使用這些通用布局管理器的基礎知識,

使用通用布局管理器

使用PyQt創建GUI應用程式時,通常會使用上一節末尾看到的四種通用布局中的一種或多種方法,來將視窗小部件布置在視窗和表單上,

在接下來的幾節中,您將在一些示例的幫助下學習如何創建和使用四個通用布局管理器,

構建水平布局:QHBoxLayout

Box layout managers從父布局或視窗小部件獲得的空間被分成多個盒子或單元格,然后使布局中的每個視窗小部件填充一個盒子,

QHBoxLayout是PyQt中兩個可用的框布局之一,這個布局管理器允許您水平排列小部件,一個接一個,這些小部件從左到右添加到布局中,這意味著您首先在代碼中添加的小部件將是布局中最左側的小部件,

要將小部件添加到QHBoxLayout物件,請在布局物件上呼叫.addWidget(widget,stretch,alignment),此方法接受一個必需引數和兩個可選引數:

  • widget是必填引數,用于保存要添加到布局的特定widget,

  • Stretch是一個可選引數,其中包含一個整數,該整數表示要應用于小部件的拉伸因子,具有較高拉伸因子的小部件在調整視窗大小時會增長更多,默認為0,這表示未分配視窗小部件拉伸因子,

  • alignment是一個可選引數,其中包含水平和垂直標志,您可以組合這些標志,以在其包含的單元格內產生所需的小部件對齊方式,默認為0,這意味著小部件將填充整個單元格,

下面是一個小型應用程式,顯示了如何使用QHBoxLayout創建水平布局,在此示例中,您將使用QPushButton物件根據將小部件添加到代碼中的順序更好地可視化每個小部件在布局中的放置位置:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QHBoxLayout,
    QPushButton,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QHBoxLayout Example")
        # Create a QHBoxLayout instance
        layout = QHBoxLayout()
        # Add widgets to the layout
        layout.addWidget(QPushButton("Left-Most"))
        layout.addWidget(QPushButton("Center"), 1)
        layout.addWidget(QPushButton("Right-Most"), 2)
        # Set the layout on the application's window
        self.setLayout(layout)
        print(self.children())

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

在第15行上,創建一個稱為layoutQHBoxLayout物件,在第17至19行,使用.addWidget()將三個按鈕添加到布局中,請注意,您分別在“居中”和“最右”按鈕中將1和2傳遞給了stretch引數,在第21行,使用.setLayout()將布局設定為視窗的頂級布局,

如果您運行此應用程式,則會在螢屏上看到以下視窗:

該視窗包含三個水平排列的按鈕,請注意,“最左鍵”按鈕對應于您在代碼中添加的第一個按鈕,因此,按鈕的顯示順序與您在代碼中添加按鈕的順序(從左到右)(從上到下)相同,

“居中”和“最右邊”按鈕具有不同的拉伸系數,因此在調整視窗大小時,它們會按比例縮放,

此外,布局中的所有按鈕和布局本身都設定為Window的子級,這是由布局物件自動完成的,該布局物件在每個小部件上內部呼叫.setParent(),在第17行上對print()的呼叫將在您的終端上列印Window的子代串列,以證明此行為,

構建垂直布局:QVBoxLayout

QVBoxLayout垂直排列小部件,一個在另一個下方,您可以使用此類創建垂直布局,并從上到下排列視窗小部件,由于QVBoxLayout是另一個框布局,因此其.addWidget()方法的作業方式與QHBoxLayout中的相同,

下面是一個PyQt應用程式,它顯示了如何創建和使用QVBoxLayout物件在GUI中創建小部件的垂直排列:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QVBoxLayout Example")
        self.resize(270, 110)
        # Create a QVBoxLayout instance
        layout = QVBoxLayout()
        # Add widgets to the layout
        layout.addWidget(QPushButton("Top"))
        layout.addWidget(QPushButton("Center"))
        layout.addWidget(QPushButton("Bottom"))
        # Set the layout on the application's window
        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

在第16行上,您將創建QVBoxLayout的實體,在第18至20行上,將三個按鈕添加到布局中,最后,將布局設定為視窗的頂層布局,

如果您運行此應用程式,則將顯示以下視窗:

您的視窗顯示了三個垂直排列的按鈕,一個在另一個按鈕下面,這些按鈕的顯示順序(從上到下)與您在代碼中添加的順序(從上到下)相同,

在網格中排列小部件:QGridLayout

您可以使用QGridLayout將小部件排列在行和列的網格中,每個小部件將在網格中具有相對位置,要定義小部件的位置或網格中的單元格,請使用表格(行,列)的一對坐標,這些坐標應該是從零開始的整數,

QGridLayout占用其父級的可用空間,將其劃分為行和列,然后將每個小部件放置在其自己的單元格或框中,QGridLayout根據小部件的數量及其坐標自動計算出最終布局將包含多少行和多少列,如果您不將小部件添加到給定的單元格,則QGridLayout將使該單元格為空,

要將小部件添加到網格布局,請在布局上呼叫.addWidget(),此方法有兩個不同的多載實作:

  • addWidget(widget, row, column, alignment)widget添加到(row, column)的單元格中,

  • addWidget(widget,fromRow,fromColumn,rowSpan,columnSpan,alignment)widget添加到單元格中,跨越多行,多列或兩者,

第一個實作采用以下引數:

  • widget是必填引數,用于保存您需要添加到布局的特定小部件,

  • row是必填引數,其中包含一個整數,該整數表示網格中行的坐標,

  • column是必填引數,其中包含一個整數,該整數表示網格中列的坐標,

  • alignment是一個可選引數,用于保存小部件在其包含的單元格內的對齊方式,默認為0,這意味著小部件將填充整個單元格,

這是一個如何使用QGridLayout創建小部件網格的示例:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QGridLayout,
    QPushButton,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QGridLayout Example")
        # Create a QGridLayout instance
        layout = QGridLayout()
        # Add widgets to the layout
        layout.addWidget(QPushButton("Button at (0, 0)"), 0, 0)
        layout.addWidget(QPushButton("Button at (0, 1)"), 0, 1)
        layout.addWidget(QPushButton("Button at (0, 2)"), 0, 2)
        layout.addWidget(QPushButton("Button at (1, 0)"), 1, 0)
        layout.addWidget(QPushButton("Button at (1, 1)"), 1, 1)
        layout.addWidget(QPushButton("Button at (1, 2)"), 1, 2)
        layout.addWidget(QPushButton("Button at (2, 0)"), 2, 0)
        layout.addWidget(QPushButton("Button at (2, 1)"), 2, 1)
        layout.addWidget(QPushButton("Button at (2, 2)"), 2, 2)
        # Set the layout on the application's window
        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

在第15行上,創建QGridLayout物件,然后,在第17至25行上,使用.addWidget()將小部件添加到布局中,要查看沒有分配小部件的網格布局如何管理單元,請注釋掉其中的一行或多行,然后再次運行應用程式,

如果您從命令列運行此代碼,則將獲得如下所示的視窗:

QGridLayout物件中的每個小部件都占據由您在.addWidget()中提供的一對坐標定義的單元格,每個按鈕上的文字均反映了這些坐標,坐標是從零開始的,因此第一個單元格位于(0,0)

.addWidget()的第二種實作中,widgetalignment引數保持不變,并且您還有四個其他引數可用于將小部件放置在多行或多列中:

  • fromRow賦值一個整數,該整數表示小部件將在其中開始的行,

  • fromColumn賦值一個整數,該整數表示小部件將在其中開始的列,

  • rowSpan賦值一個整數,該整數表示視窗小部件將在網格中占據的行數,

  • columnSpan賦值一個整數,該整數表示視窗小部件將在網格中占據的列數,

這是一個顯示.addWidget()變體如何作業的應用程式:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QGridLayout,
    QPushButton,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QGridLayout Example")
        # Create a QGridLayout instance
        layout = QGridLayout()
        # Add widgets to the layout
        layout.addWidget(QPushButton("Button at (0, 0)"), 0, 0)
        layout.addWidget(QPushButton("Button at (0, 1)"), 0, 1)
        layout.addWidget(QPushButton("Button Spans two Cols"), 1, 0, 1, 2)
        # Set the layout on the application's window
        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

在第19行,使用.addWidget()的第二種實作來添加一個占用網格中兩列的按鈕,該按鈕從第二行(fromRow = 1)和第一列(fromColumn = 0)開始,最后,該按鈕占據一行(rowSpan = 1)和兩列(columnSpan = 2),

如果您運行此應用程式,則會在螢屏上看到以下視窗:

在這種布局中,您可以使一個小部件占用多個單元格,就像使用“跨越兩個列”的按鈕一樣,

在下篇中,我們將看到:

  • 如何快速創建表單

  • 嵌套布局以構建復雜的GUI

  • 使用多頁布局和小部件

  • 布置應用程式的主視窗

  • 布置應用程式的對話框

  • 在PyQt布局中管理輸入框

更多閱讀

有人在代碼里下毒!慎用 pip install 命令

pip 20.3 新版本發布!即將拋棄 Python 2.x

5 分鐘掌握 Python 中的 Hook 鉤子函式

特別推薦

程式員摸魚指南

為你精選的硅谷極客資訊,

來自FLAG巨頭開發者、技術、創投一手訊息


點擊下方閱讀原文加入社區會員

點贊鼓勵一下

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/232575.html

標籤:python

上一篇:一文搞懂Java日志級別,重復記錄、丟日志問題

下一篇:學習之旅3-python高級資料型別

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more