欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    前言】PySide6是用來做圖形界面開發的強有力模塊,能夠輕松設計出復雜的圖形界面,樣式美觀,靈活多變。尤其是該模塊里面的Qt設計師工具軟件,讓我們在可視化環境里通過拖拽組件設計程序窗體,而且在Qt設計師里還可以連接信號和槽,實現了一些預設功能的直接封裝,免去一部分代碼的書寫過程,效率非常高。

    在上一篇筆記里,已經對Qt設計師Designer做了全面介紹,但是對組件及其屬性和方法介紹的不全,并且基本沒有涉及代碼部分,所以在這篇筆記里將結合實例對這些內容進行重點介紹。


    一、圖形界面加載方法

    1、動態加載和靜態加載

    在Qt設計師中設計的圖形界面,保存在擴展名為ui的文件中,實際使用時需要在程序里加載,有兩種方式:動態加載和靜態加載。動態加載是直接讀入圖形界面ui文件,靜態加載是先將ui文件轉換成py文件,然后在程序中以模塊的形式進行導入。相比較而言,靜態加載比動態加載多了一個轉換的步驟,但是動態加載有一個最大的問題,那就是在程序中編寫代碼時,涉及到圖形界面里面的組件的代碼部分沒有提示。因為動態加載方式讀入的是ui文件,python不能識別出ui文件里面的組件,而靜態加載導入的是圖形界面ui文件轉換后的py文件,因此不存在代碼沒有提示的問題。如果將轉換工具配置在集成開發環境里,轉換ui文件非常方便,所以我現在只用靜態加載方式。

    2、靜態加載模板

    初學時,在python主程序和圖形界面之間總是存在著一個斷層,就是很難把圖形界面跟主程序代碼連接起來形成一個完整程序。首先是因為導入的庫太多,然后涉及到的文件又多,包括ui文件、ui轉換的py文件、qrc資源文件以及qrc轉換的py資源文件,一時之間很難理清這些文件的關系。其實真正掌握之后,加載圖形界面的代碼條理還是很清晰的,下面就來理順一下從設計窗體到靜態加載的流程。下面涉及的一些細節操作可以到我上一篇筆記中查看。

    (1)操作流程

    • 在Qt Designer中設計圖形界面,包括配置資源文件、建立動作、編輯信號和槽以及保存ui文件
    • 將ui文件轉換成py文件
    • 將qrc文件轉換成py文件
    • 在python程序中書寫相應代碼

    【注】靜態加載圖形界面用到的是ui和qrc文件轉換出來的py文件,并不依賴于ui和qrc文件本身。qrc轉換成的py文件里面都是圖像、圖標和聲音等資源文件的二進制數據,主程序的運行也不再依賴于圖像、圖標和聲音的源文件。py格式的資源文件我們不用管,它的調用是在圖形界面py文件里,程序已經為我們自動生成,如果主程序中還需用到資源文件,那么在主程序中也需要導入。

    (2)代碼加載流程

    • 從PySide6的相應模塊中導入相應的類
    • 從圖形界面py文件中導入主窗口類,Ui_MainWindow或Ui_Form
    • 以模塊方式導入資源文件
    • 實例化主窗口類,就是創建窗口對象
    • 初始化窗口
    • 創建QApplication類對象
    • 顯示窗口
    • 執行QApplication類對象的exec()方法,就是保持窗口循環,直到關閉窗口

    (3)靜態加載代碼模板

    為了代碼結構合理,我們通常為主窗口自定義一個類,繼承PySide6的QMainWindow類,把加載圖形界面的代碼都寫在自定義類里,主程序體里只有創建QApplication類對象、顯示窗口和窗口循環等幾條語句,這樣整體代碼條理非常清晰。模板代碼如下:

    # 從PySide6的相應模塊中導入必須用到的類
    from PySide6.QtWidgets import QApplication, QMainWindow
    
    # 從圖形界面py文件中導入主窗口類Ui_Form
    # 如果在Qt設計師里創建的窗口是Main Window,這里導入的就是Ui_MainWindow
    from main import Ui_Form  
    
    
    # 定義主窗口類,繼承QMainWindow
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()  # 調用父類的初始化方法,pycharm里一鍵輸入
            self.ui=Ui_Form()  # 創建窗口對象
            self.ui.setupUi(self)  # 調用窗口對象的初始化方法對窗口初始化
    
    app=QApplication([])  # 創建app對象,注意參數[]空列表必須有,暫時不需要有內容
    window=MainWindow()  # 創建自定義主窗口類的窗口對象
    window.show()  # 調用窗口對象的show方法顯示窗口
    app.exec()  # 調用app對象的exec方法循環顯示窗口

    二、窗口布局

    1、布局技巧

    • 規劃階段。事先規劃總體布局,規劃時遵循由外及里的原則,即先把窗口劃分成幾個大區域,然后再按照這個原則劃分大區域里包含的分區,依此類推,創建一個布局草圖
    • 操作階段。在實際操作階段,遵循由里而外的操作原則,按照布局規劃圖從左往右或者從上往下依次創建每個大區內部的分區布局。拿一個規劃的大區為例,先把大區內最小分區里的組件放置到窗口,并簡單排列,然后把這幾個組件全選,在任意組件上右鍵→布局→選擇合適布局方式(橫向或者縱向布局),這個分區的布局就做好了。按照這種方式,把這個大區內的其它分區的布局全都做好,最后把這個大區內的所有分區布局選中,選擇合適的布局方式,這個大區的總體布局就做好了。按照這種方式,把所有規劃大區的布局都做好,最后在對象查看器的最頂層對象(即主窗口)上右鍵→布局→選擇最終的布局結構。窗口的最終布局完成后,在對象查看器里窗口對象上就會顯示布局圖標(未完成時是紅色的禁止圖標),這種狀態下,所有窗口組件都可以隨窗口的變化而自適應的變化。

    布局演示如下:

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

    2、布局微調

    上面的布局完成之后,還存在著一些問題,需要進行微調。例如,中間部位兩個顯示區域在橫向上是對等的,而我們需要左邊區域小一些右邊區域大一些。但是,總體布局只要形成,就不能用鼠標拖動的方式來更改布局的大小。像這種需要在橫向上調整大小的布局,必須在兩個獨立的布局外邊再套上一個橫向布局,然后通過調整兩個獨立區域的占比就可以調整大小了,縱向亦然。那么問題又來了,現在總體布局已經形成,怎么樣單獨更改呢?解決辦法就是,先把這兩個區域外邊的布局打散,再重新設計這部分布局。另外,每個布局都可以調整其上下左右的間隔,有些地方可以用隔板(彈簧)組件進行分隔,以達到調整組件間距的目的。布局微調演示如下:

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

    3、使用qss樣式調節組件

    每種布局里面的組件都在布局方向上受到影響,例如橫向布局里面的組件的寬度就會受到布局的控制,想要修改就可以采取上面布局微調里介紹的辦法,但是在另一個方向上的尺寸還是無法調節,這時就可以采用qss樣式表來完成。

    qss樣式表跟HTML里面的css是一樣的,書寫格式代碼就能夠對組件的字體、文字顏色、邊框顏色、背景顏色、寬高等進行調節,非常方便。qss樣式可以在每個組件自己的樣式表里定義,也可以統一在窗口對象的樣式表里定義,推薦采用統一在窗口里定義,否則如果組件很多,那么在書寫和修改樣式表時需要挨個組件去找,效率太低。并且,統一在窗口里定義qss樣式表還有一個好處,可以針對某一類組件進行統一調整,例如針對按鈕類定義了qss樣式,那么所有按鈕都可以隨著變化。

    • qss樣式的基本格式如下:
    color: rgb(255, 0, 0);
    font-size:15px;
    background-color: rgb(85, 255, 127);
    border-color: rgb(255, 255, 0);
    width:50px;height:20px;
    • 針對所有元素的格式如下:
    *{color: rgb(255, 0, 0);font-size:15px;}
    • 針對某一類組件的格式如下:
    QPushButton{color: rgb(255, 0, 0);
    font-size:15px;
    background-color: rgb(85, 255, 127);
    border-color: rgb(255, 255, 0);
    width:50px;height:20px;}
    • 針對某一個組件的格式如下:
    #pushButton{height:30px;}
    • 針對組件的某種狀態的格式如下(如按鈕的鼠標懸浮狀態):
    QPushButton:hover {color: red;border:none;}
    • 為組件添加自定義屬性,針對自定義屬性相同的組件的qss樣式:
    *[myClass=top] {height:30px;}

    qss樣式演示如下:

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>


    三、按鈕組件部分

    (一)PushButton

    PushButton就是普通按鈕,它的屬性由四部分構成:QObject、QWidget、QAbstractButton、QPushButton,功能和作用如下:

    • QObject是對象屬性,在這里可以更改對象名稱,就是在程序中用來調用組件的名稱,這是通用屬性,每個組件都具備。
    • QWidget是組件屬性,也是所有組件的通用屬性,最常用的是geometry和sizePolicy。geometry是幾何形狀,用來更改組件位置和寬高,如果不使用布局這個屬性有效,使用布局之后這個屬性失效,即無法更改。sizePolicy是尺寸策略,窗口使用布局之后,這個屬性用來調節組件在橫向和縱向上的伸展策略。
    • QAbstractButton是抽象屬性,是按鈕類組件的父類,在這部分里可以更改按鈕標題、圖標、圖標大小、快捷鍵、是否允許選中和自動重復等屬性。
    • QPushButton是PushButton按鈕的獨有屬性,包括auto Default、default和flat三個屬性。

    1、重要屬性

    (1)shortcut

    shortcut是快捷鍵屬性,它的最強大之處在于允許將任意鍵定義為快捷鍵,支持幾個普通按鍵組合,例如隨意定義一個jkl快捷鍵,在窗口運行界面,正常速度連續按jkl就能夠觸發按鈕的事件。注意,在定義普通按鍵組合快捷鍵時,先在shortcut屬性右側框里點一下,然后快速按下需要定義的幾個按鍵,如果按的慢,系統檢測就結束了,后面再按的鍵就變成了另外一組快捷鍵。

    快捷鍵設置

    (2)checkable、checked和autoExclusive

    checkable是否可選擇屬性,位置在快捷鍵屬性下面,見上圖。如果checkable屬性為真,則按鈕被點擊后不會彈起(樣式會跟正常時不同),就像電源插排上的開關按鈕,按下后就會卡住,然后再按一下彈起。利用isChecked()方法可以檢測按鈕是否為選中狀態,這樣就可以實現一些特殊功能。

    checked屬性用來設置按鈕是否選中,需要與checkable配合使用。如果將這兩個屬性都設置為真,那么程序運行后按鈕就處于按壓狀態,點擊一下才恢復到正常按鈕狀態。在程序中可以使用setChecked(bool)方法來設置checked屬性。

    autoExclusive是自動排他屬性,如果同一父組件內的一組按鈕都設置了checkable屬性為真,那么當一個按鈕按下變成按壓狀態后,其它按鈕都會彈起,就像過去的錄音機按鍵一樣。并且,如果一個按鈕設置了自動排他屬性,那么點擊自己將無法彈起。

    (3)auto Repeat、auto RepeatDelay和auto RepeatInterval

    auto Repeat自動重復屬性,如果鼠標按住按鈕不抬起,那么按鈕會重復發射信號。在重復發射信號的過程中,有延遲和間隔時間,就是auto RepeatDelay和auto RepeatInterval屬性,單位為毫秒。

    (4)default和auto Default

    default和auto Default屬性都是將按鈕設置為默認按鈕,如果焦點在該按鈕上(鼠標點擊一次或者在代碼里設定焦點),那么一直按回車鍵就可以一直發射信號。目前沒發現二者在功能上有什么差別,只是default設置為真后,按鈕會出現邊框。

    (5)flat

    flat屬性為真則將按鈕設為平面按鈕,就是沒有邊框也沒有突出顯示的按鈕,沒有其它功能。

    2、常用方法

    常用方法就是PySide6里所謂的信號,介紹如下:

    • clicked():鼠標單擊信號,鼠標左鍵點擊時觸發,最常用信號
    • pressed():鼠標按壓信號,沒發現跟clicked有什么不同
    • released():鼠標釋放信號,鼠標左鍵點擊后抬起時觸發。利用這個信號處理事件,能夠起到一定的緩沖作用,如果鼠標按下不抬起,再將指針移到按鈕外,那么就不會觸發信號,有時可以避免一些誤操作。

    3、實例演示

    下面用一個實例演示一下以上介紹的內容。程序運行后,直接按回車鍵是沒有反應的,這時我們單擊第一個加長按鈕,文本編輯框里的文本會放大,現在一直按回車鍵文字就可以一直放大了。這是因為我們在Qt設計大師里將第一個加長的按鈕的auto Default屬性設置為真,然后將它的單擊信號關聯到文本編輯框的ZOOM in(放大顯示)槽上,不需要寫代碼。程序運行后,默認焦點不在這個按鈕上,因此按回車鍵沒有反應,用鼠標點擊一下后它就獲得了焦點,由于它是自動默認按鈕,所以點擊完畢后系統默認把焦點又交還給它,因此一直按回車鍵都有效。另外,在Qt設計大師里為這個按鈕設置了”JKL”組合快捷鍵,在程序運行后,按順序正常按“JKL”就可以觸發按鈕信號,看到文字放大顯示,但是快捷鍵并不能把焦點移動到這個按鈕上。

    用鼠標點擊“按住連續縮放”按鈕沒有反應,單擊“放大顯示”按鈕,然后再點擊“按住連續縮放”按鈕不放開,這時文字就一直放大;單擊“縮小顯示”按鈕,再點擊“按住連續縮放”按鈕不放開,這時文字就一直縮小。這是因為“按住連續縮放”按鈕的auto Repeat屬性設為真,按住后會連續發射信號;而“放大顯示”和“縮小顯示”這兩個按鈕的checkable和autoExclusive屬性為真,由于是排他性的,所以點擊這兩個按鈕時,它們的checked屬性是一起改變的,在代碼進行判斷處理就可以了。

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

    4、演示代碼

    from PySide6.QtWidgets import QApplication, QMainWindow
    from ui_test1 import Ui_Form
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            self.ui=Ui_Form()
            self.ui.setupUi(self)
    				# “按住連續縮放”按鈕單擊信號
            self.ui.pushButton.clicked.connect(self.auto_expanding)
    		
    		# 文字縮放自定義方法
        def auto_expanding(self):
            if self.ui.pushButton_4.isChecked():
                self.ui.plainTextEdit.zoomIn()
            elif self.ui.pushButton_2.isChecked():
                self.ui.plainTextEdit.zoomOut()
    
    
    if __name__=='__main__':
        app=QApplication([])
        window=MainWindow()
        window.show()
        app.exec()

    (二)Tool Button

    Tool Button是工具按鈕,非常靈活的按鈕組件,可以單獨或者混合顯示圖標和文本,還可以顯示箭頭(三角形符號)。既可以當作普通按鈕使用,又可以彈出菜單,彈出菜單又有立即彈出、長按彈出和點擊菜單區彈出三種方式。善加利用,是非常實用的工具按鈕。

    最典型的應用場景是Word、Excel等辦公軟件的工具欄按鈕,例如顏色按鈕,直接點擊按鈕是設置為當前顏色,點擊右側三角符號則打開顏色選擇器。還有瀏覽器的返回按鈕,即瀏覽器地址欄左側的 這個按鈕,既可以單擊返回上一頁,又可以長按顯示瀏覽的歷史記錄。

    1、重要屬性

    QAbstractButton類屬性不用再贅述,重點介紹QToolButton里面的幾個屬性。

    (1)popupMode

    菜單彈出方式,一共有三種方式:

    • DelayedPopup:延遲彈出,即需要用鼠標左鍵長按才能彈出菜單。選擇這種方式后,單擊工具按鈕則正常執行按鈕響應事件,長按鼠標則彈出功能菜單。
    • MenuButtonPopup:菜單按鈕彈出,即像菜單按鈕一樣彈出。選擇這種方式后,工具按鈕的右側會劃分出一個窄條區域,顯示一個向下的黑色三角形符號,這個區域就是菜單響應區,點擊按鈕前面部分可以正常執行按鈕事件,點擊菜單響應區則彈出菜單。
    • InstantPopup:直接彈出。選擇這種方式后,工具按鈕不能再完成單擊響應事件,而是直接彈出功能菜單。

    (2)toolButtonStyle

    工具按鈕樣式,共有五種類型:

    • ToolButtonIconOnly:僅顯示圖標
    • ToolButtonTextOnly:僅顯示文字
    • ToolButtonTextBesideIcon:文字在圖標旁邊
    • ToolButtonTextUnderIcon:文字在圖標下面
    • ToolButtonFollowStyle:跟隨qss樣式

    (3)autoRaise

    自動升起屬性,也就是設為真之后變成平面按鈕,否則按鈕帶有邊界,且有凹陷效果,所以把該屬性稱為自動升起。

    (4)arrowType

    箭頭類型,按鈕自動顯示黑色三角符號,會覆蓋圖標和文字,共有五種方式:

    • NoArrow:沒有箭頭,按鈕和文本會顯露
    • UpArrow:箭頭向上
    • DownArrow:箭頭向下
    • LeftArrow:箭頭向左
    • RightArrow:箭頭向右

    2、常用方法

    • clicked():單擊工具按鈕發射的信號
    • triggered():單擊菜單項發射的信號
    • setMenu():設置菜單。工具按鈕并沒有添加彈出菜單的地方,需要在主菜單欄里創建菜單項目,然后在程序代碼里使用setMenu()方法來指定菜單,在代碼里也可以把主菜單欄中的供工具按鈕使用的菜單項目隱藏。

    3、實例演示

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

    4、演示代碼

    from PySide6.QtWidgets import QApplication, QMainWindow
    from ui_test2 import Ui_MainWindow
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            self.ui=Ui_MainWindow()
            self.ui.setupUi(self)
    
            # 根據需要,可以將整個菜單欄隱藏
            # self.ui.menubar.setVisible(False)
    				# 將工具按鈕使用的菜單項隱藏
            self.ui.menuFile.menuAction().setVisible(False)
            self.ui.menuEdit.menuAction().setVisible(False)
            self.ui.menuRenew.menuAction().setVisible(False)
            self.ui.menuView.menuAction().setVisible(False)
    				# 為工具按鈕設置菜單
            self.ui.toolButton.setMenu(self.ui.menuFile)
            self.ui.toolButton_2.setMenu(self.ui.menuEdit)
            self.ui.toolButton_3.setMenu(self.ui.menuRenew)
            self.ui.toolButton_4.setMenu(self.ui.menuView)
    
    
    if __name__=='__main__':
        app=QApplication([])
        window=MainWindow()
        window.show()
        app.exec()

    (三)Radio Button

    Radio Button是單選按鈕,具有排他性,成組使用。特別要注意一點,一組單選按鈕必須要放置在一個容器類組件中,也就是說一組單選按鈕必須具有同一個父類(不能是主窗口),否則單選按鈕的排他性就會出現問題,放置在不同容器內的單選按鈕互不影響。

    1、重要屬性

    Radio Button沒有自己獨特的屬性,都是繼承屬性。在Qt設計大師里,除了把一個單選按鈕設置成默認選擇狀態,幾乎不需要設置任何屬性。組件尺寸和位置基本都用鼠標拖拉的方式設定,可以在屬性里進行微調。

    • checkable:是否允許選擇
    • checked:是否被選擇

    2、常用方法

    • clicked():單選按鈕單擊信號

    3、創建按鈕組

    如果圖形界面里有很多單選按鈕,那么在代碼里就會定義對應數量的槽函數,勢必會增加代碼量以及不方便閱讀。為了避免這種情況,可以為同組的單選按鈕創建一個按鈕組,在程序代碼里只需要將按鈕組的clicked信號連接到一個自定義槽函數就可以了。在自定義槽函數里,通過檢測id號來確定哪個單選按鈕被單擊了。

    (1)在Qt設計大師里創建按鈕組

    在Qt設計大師里將同組單選按鈕全部選中,然后依次點按鼠標右鍵→Assign to button group→New button group,這樣就為這一組單選按鈕創建了按鈕組,每個單選按鈕都有一個系統自動分配的id號,可以在代碼里使用按鈕組的checkedId()方法獲取。

    (2)在程序代碼里創建按鈕組

    這種方式相對比較費事,需要事先導入QButtonGroup類,然后創建按鈕組實例對象,把同組的單選按鈕利用addButton()方法加入到一個按鈕組里,并定義每個單選按鈕的id號。如果一組的單選按鈕很多,可以將同組的單選按鈕以序列形式命名,如radioButton_1、radioButton_2等等,然后用循環的方法向按鈕組里添加單選按鈕。

    下面的實例就是采用在代碼里創建按鈕組方式,剛開始在網上查閱相關資料時,都說要創建按鈕組,就是沒人介紹如何在Qt設計大師里創建。我就以為按鈕組是一個組件,翻遍了組件區還是沒找到,無奈就只能寫代碼創建了。后來在Qt設計大師里無意中按了一下右鍵,才發現了這個無比淺顯又折磨人的奧秘!其實,在PySide6里面,像這種不大不小的坑實在是無計其數,或許還是自己學習和掌握的不到位吧!

    4、實例演示

    本例實現利用單選按鈕控制一個Label組件里圖片的對齊方式,雖然單選框在設計時很簡單,但是實際在代碼里操作時需要用到很多技巧。實例里動態設置Label組件的圖片對齊方式也是一個技巧,感覺挺繁瑣,還需要使用QtCore模塊的Qt類進行設置。

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

    5、演示代碼

    from PySide6 import QtGui
    from PySide6.QtWidgets import QApplication, QMainWindow, QButtonGroup
    from PySide6.QtCore import Qt
    from ui_radio import Ui_Form
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            self.ui=Ui_Form()
            self.ui.setupUi(self)
    
            # 如果一組的Radio Button過多,可以創建一個按鈕組對象來統一管理,這樣只需要定義一個槽函數
            self.btn_group=QButtonGroup(self)  # 創建按鈕組對象
            # 利用循環將單選按鈕radioButton_1到radioButton_9加入到按鈕組
            for i in range(1, 10):
                widget=f'self.btn_group.addButton(self.ui.radioButton_{i},i)'
                eval(widget)
            # 把按鈕組的按鈕單擊信號關聯到自定義槽函數
            self.btn_group.buttonClicked.connect(self.rbtnClicked)
    
            # 未使用按鈕組管理的單選按鈕的單擊信號處理方式,每個按鈕都需要定義一個槽函數
            self.ui.radioDisplay.clicked.connect(self.displayImage)
            self.ui.radioNodisplay.clicked.connect(self.nodisplayImage)
    
        # 單選按鈕組單擊槽函數
        def rbtnClicked(self):
            self.flag=self.btn_group.checkedId()
    
            # 自動計算顯示位置坐標
            if self.flag <=3:
                h=self.flag - 1
                v=0
            elif 4 <=self.flag <=6:
                h=self.flag - 4
                v=1
            else:
                h=self.flag - 7
                v=2
            # 根據上面確定的位置坐標,確定橫向和縱向對齊方式
            h_align=['Qt.AlignLeft', 'Qt.AlignHCenter', 'Qt.AlignRight']
            v_align=['Qt.AlignTop', 'Qt.AlignVCenter', 'Qt.AlignBottom']
            align=f'{h_align[h]} | {v_align[v]}'
            self.ui.label.setAlignment(eval(align))
    
        # 顯示圖片單選按鈕被單擊槽函數
        def displayImage(self):
            self.ui.label.setPixmap(QtGui.QPixmap(r'resfile\open.png'))
    
        # 不顯示圖片單選按鈕被單擊槽函數
        def nodisplayImage(self):
            self.ui.label.setPixmap(QtGui.QPixmap())
    
    
    if __name__=='__main__':
        app=QApplication([])
        window=MainWindow()
        window.show()
        app.exec()

    (四)CheckBox

    CheckBox是復選框組件,可以獨立使用,也可以像單選按鈕那樣加到一個按鈕組里。如果加入了按鈕組,使用QButtonGroup的exclusive屬性來控制單選還是多選,exclusive屬性為真,則復選框就變成了單選按鈕功能。

    1、重要屬性

    CheckBox都是繼承屬性,唯一獨有屬性是tristate。

    • checkable:是否允許選中,為假時該復選框將不可選
    • tristate:三態屬性,該屬性為真時,則復選框有選中、未選中和半選中三種狀態,不常使用

    2、常用方法

    • stateChanged:狀態改變觸發信號

    3、實例演示

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

    4、演示代碼

    from PySide6.QtGui import QFont
    from PySide6.QtWidgets import QApplication, QMainWindow
    from ui_checkBox import Ui_Form
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            self.ui=Ui_Form()
            self.ui.setupUi(self)
    
            # 創建一個自定義字體實例對象
            self.myfont=QFont()
            # 為字體對象設置默認字號和字體
            self.myfont.setPointSize(72)
            self.myfont.setFamily('微軟雅黑')
            # 用自定義字體對象設置文本編輯框的字體
            self.ui.plainTextEdit.setFont(self.myfont)
            # 復選框的狀態改變信號和槽
            self.ui.checkBox.stateChanged.connect(self.chk_Bold)
            self.ui.checkBox_2.stateChanged.connect(self.chk_italic)
            self.ui.checkBox_3.stateChanged.connect(self.chk_underline)
    
        # 字體加粗
        def chk_Bold(self):
            self.myfont.setBold(self.ui.checkBox.isChecked())
            self.ui.plainTextEdit.setFont(self.myfont)
    
        # 字體傾斜
        def chk_italic(self):
            self.myfont.setItalic(self.ui.checkBox_2.isChecked())
            self.ui.plainTextEdit.setFont(self.myfont)
    
        # 字體加下劃線
        def chk_underline(self):
            self.myfont.setUnderline(self.ui.checkBox_3.isChecked())
            self.ui.plainTextEdit.setFont(self.myfont)
    
    
    if __name__=='__main__':
        app=QApplication([])
        window=MainWindow()
        window.show()
        app.exec()

    (五)Command Link Button

    命令鏈接按鈕,外觀與平面按鈕相同,按鈕標題允許設置描述信息,描述信息以小字形式顯示在標題下方。功能與普通按鈕沒有區別,允許設置一組互斥按鈕。典型應用場景是Windows11操作系統的設置界面,如圖:

    PySide6的命令鏈接按鈕樣式如下:

    (六)Dialog Button Box

    對話框按鈕盒子,用于生成成套按鈕,感覺沒有什么實際意義。只有一個重要屬性standardButtons,里面包含所有對話框按鈕,通過點選自由搭配按鈕。


    四、容器組件部分

    容器組件用來承載其它組件,形成分組效果,也可以做成分頁面,對于窗口布局非常有用。在上一篇筆記里已經詳細介紹了Scroll Area、Tab Widget、Stacked widget這三個組件,在這里介紹一下其它容器組件。

    (一)Tool Box

    Tool Box是工具箱組件。顧名思義,可以放置常用工具,能夠分層疊放,不占空間,使用靈活。

    1、操作技巧

    (1)增加頁面

    在窗體的Tool Box組件上或者對象查看器的Tool Box對象上按右鍵,選擇彈出菜單中的Insert Page選項,就可以看到在當前頁之前和當前頁之后兩個選項,點擊就在相應位置插入一個新頁面。

    (2)刪除頁面

    把要刪除的頁面展開,即變為當前頁,然后在窗體的Tool Box組件上或者對象查看器的Tool Box對象上按右鍵,在彈出菜單上有Page 1 of 3(具體數字視實際情況)的菜單項,再選擇Delete Page即可刪除。這個菜單項就在插入頁面上面,就不再另行配圖了。

    2、重要屬性

    工具箱的每個頁面標題必須在屬性里才能更改,屬性設置頁面見上圖。幾個重要屬性如下:

    • frameShape:框架樣式
    • currentltemText:當前頁標題文本
    • currentltemName:當前頁名稱
    • currentltemIcon:當前頁圖標

    3、實例演示

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>

    4、演示代碼

    import os
    from PySide6.QtWidgets import QApplication, QMainWindow
    from ui_toolbox import Ui_Form
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            self.ui=Ui_Form()
            self.ui.setupUi(self)
            self.ui.pushButton_8.clicked.connect(self.notepad)
            self.ui.pushButton_9.clicked.connect(self.calc)
    
        def notepad(self):
            os.system('notepad')
    
        def calc(self):
            os.system('calc')
    
    
    if __name__=='__main__':
        app=QApplication([])
        window=MainWindow()
        window.show()
        app.exec()

    (二)Dock Widget

    Dock Widget是停靠組件,本身又是容器組件,可以在窗口上下左右四個邊進行拖拽停靠。雙擊標題欄或者點擊浮動窗口按鈕,就可以從工具欄形式變成浮動窗口,點擊Dock Widge的關閉按鈕可以隱藏該組件,還可以利用它的show()和hide()方法進行顯示和隱藏。

    【注意】使用Dock Widget組件,創建的窗體必須是MainWindow,這樣Dock組件才能夠實現停靠和浮動功能。

    1、重要屬性

    Dock Widget的重要屬性都在Features(特征)里,內容如下:

    • floating:正在浮動屬性,設置為真則組件變成浮動狀態(浮動窗口),默認是假
    • DockWidgetClosable:停靠組件是否允許關閉,默認是真,如果設為假則組件上不顯示關閉按鈕,不能關閉
    • DockWidgetMovable:停靠組件是否允許移動,默認是真,如果設為假則組件不能拖動
    • DockWidgetFloatable:停靠組件是否允許浮動,默認是真,如果設為假則組件上不顯示浮動按鈕,不能浮動
    • DockWidgetVerticalTitleBar:縱向標題欄,默認是假
    • DockWidgetFeatureMask:特征掩飾,跟縱向標題欄屬性是聯動的,也是設置縱向標題欄
    • NoDockWidgetFeatures:沒有停靠組件特征,組件上不顯示浮動和關閉按鈕,組件不能拖動和關閉,不能移動

    2、常用方法

    • show():顯示組件
    • hide():隱藏組件
    • setFlating():設置浮動屬性
    • setFeatures():設置特征,即設置上面介紹的那些屬性

    3、實例演示

    本例是在Qt設計師里制作了一個簡易的記事本界面,用Dock Widget組件做了一個工具欄,菜單里有兩項:顯示和隱藏Dock Widget組件。界面設計好之后,直接在Qt設計師里將功能按鈕的clicked()信號與文本編輯框的相應預設槽函數進行了關聯,不需要到主程序里寫代碼,直接在Qt設計師里就可以實現全部功能。演示如下:

    <script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>


    未完,待續……

    DevExpress提供了一個比較強大的圖形繪制工具,可以用于繪制各種圖形,如流程圖、組織機構圖等等,本篇隨筆介紹XtraDiagram.DiagramControl的使用,以及利用代碼對其屬性進行控制,以及利用圖形模具的自定義操作,實現一些簡單流程圖形的繪制和處理。

    DiagramControl是類似Visio的繪圖控件,以前我2006年的就接觸使用Visio的二次開發,當時開始還是利用VB6 + VIsio2003進行二次開發的,后來把它改良為C# + Visio進行二次開發,DiagramControl的對象模型很類似Visio的相關對象模型,如對于工具欄的形狀,稱之為模具(Stencil),Visio也是稱之為Stencil, DiagramControl里面的很多接口名稱依舊采用Stencil進行命名,因此估計也是借鑒了很多Visio的對象設計知識,如果您對Visio二次開發感興趣,可以參考我的隨筆文章《Visio二次開發》,里面有很多相關的內容。

    而如果想了解這個控件的相關知識和使用,參考官網的案例和說明應該是比較好的教程(https://docs.devexpress.com/WindowsForms/118290/controls-and-libraries/diagrams/getting-started )。

    1、DiagramControl控件的使用

    DiagramControl是一個界面控件,類似Visio SDK里面的DrawingControl的存在,可以通過它進行圖形的繪制,各種窗口的顯示和隱藏,以及跟蹤各種事件的處理。

    DiagramControl控件拖動到窗體中后,會自動增加一些屬性窗口,上排的繪圖工具中的按鈕是我添加的,用來測試該控件的一些屬性的控制。

    1)屬性窗口的顯示和隱藏(折疊)

    這個通過控制diagramControl1.OptionsView.PropertiesPanelVisibility 屬性就可以實現對這個屬性窗口的控制了。

    里面顯示一些系統位置和內容信息,以及一些自定義信息的窗口,后面我會介紹如何自定義處理這些模具的屬性。

    通過按鈕處理的代碼,我們可以實現對這個窗口的顯示或者隱藏處理。

    //切換屬性窗口的顯示或關閉
    var status=diagramControl1.OptionsView.PropertiesPanelVisibility;
    diagramControl1.OptionsView.PropertiesPanelVisibility=(status==PropertiesPanelVisibility.Visible ? PropertiesPanelVisibility.Collapsed : PropertiesPanelVisibility.Visible);

    2)模具形狀窗口的顯示或隱藏

    模具形狀的窗口,它是放在一個面板里面,我們只需要通過控制該面板的顯示或者隱藏就可以了,如下代碼所示。

    //切換模具形狀窗口的顯示或關閉
    var status=diagramToolboxDockPanel1.Visibility;
    diagramToolboxDockPanel1.Visibility=(status==DevExpress.XtraBars.Docking.DockVisibility.Visible ? DevExpress.XtraBars.Docking.DockVisibility.Hidden : DevExpress.XtraBars.Docking.DockVisibility.Visible);

    或者通過控件的Toolbar屬性進行控制,一樣的效果。

    //切換模具形狀窗口的顯示或關閉
    var status=this.diagramControl1.OptionsView.ToolboxVisibility;
    this.diagramControl1.OptionsView.ToolboxVisibility=status==ToolboxVisibility.Closed ? ToolboxVisibility.Full : ToolboxVisibility.Closed;

    3)放大縮小窗口的顯示或者隱藏

    同樣我們也可以控制放大縮小窗口的顯示或者隱藏,它也是圖形繪制的一個常見的窗口。我們只需要判斷或者設置diagramControl1.OptionsView.ShowPanAndZoomPanel 屬性就可以了,如下代碼所示。

    //切換放大縮小窗口的顯示或關閉
    var status=diagramControl1.OptionsView.ShowPanAndZoomPanel;
    diagramControl1.OptionsView.ShowPanAndZoomPanel=!status;

    4)其他屬性的處理

    另外,我們可以通過控制一些屬性,實現對標尺、網格、只讀視圖等模式進行控制。

    //是否顯示標尺
    this.diagramControl1.OptionsView.ShowRulers=this.chkRuler.Checked;
    //是否顯示網格
    this.diagramControl1.OptionsView.ShowGrid=this.chkGrid.Checked;
    //是否只讀視圖
    this.diagramControl1.OptionsProtection.IsReadOnly=this.chkReadOnly.Checked;

    2、繪圖的處理事件

    在繪制圖形的時候,一般來說我們可能需要切換點選模式或者連接線模式,因此可以通過它的屬性ActiveTool進行設置。在點選模式下,可以對圖形進行拖動、放大縮小、旋轉等處理,連接線模式下,則會加亮連接點,便于自動繪制連接線。

    private void btnPointerMode_Click(object sender, EventArgs e)
    {
        diagramControl1.OptionsBehavior.ActiveTool=diagramControl1.OptionsBehavior.PointerTool;
    }
    
    private void btnConnectorMode_Click(object sender, EventArgs e)
    {
        diagramControl1.OptionsBehavior.ActiveTool=diagramControl1.OptionsBehavior.ConnectorTool;
    }

    當然,我們也可以通過對鼠標行為的分析來進行控制,如果鼠標懸停或者放置在圖形上,就自動切換模式為連接線模式,否則為點選模式,那么只需要判斷鼠標的移動行為即可自動處理,如下代碼所示。

            /// <summary>
            /// 實現對圖形自動切換到連接點模式
            /// </summary>
            private void diagramControl1_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.Button==MouseButtons.Left)
                    return;
    
                DiagramItem item=diagramControl1.CalcHitItem(e.Location);
                if (item==null)
                {
                    diagramControl1.OptionsBehavior.ActiveTool=diagramControl1.OptionsBehavior.PointerTool;
                    return;
                }
                else if (item is DiagramConnector)
                {
                    diagramControl1.OptionsBehavior.ActiveTool=diagramControl1.OptionsBehavior.ConnectorTool;
                    return;
                }
    
                Rect itemBounds=new Rect(new Point(item.Position.X, item.Position.Y), new Size(item.Width, item.Height));
                PointFloat documentPoint=diagramControl1.PointToDocument(new PointFloat(e.Location));
                DiagramHitInfo[] hitInfo=diagramControl1.CalcHitInfo(documentPoint);
                if (itemBounds.Contains(new Point(documentPoint.X, documentPoint.Y)))
                {
                    itemBounds.Inflate(-5, -5);
                    if (!itemBounds.Contains(new Point(documentPoint.X, documentPoint.Y)))
                    {
                        diagramControl1.OptionsBehavior.ActiveTool=diagramControl1.OptionsBehavior.ConnectorTool;
                        return;
                    }
                }
                diagramControl1.OptionsBehavior.ActiveTool=diagramControl1.OptionsBehavior.PointerTool;
            }

    另外圖形的保存xml、PNG、PDF處理和加載代碼如下所示。

    /// <summary>
    /// 保存XML和圖片文件
    /// </summary>
    private void SaveXml()
    {
        var xml=Path.Combine(Application.StartupPath, "MyFlowShapes.xml");
        diagramControl1.SaveDocument(xml);
    
        var pngFile=Path.Combine(Application.StartupPath, "MyFlowShapes.png");
        diagramControl1.ExportDiagram(pngFile);
    }
    private void btnLoadXml_Click(object sender, EventArgs e)
    {
        var xml=FileDialogHelper.OpenXml();
        if(!string.IsNullOrEmpty(xml))
        {
            diagramControl1.LoadDocument(xml);
        }
    }

    最終案例的效果如下所示。

    3、注冊自定義的形狀

    在實際的圖形繪制開發中,我們可以需要創建一些指定的形狀模具,那么我們弄好后一般可以存放在XML中,然后進行加載到控件上來,如下代碼就是注冊自定義的形狀的處理。

    /// <summary>
    /// 注冊自定義的形狀。
    /// 自定義圖形是以XML文件形式進行保存,圖形需要按照規定XML格式進行繪制
    /// </summary>
    private void LoadShapes2()
    {
        var projectName="SmallExampleDemo.Examples.XtraDiagram";
        using (var stream=Assembly.GetExecutingAssembly().GetManifestResourceStream(projectName + ".CustomContainers.xml"))
        {
            var stencil=DiagramStencil.Create(MyStencilId, MyStencilName, stream, shapeName=> shapeName);
            DiagramToolboxRegistrator.RegisterStencil(stencil);
        }
        diagramControl1.SelectedStencils=new StencilCollection(MyStencilId);//(MyStencilId, BasicShapes.StencilId);
    }

    我們只需要設置選中的圖形就可以了,其他有需要的可以從More Shapes中選擇即可。

    我們如果需要在屬性窗口中顯示自定義的屬性,那么我們需要一些代碼開發才能實現。

    我們首先需要繼承一個DiagramShape的子類,然后實現自己自定義的屬性定義,如下代碼所示。

    對自定義屬性的處理,需要在事件中實現

    diagramControl1.CustomGetEditableItemProperties +=DiagramControl_CustomGetEditableItemProperties;

    通過對它進行判斷可以實現自定義屬性的顯示處理

    void DiagramControl_CustomGetEditableItemProperties(object sender, DiagramCustomGetEditableItemPropertiesEventArgs e)
    {
        if (e.Item is DiagramShapeEx)
        {
            e.Properties.Add(TypeDescriptor.GetProperties(typeof(DiagramShapeEx))["Status"]);
            e.Properties.Add(TypeDescriptor.GetProperties(typeof(DiagramShapeEx))["TypeName"]);
        }
    }

    然后我們可以注冊創建自己的模具形狀集合,如下代碼所示。

    /// <summary>
    /// 創建自定義的模具
    /// </summary>
    /// <returns></returns>
    DiagramStencil CreateCustomDrawShapesStencil()
    {
        var stencilId="CustomedFlowShape";
        var stencilName="流程圖";
        var shapeSizeSmall=new Size(100, 37.5);
        var shapeSize=new Size(100, 75);
    
        DiagramControl.ItemTypeRegistrator.Register(typeof(DiagramShapeEx));
        var stencil=new DiagramStencil(stencilId, stencilName);            
    
        //流程類型
        stencil.RegisterTool(new FactoryItemTool("StartEnd", ()=> "流程開始", diagram=> { 
            var shape=new DiagramShapeEx(BasicFlowchartShapes.StartEnd, "流程開始");
            shape.Appearance.BackColor=Color.Red;
            return shape;
        }, shapeSizeSmall));
        stencil.RegisterTool(new FactoryItemTool("Decision", ()=> "流程條件", diagram=> { 
            var shape=new DiagramShapeEx(BasicFlowchartShapes.Decision, "流程條件");
            shape.Appearance.BackColor=Color.FromArgb(199, 115, 1);//Color.Red;
            return shape;
        }, shapeSize));

    這兩個流程開始,流程條件,我們直接是從 BasicFlowchartShapes 集合中借用過來,構建自己的自定義對象的,默認創建的對象是方形的。

    如果我們需要動態構建其他自定義類型,我們可以指定它的顏色等樣式,從而構建不同類型的圖形。

    //循環添加相關流程節點
    var procNames=new List<string> { "審批", "歸檔", "閱辦", "會簽", "領導批示分閱"};
    //定義幾個初始化顏色順序
    var colors=new List<Color> { Color.DeepSkyBlue, Color.ForestGreen, Color.Violet, Color.Yellow, Color.Blue, Color.Orange, Color.Indigo, Color.Purple, Color.Black, Color.Brown, Color.Pink };
    int i=0;
    foreach (string name in procNames)
    {
        var shapeId=string.Format("Process_{0}", i++);
    
        stencil.RegisterTool(new FactoryItemTool(shapeId, ()=> name, diagram=>
        {
            var shape=new DiagramShapeEx(name, Status.Inactive);
            var index=procNames.IndexOf(name);
            var color=colors[index % 10];//Color.Red;
            var fontColor=(color==Color.Yellow) ? Color.Black : Color.White;
    
            //沒什么作用
            //shape.ThemeStyleId=GetStyle(index); //從Accent1樣式開始  DiagramShapeStyleId.Styles[index];//                  
            shape.Appearance.BackColor=color;
            shape.Appearance.BorderSize=3;
            shape.Appearance.Font=new Font("宋體", 12f, FontStyle.Bold);
            shape.Appearance.ForeColor=fontColor;
            return shape;
        }, shapeSize));
    }

    這樣就有不同顏色的圖形對象了。

    根據這些我們就可以繪制出自己的各種流程圖了,并且也可以根據數據庫的信息,進行動態繪制展示。


    文章來自https://www.cnblogs.com/wuhuacong/p/16404257.html

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有