3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python【PyQt5】的环境搭建和使用(全网最全)其一

發布時間:2024/3/12 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python【PyQt5】的环境搭建和使用(全网最全)其一 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

什么是pyQT

為什么要開發桌面應用

要講些什么

搭建PyQt5開發環境

?參見CSDN:pyQt5環境的搭建_Hi~晴天大圣的博客-CSDN博客_pyqt5環境搭建

1 Python

2 PyQt模塊插件

??? PyQt5中插件的作用:??? QtDesigner——通過Qt語言進行UI設計(支持拖拽式的UI設計)??? PyUIC——主要用來將QtDesigner代碼轉化成Python代碼??? Pyrcc—— 將圖片、數據文件資源打包成py文件

3 PyCharm

添加到環境變量:環境變量目錄

問題:在安裝第三方庫時出現報錯"These Packages Do Not Match The Hashes From The Requirements File."

python在虛擬解釋器環境中使用pip安裝第三方庫出現Requirement already satisfied錯誤

1到14課時后續學習后添加!

課時15 ? 開發第一個基于PyQt5的桌面應用

?課時16 ? 打開QtDesigner設計師工具

ctrl+R預覽

將.ui文件轉換為.py文件

方法一: python -m PyQt5.uic.pyuic demo.ui -o demo.py

方法二:

python文件夾//打開pyuic5程序 -o 文件名稱 直接生成demo.py

推薦 方式三

課時17 ? 在QtDesigner中使用布局

?課時18 ? 調用源文件:RunDemo.py調用demo.py文件

課時19 ? PyQt5中的瀏覽器控件-QtWebEngine

課時20 ? Edit 編輯伙伴 編輯Tab順序

課時21 ? 在Qt Designer中設置信號與插槽

?課時22 ?? 動作編輯器

?課時23 ? 主窗口類型

QMainWindow:可以包含菜單欄,工具欄,狀態欄和標題欄

QDialog:是對話窗口的基類。沒有菜單欄,工具欄,狀態欄

QWidget:不確定窗口的用途,就使用QWidget

課時24 ? 接下來用代碼寫一個程序Demo

課時25 ? 讓程序居中窗口

課時26??? 退出應用程序

?課時27 ? 獲取屏幕坐標系

課時28?? 設置窗口和應用程序圖標

課時29 顯示控件提示信息

課時30 QLabel控件的基本用法

課時31 QLabel與伙伴關系

課時32 QLineEdit控件與回顯模式

課時33 限制QLineEdi t控件的輸入

校驗器

課時34 使用掩碼限制QLineEdit控件的輸入

課時35 QLineEdit綜合案例

課時36 使用QTextEdit控件輸入多行文本

課時37 按鈕控件(QpushButton)

單選按鈕控件QRatioButton

課時39 復選框控件QCheckBox?編輯?編輯

?課時40 下拉列表控件QComboBox

?課時41 滑塊控件QSlider

課時42 計數器控件QSpinBox

課時43 使用 QDialog顯示通用對話框

課時44 顯示不同類型的消息對話框

課時45 輸入對話框QInputDialog

課時46? 字體對話框QFontDialog

?課時47 顏色對話框QColorDialog

課時48 文件對話框QFileDialog

課時49 在窗口上繪制文本

課時50 用像素點繪制正弦曲線

?編輯

課時51 繪制不同類型的直線

課時52 繪制各種圖形

?課時53 用畫刷填充圖形區域

?課時54 讓控件支持拖拽動作

?課時55 使用剪貼板

課時56 日歷控件

課時57 設置不同風格的日期和時間

?課時58 日期和時間控件的高級操作

?課時59 創建和使用菜單

課時60 創建和使用工具欄

課時61 創建和使用狀態欄?

用于顯示狀態信息,一般在窗口的最下方顯示

課時62 使用打印機

課時63 顯示打印對話框

?課時64 顯示二維表數據

?課時65 顯示列數據

課時66? 擴展的列表控件

課時67 擴展的表格控件

課時68 在單元格中放置控件

課時69 在表格中搜索Cell和行定位

課時70 設置單元格字體和顏色

課時71 按表格的某一列排序

課時71 設置單元格的文本對齊方式

課時73 合并單元格

課時74 設置單元格的尺寸

課時75 在單元格中實現圖文混排的效果

課時76 改變單元格中圖片的尺寸

課時77 在表格中顯示上下文菜單

?課時78 樹控件(QTreeWidget)的基本用法

?編輯

課時79 為樹節點添加響應事件

?課時 80 增加,修改和刪除樹控件的節點

課時81 QTreeView控件與系統定制模式

課時82 選項卡控件(QTabWidget)

?課時83 堆棧窗口控件(QStackedWidget)

課時84 停靠控件(QDockWidget)

課時85 容納多文檔的窗口

課時86 滾動條控件(QScrollBar)

課時87 動態顯示當前時間(QTimer)

?課時88 讓窗口定時關閉

課時89 使用線程類(QThread)編寫計數器

課時90 用Web瀏覽器控件(QWebEngineView)顯示網頁

課時91 裝載本地Web頁面

課時91 顯示嵌入Web頁面

?課時93 PyQt5調用JavaScript代碼,并返回值

課時94 JavaScript調用PyhtonAPI計算階乘

課時95 絕對布局

課時96 水平盒布局(QHBoxLayout)

課時97 設置控件的對齊方式

課時98? 垂直盒布局

課時99 設置布局的伸縮量

課時100 讓按鈕永遠在窗口的右下角

課時101 柵格布局:用循環方式實現計算器UI

?課時102 柵格布局:進行表單UI設計

課時103 表單布局

課時104 拖動控件之間的邊界(QSplitter)

課時105 信號與槽基礎

課時106 自定義信號實現對象之間的通信

課時107 可以傳遞多個參數的信號

課時108 為類添加多個信號(重載形式的信號)

課時109 信號與槽的N對N連接與斷開連接

課時110 為窗口添加信號

?課時111 多線程更新UI數據

課時112 信號與槽自動連接

課時113 用Lambda表達式為槽函數傳遞參數

?課時114 用partial對象為槽函數傳遞參數

課時115 override(覆蓋)槽函數

?課時116 多窗口交互(1):不使用信號與槽

課時117 多窗口交互(2):使用信號與槽

?課時118 設置窗口中控件的風格

?課時119 設置窗口樣式

?課時120 用代碼設置窗口的最大化和最小化

課時121 項目實戰:實現繪圖應用

課時122? QSS基礎

?課時123 使用QSS選擇器設置控件樣式

課時124 QSS子控件選擇器

課時125 使用QSS為標簽和按鈕添加背景圖

?課時126 裝載QSS文件

?課時127 三種設置背景色和背景圖片的方式

方式一 QSS?

?方式二 QPalette

方式三 直接繪制

課時127 實現不規則窗口(異形窗口)注意只對windowse系統有效果

?課時128 移動和關閉不規則窗口(異形窗口)

?課時129 實現異形窗口動畫效果?編輯

課時130 裝載gif動畫文件

課時131 縮放圖片

課時132 用動畫效果改變窗口的尺寸

課時133用動畫效果以不同速度移動窗口

?課時134 用PyInstaller打包PyQt5應用

課時135 操作SQLite數據庫

課時136 使用可視化的方式對SQLite數據庫進行增刪改查操作

課時137 分頁顯示數據

?課時138 使用PyQtGraph進行數據可視化


什么是pyQT

pyqt是一個用于創建GUI應用程序的跨平臺工具包,它將python與qt庫融為一體。也就是說,pyqt允許使用python語言調用qt庫中的API。這樣做的最大好處就是在保存了qt高運行效率的同時,大大提高開發效率。因為,使用python語言開發程序要比使用c++語言開發程序快的多。pyqt對qt做了完整的封裝,幾乎可以用pyqt做qt能做的任何事情。

??????? 由于目前最新的pyqt版本是5.11,所以習慣上稱呼為pyqt為pyqt5

為什么要開發桌面應用

???????

桌面應用,也可以成為GUI應用,在windows處于非常火爆的15年時間(1995到2010)里是非常火的,不過最近幾年web應用和移動應用搶了風頭。盡管web和移動應用看似成為現在的主流。但桌面應用目前仍然為很多類型應用的首選。移動應用由于屏幕太小,機器性能遠低于同時代的pc機,所以至少目前來看,在短時間內移動應用是無法取代pc應用的,而在pc瀏覽器上運行的web應用的主要優勢是不需要安裝的,只要有瀏覽器就可以運行。

??????? 但缺點也顯而易見,web應用在瀏覽器部分的邏輯代碼通常都是由于javascript語言編寫的,運行效率比較低,而且web應用是無法完全控制本機的硬件的,如攝像頭,藍牙設備,打印機,串口等,web應用在用戶體驗上也不如同時代的桌面應用,而web設備不擅長的事正好是桌面應用的強項,因此,在未來的幾十年,桌面應用仍然會占有非常重要的地位。

要講些什么

Qt Designer

pyQt5基本窗口控件(QMainWindow,Qwidget,Qlabel,QLineEdit,菜單,工具欄等)

pyQt5高級控件(QTableView,QListView,容器,多線程等)

pyQt5布局管理(QBoxLayout,QGridLayout,QFormLayout,嵌套布局等)

pyQt5信號與槽(事件處理,數據傳遞等)

pyQt5圖形與特效(定制窗口風格,繪圖,QSS與UI美化,不規則窗口,設置樣式等)

pyQt5擴展應用(制作pyQt5安裝程序,數據處理,第三方繪圖庫在pyQt5中的應用,UI自動化測試等)

搭建PyQt5開發環境

?參見CSDN:pyQt5環境的搭建_Hi~晴天大圣的博客-CSDN博客_pyqt5環境搭建

1 Python

2 PyQt模塊插件

??? PyQt5中插件的作用:
??? QtDesigner——通過Qt語言進行UI設計(支持拖拽式的UI設計)
??? PyUIC——主要用來將QtDesigner代碼轉化成Python代碼
??? Pyrcc—— 將圖片、數據文件資源打包成py文件

3 PyCharm

因為這里存在網絡慢的原因 我使用了手機數據分享給電腦的方式下載的PyQt5

?下載過程有些慢 只能耐性等待...

添加到環境變量:環境變量目錄

?C:\Users\xiangbin\AppData\Local\Programs\Python\Python39\Lib\site-packages\PyQt5\Qt5\plugins

問題:在安裝第三方庫時出現報錯"These Packages Do Not Match The Hashes From The Requirements File."

原因:通常是因為網速問題導致的下載錯誤,導致對應的哈希值不匹配。

解決方法:需要在pip時,添加"–upgrade"參數即可。通常這時下載還會報錯timeout,因此多加一個"–default-timeout=100000" 更為保險(timeout的賦值可以視情況變化)。

pip install --upgrade --default-timeout=100000 packagename -i http://pypi.douban.com/simple

當使用conda安裝完pyqt5后,在pycharm中配置額外模塊時發現找不到designer.exe文件
經過查資料發現,是因為我安裝pyqt5時,里面不帶這個pyqt5-tools文件,所以在使用conda下的pip下載pyqt5-tools即可(conda是下載不了pyqt5-tools的)
解決方法,在命令行中輸入pip install PyQt5-tools -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com即可

python在虛擬解釋器環境中使用pip安裝第三方庫出現Requirement already satisfied錯誤

原因是:用項目自己創建的虛擬解釋器環境時,因為沒有配置系統環境變量,所以找不到要安裝的地址,不知道這個包要安裝到那個位置。
解決辦法,在安裝語句中加- -target,指定安裝的位置,用項目虛擬解釋器環境安裝的話,安裝位置為項目中的虛擬環境中,默認為:

pip install --target=項目路徑\項目名稱\venv\Lib\site-packages 要安裝的包名

例如:

pip install --target=C:\Users\xiangbin\AppData\Local\Programs\Python\Python39\Lib\site-packages ?PyQt5-tools

1到14課時后續學習后添加!

課時15 ? 開發第一個基于PyQt5的桌面應用

# @CSDN王家視頻教程圖書館 # @Time 2022/11/22 17:59import sysfrom PyQt5.QtWidgets import QApplication,QWidget''' 鑒于這兩種情況中__name__的值是不同的:當一個模塊被直接執行時,其__name__必然等于__main__;當一個模塊被引用時, 其__name__必然等于文件名(不含.py)。所以利用判斷__name__ == '__main__'的真假就可以將這兩種情況區分出來。 ''' if __name__ == '__main__':#創建QApplication類的實例app=QApplication(sys.argv)#創建一個窗口w = QWidget()#設置窗口的尺寸w.resize(300,150)#移動窗口w.move(300,300)#設置窗口的標題w.setWindowTitle('第一個基于pyqt的桌面程序')#顯示窗口w.show()#進入程序的主循環 并通過exit函數確保主循環安全結束sys.exit(app.exec_())

?課時16 ? 打開QtDesigner設計師工具

?或者

ctrl+R預覽

將.ui文件轉換為.py文件

方法一: python -m PyQt5.uic.pyuic demo.ui -o demo.py

生成完成 !demo.py

方法二:

python文件夾//打開pyuic5程序 -o 文件名稱 直接生成demo.py

推薦 方式三

?生成完成 !demo1.py

課時17 ? 在QtDesigner中使用布局

全選控件 右鍵 選擇布局 為水平布局

其他布局設置方式同理 因為第二擴展菜單截圖 截不到 這里請參考

?CTRL + R 預覽

?

?課時18 ? 調用源文件:RunDemo.py調用demo.py文件

課時19 ? PyQt5中的瀏覽器控件-QtWebEngine

?新版本的QtDesigner里是沒有WebView的,想要使用瀏覽器控件就需要自己安裝QtWebEngine。安裝之后也是沒有圖形界面的控件的,所以使用策略就是

用其他控件在圖形界面布局,然后生成python代碼之后在代碼中修改

修改代碼參考如下

from PyQt5 import QtWebEngineWidgets

self.webView = QtWebEngineWidgets.QWebEngineView(self.centralwidget)
self.webView.setGeometry(QtCore.QRect(300, 300, 451, 241))
self.webView.setUrl(QtCore.QUrl("https://markwannafly.blog.csdn.net/"))
self.webView.setObjectName("webView")

或者:如何在Python QT Designer中插入Web瀏覽器

課時20 ? Edit 編輯伙伴 編輯Tab順序

課時21 ? 在Qt Designer中設置信號與插槽

信號(signal)

是Qt的核心機制,也是PyQt的核心機制

信號:是由對象或者控件發射出去的消息

按鈕的單擊事件

當單擊按鈕時,按鈕就會向外部發送單擊消息,這些發送出去的信號需要一些代碼來攔截,這些代碼就是插槽上一個函數或者方法

一個信號可以和多個槽綁定,一個槽可以攔截多個信號

?課時22 ?? 動作編輯器

?課時23 ? 主窗口類型

有3種窗口

QMainWindow

QWidget

QDialog

QMainWindow:可以包含菜單欄,工具欄,狀態欄和標題欄

QDialog:是對話窗口的基類。沒有菜單欄,工具欄,狀態欄

QWidget:不確定窗口的用途,就使用QWidget

課時24 ? 接下來用代碼寫一個程序Demo

?這里分享一個在線icon制作的網站:Icon圖標在線制作工具

# @CSDN王家視頻教程圖書館 # @Time 2022/11/22 23:14 import sys from PyQt5.QtWidgets import QMainWindow,QApplication from PyQt5.QtGui import QIcon class FirstMainWin(QMainWindow):def __init__(self):super(FirstMainWin,self).__init__()#設置主窗口的標題self.setWindowTitle("第一個主窗口應用")#設置窗口的尺寸self.resize(400,300)self.status=self.statusBar()self.status.showMessage("只存在5秒的消息",5000)#只有本程序可以調用 防止其他程序調用本程序 if __name__ == '__main__':app=QApplication(sys.argv)app.setWindowIcon(QIcon('./and.png'))main=FirstMainWin()main.show()# 程序的主循環sys.exit(app.exec_())

課時25 ? 讓程序居中窗口

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 11:38 # 龍文學python # @Time 2022/11/22 23:14 import sys from PyQt5.QtWidgets import QDesktopWidget,QMainWindow,QApplication from PyQt5.QtGui import QIcon class CenterForm(QMainWindow):def __init__(self):super(CenterForm,self).__init__()#設置主窗口的標題self.setWindowTitle("讓主窗口居中")#設置窗口的尺寸self.resize(400,300)def center(self):# 獲取屏幕坐標系screen=QDesktopWidget.screenGeometry()#獲取窗口坐標系size=self.geometry()newLeft=(screen.width()-size.width())/2newTop=(screen.height()-size.height())/2self.move(newLeft,newTop)#只有本程序可以調用 防止其他程序調用本程序 if __name__ == '__main__':app=QApplication(sys.argv)app.setWindowIcon(QIcon('./and.png'))main=CenterForm()main.show()# 程序的主循環sys.exit(app.exec_())

課時26??? 退出應用程序

?課時27 ? 獲取屏幕坐標系

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 12:11 import sys from PyQt5.QtWidgets import QDesktopWidget,QHBoxLayout,QMainWindow,QApplication,QPushButton,QWidgetdef onClick_Button():print("第一種方式 窗口坐標系 包含標題欄")print("widget.x()=%d" % widget.x())print("widget.y()=%d" % widget.y())print("widget.width()=%d" % widget.width())print("widget.height()=%d" % widget.height())print("第二種方式 窗口坐標系 不包含標題欄 只有工作區")print("widget.geometry().x()=%d" % widget.geometry().x())print("widget.geometry().y()=%d" % widget.geometry().y())print("widget.geometry().width()=%d" % widget.geometry().width())print("widget.geometry().height()=%d" % widget.geometry().height())print("第三種方式 暫時未理解全面")print("widget.frameGeometry().x()=%d" % widget.frameGeometry().x())print("widget.frameGeometry().y()=%d" % widget.frameGeometry().y())print("widget.frameGeometry().width()=%d" % widget.frameGeometry().width())print("widget.frameGeometry().height()=%d" % widget.frameGeometry().height()) app=QApplication(sys.argv)widget=QWidget() btn=QPushButton(widget) btn.setText('按鈕')btn.clicked.connect(onClick_Button)btn.move(55,55)widget.resize(300,240)#設置工作區的尺寸widget.move(250,200)widget.setWindowTitle('屏幕坐標系')widget.show()sys.exit(app.exec_())

課時28?? 設置窗口和應用程序圖標

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 12:40 ''' 窗口的setWindowIcon方法用于設置窗口的圖標,只在windows中可用 QAplication中的setQindowIcon的方法用于設置主窗口的圖標和應用程序圖標,但調用了窗口的setWindowIcon方法 QAplication中的setQindowIcon的方法就只能用于設置應用程序圖標了 ''' import sys from PyQt5.QtWidgets import QDesktopWidget,QMainWindow,QApplication from PyQt5.QtGui import QIcon class IconFrom(QMainWindow):def __init__(self):super(IconFrom,self).__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 250, 250)#設置主窗口的標題self.setWindowTitle("設置窗口圖標")#設置窗口圖標self.setWindowIcon(QIcon('./and.png'))#只有本程序可以調用 防止其他程序調用本程序 if __name__ == '__main__':app=QApplication(sys.argv)#app.setWindowIcon(QIcon('./and.png'))main=IconFrom()main.show()# 程序的主循環sys.exit(app.exec_())

課時29 顯示控件提示信息

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 12:51 #顯示控件提示信息 import sys from PyQt5.QtWidgets import QDesktopWidget,QHBoxLayout,QMainWindow,QApplication,QToolTip,QPushButton,QWidget from PyQt5.QtGui import QIcon from PyQt5.QtGui import QFontclass TooltipForm(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):QToolTip.setFont(QFont("SansSerif",12))self.setToolTip('今天是<b>星期五<b>')self.setGeometry(300,300,200,200)self.setWindowTitle('設置控件提示信息')# 添加Buttonself.button1 = QPushButton("我的按鈕")self.button1.setToolTip('這是一個按鈕ok')layout = QHBoxLayout()layout.addWidget(self.button1)mainFrame = QWidget()mainFrame.setLayout(layout)self.setCentralWidget(mainFrame)#按鈕點擊事件方法(自定義的槽)def onClick_Button(self):sender=self.sender()print(sender.text()+'按鈕被按下')app=QApplication.instance()#退出應用程序app.quit()#只有本程序可以調用 防止其他程序調用本程序 if __name__ == '__main__':app=QApplication(sys.argv)app.setWindowIcon(QIcon('./and.png'))main=TooltipForm()main.show()# 程序的主循環sys.exit(app.exec_())

課時30 QLabel控件的基本用法

QLabel控件

setAlignment():設置文本的對齊方式

setIndent():設置文本縮進

text():獲取文本內容

selectedText():返回所選擇的字符

setWordWrap():設置是否允許換行

QLabel常用的信號(事件):

1.當鼠標滑過QLabel控件時出發:linkHovered

2.當鼠標單擊QLabel控件時觸發:linkActivated

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 12:51 import sys from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout # 垂直布局 from PyQt5.QtGui import QPalette # 調色版 from PyQt5.QtGui import QPixmap # 展示圖片 from PyQt5.QtCore import Qt # 有一些常量在這里面,eg:blueclass QLabelDdemo(QWidget):def __init__(self):super(QLabelDdemo, self).__init__()self.initUI()def initUI(self):label1 = QLabel(self)label2 = QLabel(self)label3 = QLabel(self)label4 = QLabel(self)label1.setText('<font color=yellow>這是一個文本標簽</font>')label1.setAutoFillBackground(True) # 自動填充背景palette = QPalette()# 設置背景色palette.setColor(QPalette.Window, Qt.blue)#設置背景色# 對label1設置調色版label1.setPalette(palette)# 跳轉到一個網頁或者觸發一個點擊事件label2.setText("<a href='#'>歡迎使用Python GUI程序</a>")# 文本居中label3.setAlignment(Qt.AlignCenter)# 提示信息label3.setToolTip('這是一個圖片標簽')label3.setPixmap(QPixmap('./and.png'))# 如果設為True,用瀏覽器打開網頁,如果設為False,調用槽函數label4.setOpenExternalLinks(True)label4.setText("<a href='www.baidu.com'>打開百度</a>")# 右對齊label4.setAlignment(Qt.AlignRight)label4.setToolTip('這是一個超級鏈接')vbox = QVBoxLayout()vbox.addWidget(label1)vbox.addWidget(label2)vbox.addWidget(label3)vbox.addWidget(label4)# 綁定信號和槽# 滑過事件label2.linkHovered.connect(self.linkHovered)# 單擊事件label4.linkActivated.connect(self.linkClicked)self.setLayout(vbox)self.setWindowTitle('QLabel控件演示')self.resize(400, 300)returndef linkHovered(self):print('當鼠標滑過label2標簽時,觸發事件')def linkClicked(self):print('當鼠標單擊label4標簽時,觸發事件')if __name__ == '__main__':app = QApplication(sys.argv)main = QLabelDdemo()main.show()sys.exit(app.exec_())

課時31 QLabel與伙伴關系

伙伴關系

舉例:柵格布局下給控件設置伙伴關系

addWidget函數:

mainLayout . addWidget(控件對象, rowIndex, columnIndex, row, column)

第一個參數是要添加的控件對象,第二個和第三個是位置索引(行,列),就像矩陣一樣是從(0,0)開始的,第四,五參數是空間大小,第四個是占幾行,第五個是占幾列

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 14:12 from PyQt5.QtWidgets import * import sys''' QLabel與伙伴控件 控件對象 #組件對象 rowIndex,columnIndex #控件位置 row,column #指定控件的尺寸 mainLayout.addWidget(控件對象,rowIndex,columnIndex,row,column) ''' class QLabelBuddy(QDialog):def __init__(self):super(QLabelBuddy, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QLabel與伙伴關系')self.resize(400, 150)# &代表設置熱鍵,其后第一個字母就是熱鍵,不區分大小寫,Alt+熱鍵調用即可nameLabel = QLabel('&Name(N)', self) # designer下的labelnameLineEdit = QLineEdit(self) # designer下的lineEdit,即文本輸入框# 設置伙伴關系nameLabel.setBuddy(nameLineEdit)passwordLabel = QLabel('&Password(P)', self) # designer下的labelpasswordLineEdit = QLineEdit(self) # designer下的lineEdit,即文本輸入框# 設置伙伴關系passwordLabel.setBuddy(passwordLineEdit)btnOK = QPushButton('&OK(O)')btnCancel = QPushButton('&Cancel(C)')# 柵格布局mainlayout = QGridLayout(self)mainlayout.addWidget(nameLabel, 0, 0) # 放在第一行第一列# 放在第一行第二列,占用空間大小為一行兩列(占用大小一行兩列意思就是編輯框寬是標簽控件的兩倍)mainlayout.addWidget(nameLineEdit, 0, 1, 1, 2)mainlayout.addWidget(passwordLabel, 1, 0) # 放在第二行第一列mainlayout.addWidget(passwordLineEdit, 1, 1, 1, 2) # 放在第二行第二列,占用空間大小為一行兩列mainlayout.addWidget(btnOK, 2, 1) # 第三行第二列mainlayout.addWidget(btnCancel, 2, 2) # 第三行第三列returnif __name__ == '__main__':app = QApplication(sys.argv)main = QLabelBuddy()main.show()sys.exit(app.exec_())

課時32 QLineEdit控件與回顯模式


?

高級功能:EchoMode(回顯模式)基本功能:輸入單行文本4種回顯模式:1.Normal就是正常的文本框輸入,我們輸入一個,文本框上就有一個2.NoEcho比如Linux下輸入密碼,輸了半天感覺屏幕上啥也沒輸,但其實輸入了,只不過不顯示到屏幕上而已3.Password就像QQ登錄一樣,回顯但回顯的是小黑圓圈,用于輸入密碼4.PasswordEchoOnEdit也是輸入密碼時,處于編輯時會回顯,但離開編輯狀態時(比如把鼠標移到別的編輯框時)則變成小黑圓圈

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 14:44''' 課時32 QLineEdit控件與回顯模式(EchoMode) ''' from PyQt5.QtWidgets import * import sysclass QLineEditEchoMode(QDialog):def __init__(self):super(QLineEditEchoMode, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('文件輸入框的回顯模式')self.resize(400, 300)# 表單布局formLayout = QFormLayout()# 創建編輯框normalLineEdit = QLineEdit()noEchoLineEdit = QLineEdit()passwordLineEdit = QLineEdit()passwordEchoOnEditLineEdit = QLineEdit()# 放入表單布局中formLayout.addRow('Normal', normalLineEdit)formLayout.addRow('NoEcho', noEchoLineEdit)formLayout.addRow('Password', passwordLineEdit)formLayout.addRow('PasswordEchoOnEdit', passwordEchoOnEditLineEdit)# placeholdertext(沒輸入時文本框里默認顯示的灰色字體)normalLineEdit.setPlaceholderText('Normal')noEchoLineEdit.setPlaceholderText('NoEcho')passwordLineEdit.setPlaceholderText('Password')passwordEchoOnEditLineEdit.setPlaceholderText('PasswordEchoOnEdit')# 設置文本框回顯模式normalLineEdit.setEchoMode(QLineEdit.Normal)noEchoLineEdit.setEchoMode(QLineEdit.NoEcho)passwordLineEdit.setEchoMode(QLineEdit.Password)passwordEchoOnEditLineEdit.setEchoMode(QLineEdit.PasswordEchoOnEdit)self.setLayout(formLayout)if __name__ == '__main__':app = QApplication(sys.argv)main = QLineEditEchoMode()main.show()sys.exit(app.exec_())

課時33 限制QLineEdi t控件的輸入

校驗器

如限制只能輸入整數、浮點數或滿足一定條件的字符串

代碼問題:

限制范圍的函數setRange有bug 需要正則表達式解決bug 可能在蘋果系統可以(應該也不行) win系統不行

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 15:04 課時33 限制QLineEdi t控件的輸入import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import QIntValidator, QDoubleValidator, QRegExpValidator # 最后一個是正則表達式校驗器 from PyQt5.QtCore import QRegExp # 正則表達式類class QLineEditValidator(QWidget):def __init__(self):super(QLineEditValidator, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('文龍學校驗器')# 創建表單布局formLayout = QFormLayout()intLineEdit = QLineEdit()doubleLineEdit = QLineEdit()validatorLineEdit = QLineEdit()formLayout.addRow('整數類型', intLineEdit)formLayout.addRow('浮點類型', doubleLineEdit)formLayout.addRow('數字和字母', validatorLineEdit)intLineEdit.setPlaceholderText('整型[1,99]')doubleLineEdit.setPlaceholderText('浮點類型[-360,360]')validatorLineEdit.setPlaceholderText('數字和字母')# 整數校驗器[1,99]intValidator = QIntValidator(self) # 因為此函數需要一個QWidget對象作為參數,所以把自己傳進去了intValidator.setRange(1, 99) # 試了試可以輸入0# 浮點校驗器[-1,360],精度:小數點后2位doubleValidator = QDoubleValidator(self) # 傳self原因同上doubleValidator.setRange(-1, 360) # setRange有bug 需要正則表達式解決bug 可以在蘋果系統可以(沒有試過) win系統不行doubleValidator.setNotation(QDoubleValidator.StandardNotation)# 設置精度,小數點2位doubleValidator.setDecimals(2)# 字符和數字reg = QRegExp('[a-zA-Z0-9]+$') # 正則表達式validtor = QRegExpValidator(self) # 傳self原因同上validtor.setRegExp(reg)# 設置校驗器intLineEdit.setValidator(intValidator)doubleLineEdit.setValidator(doubleValidator)validatorLineEdit.setValidator(validtor)self.setLayout(formLayout)if __name__ == '__main__':app = QApplication(sys.argv)main = QLineEditValidator()main.show()sys.exit(app.exec_())

課時34 使用掩碼限制QLineEdit控件的輸入

用掩碼限制QLineEdit控件的輸入

A:ASCII字母字符是必須輸入的(A-Z、a-z) a:ASCII字母字符是允許輸入的,但不是必需的(A-Z、a-z) N:ASCII字母字符是必須輸入的(A-Z、a-z、0-9) n:ASCII字母字符是允許輸入的,但不是必需的(A-Z. a-z、0-9) X:任何字符都是必須輸入的 x:任何字符都是允許輸入的,但不是必需的 9:ASCII數字字符是必須輸入的(0-9) 0:ASCII數字字符是允許輸入的,但不是必需的(0-9) D:ASCII數字字符是必須輸入的(1-9) d:ASCII數字字符是允許輸入的,但不是必需的(1-9) #:ASCII數字字符或加減符號是允許輸入的,但不是必需的 H:十六進制格式字符是必須輸入的(A-F、a-f、0-9) h:十六進制格式字符是允許輸入的,但不是必需的(A-F、a-f、0-9) B:二進制格式字符是必須輸入的(0, 1) b:二進制格式字符是允許輸入的,但不是必需的(0, 1) >:所有的字母字符都大寫<:所有字母字符都小寫!:關閉大小寫轉換\:使用"\"轉義上面列出的字符 # @CSDN王家視頻教程圖書館 # @Time 2022/11/23 15:26 import sys from PyQt5.QtWidgets import *class QLineEditMask(QWidget):def __init__(self):super(QLineEditMask, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('用掩碼限制QLineEdit控件的輸入')formLayout = QFormLayout()ipLineEdit = QLineEdit() # ip地址macLineEdit = QLineEdit() # MAC地址dateLineEdit = QLineEdit() # 日期licenseLineEdit = QLineEdit() # 驗證碼#192.168.21.45# 最后加個分號和_意為沒輸入是默認顯示_ ,前面的都是掩碼,即ASCII數字字符是允許輸入的,但不是必需的(0-9)ipLineEdit.setInputMask('000.000.000.000;_')macLineEdit.setInputMask('HH:HH:HH:HH:HH:HH;_')dateLineEdit.setInputMask('0000-00-00')licenseLineEdit.setInputMask('>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#') # 若沒有輸入顯示井號formLayout.addRow('數字掩碼', ipLineEdit)formLayout.addRow('MAC掩碼', macLineEdit)formLayout.addRow('日期掩碼', dateLineEdit)formLayout.addRow('許可證掩碼', licenseLineEdit)self.setLayout(formLayout)if __name__ == '__main__':app = QApplication(sys.argv)main = QLineEditMask()main.show()sys.exit(app.exec_())

課時35 QLineEdit綜合案例

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 15:37 from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import Qt import sysclass QLine_comprehensive_case(QWidget):def __init__(self):super(QLine_comprehensive_case, self).__init__()self.initUI()def initUI(self):'''控件定義及屬性設置'''edit1 = QLineEdit()# int校驗器edit1.setValidator(QIntValidator())# 設置最大位數為4位,即不超過9999edit1.setMaxLength(4)# 右對齊edit1.setAlignment(Qt.AlignRight)# 這個字號直接影響輸入框的尺寸edit1.setFont(QFont('Arial', 18))edit2 = QLineEdit()edit2.setValidator(QDoubleValidator(0.99, 99.99, 2)) # 2是精度,即小數點后幾位edit3 = QLineEdit()edit3.setInputMask('99_9999_999999;#')edit4 = QLineEdit()edit4.textChanged.connect(self.textChanged) # 綁定信號和槽edit5 = QLineEdit()edit5.setEchoMode(QLineEdit.Password)edit5.editingFinished.connect(self.enterPress) # 綁定信號和槽edit6 = QLineEdit('Hello Pyqt5!')edit6.setReadOnly(True) # 只讀'''將控件添加到表單'''formlayout = QFormLayout()formlayout.addRow('整數校驗', edit1)formlayout.addRow('浮點數校驗', edit2)formlayout.addRow('input mask', edit3)formlayout.addRow('文本變化', edit4)formlayout.addRow('密碼', edit5)formlayout.addRow('只讀', edit6)'''設置主窗口屬性'''self.setLayout(formlayout)self.setWindowTitle('QLineEdit綜合案例')'''槽函數'''def textChanged(self, text):print('輸入的內容' + text)def enterPress(self):print('已輸入值')if __name__ == '__main__':app = QApplication(sys.argv)main = QLine_comprehensive_case()main.show()sys.exit(app.exec_())

課時36 使用QTextEdit控件輸入多行文本

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 16:30 from PyQt5.QtWidgets import * import sysclass QTextEditDemo(QWidget):def __init__(self):super(QTextEditDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QTextEdit控件演示')self.resize(300, 320)# 定義控件self.textEdit = QTextEdit()self.buttonText = QPushButton('顯示文本')self.buttonHTML = QPushButton('顯示HTML')self.buttonToText = QPushButton('獲取文本')self.buttonToHTML = QPushButton('獲取HTML')# 垂直布局layout = QVBoxLayout()layout.addWidget(self.textEdit)layout.addWidget(self.buttonText)layout.addWidget(self.buttonHTML)layout.addWidget(self.buttonToText)layout.addWidget(self.buttonToHTML)# 綁定信號和槽self.buttonText.clicked.connect(self.onClick_buttonText)self.buttonHTML.clicked.connect(self.onClick_buttonHTML)self.buttonToText.clicked.connect(self.onClick_buttonToText)self.buttonToHTML.clicked.connect(self.onClick_buttonToHTML)self.setLayout(layout)# 槽函數def onClick_buttonText(self):# 普通文本self.textEdit.setPlainText('Hello World!')def onClick_buttonHTML(self):# 富文本(HTML)self.textEdit.setHtml('<font color="blue" size="5">Hello World</font>')def onClick_buttonToText(self):print(self.textEdit.toPlainText()) # 控制臺輸出普通文本def onClick_buttonToHTML(self):print(self.textEdit.toHtml()) # 控制臺輸出HTML文本if __name__ == '__main__':app = QApplication(sys.argv)main = QTextEditDemo()main.show()sys.exit(app.exec_())

課時37 按鈕控件(QpushButton)

QAbstractButton(所有按鈕控件的父類) QPushButton(普通按鈕) AToolButton(工具條按鈕) QRadioButton(單選框按鈕) QCheckBox(復選框按鈕)

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 16:47import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import *class QPushButtonDemo(QDialog):def __init__(self):super(QPushButtonDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QPushButton Demo')self.resize(350, 200)layout = QVBoxLayout() # 垂直布局self.btn1 = QPushButton('第一個按鈕')self.btn1.setText('First Button1')# 下面兩句配合使用,功能類似于單選框按鈕QCheckBoxself.btn1.setCheckable(True)self.btn1.toggle() # 按一下就按下去了,再按一下才能抬起# btn1一個信號對應兩個槽函數self.btn1.clicked.connect(self.buttonState) # 先綁定誰系統就先調用誰self.btn1.clicked.connect(lambda: self.whichButton(self.btn1))layout.addWidget(self.btn1)# 在文本前面顯示圖像self.btn2 = QPushButton('圖像按鈕')self.btn2.setIcon(QIcon(QPixmap('./and.png')))self.btn2.clicked.connect(lambda: self.whichButton(self.btn2))layout.addWidget(self.btn2)self.btn3 = QPushButton('不可用的按鈕')self.btn3.setEnabled(False)layout.addWidget(self.btn3)self.btn4 = QPushButton('&MyButton') # 設置了熱鍵M/mself.btn4.setDefault(True) # 如果沒有任何按鈕被選中,那么按回車就是按了這個按鈕self.btn4.clicked.connect(lambda: self.whichButton(self.btn4))layout.addWidget(self.btn4)self.setLayout(layout)'''注意下面的方法是兩個參數,如果用傳統的信號與槽連接方式的話,只會將按鈕對象本身傳入,那樣的話第二個參數就沒有傳入值了所以要用lambda表達式,當前對象直接調用這個函數,傳入的值就對應第二個參數了'''def whichButton(self, btn):# self.sender() #通過此方法可得到是哪個按鈕被按下,或者可用此方法中的傳參方法print('被單擊的按鈕是<' + btn.text() + '>')def buttonState(self):if self.btn1.isChecked():print('按鈕1已經被選中')else:print('按鈕1未被選中')if __name__ == '__main__':app = QApplication(sys.argv)main = QPushButtonDemo()main.show()sys.exit(app.exec_())

單選按鈕控件QRatioButton

在一個容器內的單選按鈕是互斥的,即選中了一個單選按鈕,就不能再選中另一個單選按鈕,也就是不能同時處于選中狀態。在不同容器中的單選按鈕是分開的,互不影響。

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 17:12 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import *class QRatioButtonDemo(QWidget):def __init__(self):super(QRatioButtonDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QRatioButton')self.resize(350, 100)# 水平布局layout = QHBoxLayout()self.btn1 = QRadioButton('單選按鈕1')# 設為默認是選中狀態self.btn1.setChecked(True)# toggled是狀態切換的信號self.btn1.toggled.connect(self.buttonState)layout.addWidget(self.btn1)self.btn2 = QRadioButton('單選按鈕2')self.btn2.toggled.connect(self.buttonState)layout.addWidget(self.btn2)self.setLayout(layout)def buttonState(self):ratiobtn = self.sender()if ratiobtn.isChecked() == True:print('<' + ratiobtn.text() + '>被選中')else:print('<' + ratiobtn.text() + '>被取消選中狀態')# 同一容器下單選按鈕是互斥的,所以不必利用ratiobtn.text()來分情況判斷'''if ratiobtn.text()=='單選按鈕1':#是否被選中if ratiobtn.isChecked()==True:print('<'+ratiobtn.text()+'>被選中')else:print('<'+ratiobtn.text()+'>被取消選中狀態')if ratiobtn.text()=='單選按鈕2':if ratiobtn.isChecked()==True:print('<'+ratiobtn.text()+'>被選中')else:print('<'+ratiobtn.text()+'>被取消選中狀態')'''if __name__ == '__main__':app = QApplication(sys.argv)main = QRatioButtonDemo()main.show()sys.exit(app.exec_())

課時39 復選框控件QCheckBox

3種狀態:未選中:0半選中:1選中:2tristate屬性表示復選框是三種狀態還是兩種狀態,如果tristate為true,則表示復選框中有選中,半選中,未選中三種狀態,即setTristate(True)即表示允許半選中。 # @CSDN王家視頻教程圖書館 # @Time 2022/11/23 17:39import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtCore import Qt # 其中有許多常量class QCheckBoxDemo(QWidget):def __init__(self):super(QCheckBoxDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QCheckBoxDemo')self.resize(350, 100)layout = QHBoxLayout()self.checkbox1 = QCheckBox('復選框控件1')# 默認選中self.checkbox1.setChecked(True) # 此函數只有兩種狀態self.checkbox1.stateChanged.connect(lambda: self.checkboxState(self.checkbox1))layout.addWidget(self.checkbox1)self.checkbox2 = QCheckBox('復選框控件2')self.checkbox2.stateChanged.connect(lambda: self.checkboxState(self.checkbox2))layout.addWidget(self.checkbox2)self.checkbox3 = QCheckBox('半選中控件3')# 設置選中有三個狀態(即允許半選中)self.checkbox3.setTristate(True)# setCheckState函數有三種狀態:Unchecked,PartiallyChecked,Checkedself.checkbox3.setCheckState(Qt.PartiallyChecked)self.checkbox3.stateChanged.connect(lambda: self.checkboxState(self.checkbox3))layout.addWidget(self.checkbox3)self.setLayout(layout)def checkboxState(self, cb):check1Status = self.checkbox1.text() + ',isChecked=' + str(self.checkbox1.isChecked()) + ',isCheckstate=' + str(self.checkbox1.checkState()) + '\n'check2Status = self.checkbox2.text() + ',isChecked=' + str(self.checkbox2.isChecked()) + ',isCheckstate' + str(self.checkbox2.checkState()) + '\n'check3Status = self.checkbox3.text() + ',isChecked=' + str(self.checkbox3.isChecked()) + ',isCheckstate' + str(self.checkbox3.checkState()) + '\n'print(check1Status + check2Status + check3Status)if __name__ == '__main__':app = QApplication(sys.argv)main = QCheckBoxDemo()main.show()sys.exit(app.exec_())

?課時40 下拉列表控件QComboBox

1 如何將列表項添加到QComboBox控件中

2 如何獲取選中的列表項

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 17:56import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtCore import Qt # 其中有許多常量class QComboBoxDemo(QWidget):def __init__(self):super(QComboBoxDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QComboBoxDemo')self.resize(350, 100)# 垂直布局layout = QVBoxLayout()self.label = QLabel('請選擇編程語言')self.cb = QComboBox()self.cb.addItem('JavaEE')self.cb.addItem('Uniapp')self.cb.addItems(['Python', '大數據', '區塊鏈'])# 每一項都對應一個下標索引self.cb.currentIndexChanged.connect(self.selectionChange) # 此信號默認傳遞兩個參數(控件本身,索引)layout.addWidget(self.label)layout.addWidget(self.cb)self.setLayout(layout)def selectionChange(self, i):# 標簽會隨著當前選中的下拉項而改變self.label.setText(self.cb.currentText())self.label.adjustSize()for j in range(self.cb.count()):print('item' + str(j) + '=' + self.cb.itemText(j))print('current index', i, 'selection changed', self.cb.currentText())if __name__ == '__main__':app = QApplication(sys.argv)main = QComboBoxDemo()main.show()sys.exit(app.exec_())

?課時41 滑塊控件QSlider

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 18:20 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import Qt # 其中有許多常量class QSliderDemo(QWidget):def __init__(self):super(QSliderDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QSlider演示')self.resize(350, 500)# 垂直布局layout = QVBoxLayout()self.label = QLabel('Hello PyQt5!')self.label.setAlignment(Qt.AlignCenter)layout.addWidget(self.label)# 滑塊分為水平和垂直兩種# 水平slider1self.slider1 = QSlider(Qt.Horizontal) # 水平,左右滑動# 設置最小值self.slider1.setMinimum(12)# 設置最大值self.slider1.setMaximum(48)# 步長self.slider1.setSingleStep(3)# 設置當前值self.slider1.setValue(18)# 設置刻度的位置,刻度在下方self.slider1.setTickPosition(QSlider.TicksBelow)# 刻度間隔self.slider1.setTickInterval(6)self.slider1.valueChanged.connect(self.valueChange)# 垂直slider2self.slider2 = QSlider(Qt.Vertical) # 垂直滑塊self.slider2.setMinimum(1)self.slider2.setMaximum(80)self.slider2.setSingleStep(5)self.slider2.setTickPosition(QSlider.TicksLeft) # 刻度條放在滑塊的左邊self.slider2.setTickInterval(10)self.slider2.valueChanged.connect(self.valueChange)layout.addWidget(self.slider1)layout.addWidget(self.slider2)self.setLayout(layout)def valueChange(self):'''注意這里是sender(),而不是slider1也不是slider2,sender()獲取當前操作的控件,這樣無論拖動哪個滑動條字體大小都會變化,因為這倆信號對應這一個槽函數'''print('當前值:%s' % self.sender().value())size = self.sender().value() # 獲得當前值# 使字號根據當前值來變化self.label.setFont(QFont('Arial', size))if __name__ == '__main__':app = QApplication(sys.argv)main = QSliderDemo()main.show()sys.exit(app.exec_())

課時42 計數器控件QSpinBox

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 18:34 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import Qt # 其中有許多常量class QSpinBoxDemo(QWidget):def __init__(self):super(QSpinBoxDemo, self).__init__()self.initUI()def initUI(self):####################################### 窗口設置self.setWindowTitle('QSliderDemo')self.resize(350, 120)# 垂直布局layout = QVBoxLayout()######################################## 控件self.label = QLabel('當前值')self.label.setAlignment(Qt.AlignCenter)self.sb = QSpinBox()# 默認值self.sb.setValue(18)# 設置范圍self.sb.setRange(10, 38)# 設置步長self.sb.setSingleStep(3)####################################### 信號與槽self.sb.valueChanged.connect(self.valueChange)####################################### 組裝layout.addWidget(self.label)layout.addWidget(self.sb)self.setLayout(layout)def valueChange(self):self.label.setText('當前值:' + str(self.sb.value()))if __name__ == '__main__':app = QApplication(sys.argv)main = QSpinBoxDemo()main.show()sys.exit(app.exec_())

課時43 使用 QDialog顯示通用對話框

QMessageBox??? 消息對話框
QColorDialog????? 顏色對話框
QFileDialog?? ? ?? 文件對話框
QFontDia log????? 字體對話框
QInputDialog????? 輸入對話框(獲取輸入信息)

課時44 顯示不同類型的消息對話框

?

主要用于顯示軟件的版本和作者及其他和軟件息息相關的信息

常用的消息對話框:

1.關于對話框
2.錯誤對話框
3.警告對話框
4.提問對話框
5.消息對話框


有2點差異
1.顯示的對話框圖標可能不同
2.顯示的按鈕是不一樣的

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 19:18 import sys from PyQt5.QtWidgets import *class QMessageBoxDemo(QWidget):def __init__(self):super(QMessageBoxDemo, self).__init__()self.initUI()def initUI(self):# 窗口設置self.setWindowTitle('QMessageBoxDemo')self.resize(400, 300)# 控件self.btn1 = QPushButton()self.btn1.setText('顯示關于對話框')self.btn2 = QPushButton()self.btn2.setText('顯示消息對話框')self.btn3 = QPushButton()self.btn3.setText('顯示警告對話框')self.btn4 = QPushButton()self.btn4.setText('顯示錯誤對話框')self.btn5 = QPushButton()'''一般是提問用戶,讓用戶做出選擇比如關閉一個正在編輯的文件,如果沒有保存,軟件會提示你是否保存或者要覆蓋一個文件的話,會提示是否要覆蓋等'''self.btn5.setText('顯示提問對話框')# 信號與槽綁定self.btn1.clicked.connect(self.showDialog)self.btn2.clicked.connect(self.showDialog)self.btn3.clicked.connect(self.showDialog)self.btn4.clicked.connect(self.showDialog)self.btn5.clicked.connect(self.showDialog)# 布局layout = QVBoxLayout()layout.addWidget(self.btn1)layout.addWidget(self.btn2)layout.addWidget(self.btn3)layout.addWidget(self.btn4)layout.addWidget(self.btn5)self.setLayout(layout)# 槽函數def showDialog(self):text = self.sender().text()if text == '顯示關于對話框':QMessageBox.about(self, '關于', '這是一個關于對話框')elif text == '顯示消息對話框':'''第二個參數是窗口名,第三個參數是窗口內容最后一個參數是默認的,什么也不做,按回車就執行默認選項'''reply = QMessageBox.information(self, '消息', '這是一個消息對話框', QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)print(reply == QMessageBox.Yes)elif text == '顯示警告對話框':QMessageBox.warning(self, '警告', '這是一個警告對話框', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)elif text == '顯示錯誤對話框':QMessageBox.critical(self, '警告', '這是一個錯誤對話框', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)elif text == '顯示提問對話框':QMessageBox.question(self, '提問', '這是一個提問對話框', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)if __name__ == '__main__':app = QApplication(sys.argv)main = QMessageBoxDemo()main.show()sys.exit(app.exec_())

課時45 輸入對話框QInputDialog

QInputDialog.getItem? 用于顯示輸入列表,即往里傳入一個元組或列表,就會顯示一個QComboBox

QInputDialog.getText? 用于錄入普通文本

QInputDialog.getInt???? 用于輸入整數的,顯示一個計數器控件

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 19:38 import sys from PyQt5.QtWidgets import *class QInputDialogDemo(QWidget):def __init__(self):super(QInputDialogDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QInputDialogDemo')self.resize(400, 150)# 表單布局layout = QFormLayout()self.btn1 = QPushButton('獲取列表中的選項')self.btn1.clicked.connect(self.getItem)self.lineEdit1 = QLineEdit()layout.addRow(self.btn1, self.lineEdit1)self.btn2 = QPushButton('獲取字符串')self.btn2.clicked.connect(self.getText)self.lineEdit2 = QLineEdit()layout.addRow(self.btn2, self.lineEdit2)self.btn3 = QPushButton('獲取整數')self.btn3.clicked.connect(self.getInt)self.lineEdit3 = QLineEdit()layout.addRow(self.btn3, self.lineEdit3)self.setLayout(layout)# 槽函數# 下拉框def getItem(self):items = ('JavaEE', 'Uniapp', '大數據', '區塊鏈', '人工智能')# 返回的是個元組,第一個元素就是input里對應的內容,第二個元素是個布爾量,如果對話框是按OK則返回1,取消就是返回0item, ok = QInputDialog.getItem(self, '請選擇技術方向', '技術列表', items)print(ok) # 點了OK就返回True,點了Cancel就返回Falseif ok and item:self.lineEdit1.setText(item)print(ok)# 字符串def getText(self):text, ok = QInputDialog.getText(self, '文本輸入框', '輸入姓名')if ok and text:self.lineEdit2.setText(text)# 整數def getInt(self):num, ok = QInputDialog.getInt(self, '整數輸入框', '輸入數字')if ok and num:self.lineEdit3.setText(str(num))if __name__ == '__main__':app = QApplication(sys.argv)main = QInputDialogDemo()main.show()sys.exit(app.exec_())

課時46? 字體對話框QFontDialog

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 19:52 import sys from PyQt5.QtWidgets import *class QFontDialogDemo(QWidget):def __init__(self):super(QFontDialogDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QFontDialogDemo')self.resize(400, 150)layout = QVBoxLayout()self.fontBtn = QPushButton('選擇字體')self.fontBtn.clicked.connect(self.getFont)layout.addWidget(self.fontBtn)self.fontLabel = QLabel('Hello,測試字體例子')layout.addWidget(self.fontLabel)self.setLayout(layout)def getFont(self):(font, ok) = QFontDialog.getFont()if ok:self.fontLabel.setFont(font)if __name__ == '__main__':app = QApplication(sys.argv)main = QFontDialogDemo()main.show()sys.exit(app.exec_())

?課時47 顏色對話框QColorDialog

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 19:59 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import QPaletteclass QColorDialogDemo(QWidget):def __init__(self):super(QColorDialogDemo, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QColorDialogDemo')self.resize(400, 150)layout = QVBoxLayout()self.colorBtn = QPushButton('設置顏色')self.colorBtn.clicked.connect(self.getColor)layout.addWidget(self.colorBtn)self.colorBackBtn = QPushButton('設置背景顏色')self.colorBackBtn.clicked.connect(self.getBackColor)layout.addWidget(self.colorBackBtn)self.colorLabel = QLabel('Hello,測試顏色例子')layout.addWidget(self.colorLabel)self.setLayout(layout)def getColor(self):color = QColorDialog.getColor()# 調色板p = QPalette()# 注意WindowText(這是類屬性,常量)的大小寫,這是常量,別選錯了!!!!p.setColor(QPalette.WindowText, color)print('QPalette.WindowText =', QPalette.WindowText)print('QPalette.Window =', QPalette.Window)self.colorLabel.setPalette(p)# 設置背景顏色def getBackColor(self):color = QColorDialog.getColor()p = QPalette()p.setColor(QPalette.Window, color)# 自動填充背景self.colorLabel.setAutoFillBackground(True)self.colorLabel.setPalette(p)if __name__ == '__main__':app = QApplication(sys.argv)main = QColorDialogDemo()main.show()sys.exit(app.exec_())

課時48 文件對話框QFileDialog

課時49 在窗口上繪制文本

繪圖API: 繪制文本
1.文本
2.各種圖形(直線,點,橢圓,弧,扇形,多邊形等)
3.圖像

QPainter過程:
painter = QPainter()????????? #創建繪制對象
painter. begin()?????????????? ? #開始繪制
painter. drawText(...)??????? #繪制過程
painter. end()??????? ?????????? #結束繪制
必須在paintEvent事件方法(此方法窗口自動調用,創建窗口或窗口尺寸變化時)中繪制各種元素

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 20:29 import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QPainter, QColor, QFont from PyQt5.QtCore import Qtclass DrawText(QWidget):def __init__(self):super(DrawText, self).__init__()self.setWindowTitle('在窗口上繪制文本')self.resize(300, 200)self.text = 'CSDN王家視頻教程圖書館'def paintEvent(self, event):painter = QPainter(self)painter.begin(self)print('窗口大小改變,此方法會不斷調用')# 畫筆painter.setPen(QColor(150, 43, 5)) # RGB# 字體,字號painter.setFont(QFont('SimSun', 25))# 繪圖區域,居中,繪制文本painter.drawText(event.rect(), Qt.AlignCenter, self.text)painter.end()if __name__ == '__main__':app = QApplication(sys.argv)main = DrawText()main.show()sys.exit(app.exec_())

課時50 用像素點繪制正弦曲線

#核心代碼參考for i in range(1000):x = 100 * (-1 + 2.0 * i / 1000) + size.width() / 2.0 # 加上size.width()/2.0是將繪制圖像原點挪到窗口中間y = -50 * math.sin((x - size.width() / 2.0) * math.pi / 50) + size.height() / 2.0painter.drawPoint(x, y) # 說是曲線,其實是畫了1000個點,看上去有點像曲線

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 20:34 ''' 用像素點繪制正弦曲線 -2PI 2PI drawPoint(x,y) '''import sys, math from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import Qtclass DrawPoints(QWidget):def __init__(self):super(DrawPoints, self).__init__()self.resize(500, 300)self.setWindowTitle('在窗口上用像素點繪制2個周期的正弦曲線')def paintEvent(self, event):painter = QPainter() # 定義畫圖對象painter.begin(self) # 開始畫圖painter.setPen(Qt.blue)size = self.size()for i in range(1000):x = 100 * (-1 + 2.0 * i / 1000) + size.width() / 2.0 # 加上size.width()/2.0是將繪制圖像原點挪到窗口中間y = -50 * math.sin((x - size.width() / 2.0) * math.pi / 50) + size.height() / 2.0painter.drawPoint(x, y) # 說是曲線,其實是畫了1000個點,看上去有點像曲線painter.end() # 結束畫圖if __name__ == '__main__':app = QApplication(sys.argv)main = DrawPoints()main.show()sys.exit(app.exec_())

課時51 繪制不同類型的直線

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 20:22 import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QPainter, QColor, QFont, QPen from PyQt5.QtCore import Qtclass DrawMutilLine(QWidget):def __init__(self):super(DrawMutilLine, self).__init__()self.setWindowTitle('設置Pen的樣式')self.resize(350, 250)def paintEvent(self, event):painter = QPainter()painter.begin(self)# 顏色,粗細,畫筆類型pen = QPen(Qt.red, 3, Qt.SolidLine) # 最后一個參數是實線painter.setPen(pen)painter.drawLine(20, 40, 250, 40)pen.setStyle(Qt.DashLine)painter.setPen(pen) # 切記設置完style之后,要再將pen設置一遍,否則不會起作用painter.drawLine(20, 80, 250, 80)pen.setStyle(Qt.DashDotDotLine)painter.setPen(pen)painter.drawLine(20, 120, 250, 120)pen.setStyle(Qt.DotLine)painter.setPen(pen)painter.drawLine(20, 160, 250, 160)pen.setStyle(Qt.CustomDashLine)pen.setDashPattern([1, 10, 5, 10]) # 線長度,間隔長度,線長度,間隔長度painter.setPen(pen)painter.drawLine(20, 200, 250, 200)painter.end()if __name__ == '__main__':app = QApplication(sys.argv)main = DrawMutilLine()main.show()sys.exit(app.exec_())

課時52 繪制各種圖形

繪制各種圖形

圓形
橢圓
矩形(正方形)
多邊形
繪制圖像

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 20:47 import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QPainter, QPolygon, QImage from PyQt5.QtCore import Qt, QRect, QPoint import osclass DrawAll(QWidget):def __init__(self):super(DrawAll, self).__init__()self.setWindowTitle('繪制各種圖形')self.resize(400, 600)def paintEvent(self, event):qp = QPainter(self)qp.begin(self)qp.setPen(Qt.blue)# 繪制弧# 左上角坐標,寬,高rect = QRect(0, 10, 200, 200)# 繪制區域(在其中繪制,起始角度,結束角度)# alen:一個alen等于1/16度,eg:畫45°的弧就是45*16qp.drawArc(rect, 0, 50 * 16)# 通過弧繪制圓qp.setPen(Qt.red)# rect也可直接當參數傳進去qp.drawArc(120, 10, 100, 100, 0, 360 * 16)# 繪制帶弦的弧rect1 = QRect(10, 120, 100, 100)qp.drawChord(rect1, 12, 130 * 16)# 繪制扇形rect2 = QRect(10, 240, 100, 100)qp.drawPie(rect2, 12, 130 * 16)# 橢圓(不需要指定角度)# 寬和高肯定是不一樣的,如果一樣就是圓了,所以繪制圓可以通過橢圓,也可以通過弧qp.drawEllipse(120, 120, 150, 100)# 繪制多邊形# 五邊形,需要五個點point1 = QPoint(140, 380)point2 = QPoint(270, 420)point3 = QPoint(290, 512)point4 = QPoint(290, 588)point5 = QPoint(200, 533)polygon = QPolygon([point1, point2, point3, point4, point5])qp.drawPolygon(polygon)# 繪制圖像print(os.path.exists('./and.png')) # 此路徑是否存在# 裝載圖像image = QImage('./and.png')# 將圖像(面積)縮小64倍rect3 = QRect(10, 400, image.width() / 8, image.height() / 8)qp.drawImage(rect3, image)qp.end()if __name__ == '__main__':app = QApplication(sys.argv)main = DrawAll()main.show()sys.exit(app.exec_())

?課時53 用畫刷填充圖形區域

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 21:02 import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QPainter, QPolygon, QImage, QBrush from PyQt5.QtCore import Qt, QRect, QPointclass FillRect(QWidget):def __init__(self):super(FillRect, self).__init__()self.setWindowTitle('繪制各種圖形')self.resize(400, 200)def paintEvent(self, event):qp = QPainter(self)qp.begin(self)brush = QBrush(Qt.SolidPattern) # 實心qp.setBrush(brush)qp.drawRect(10, 15, 90, 60)brush = QBrush(Qt.Dense1Pattern)qp.setBrush(brush)qp.drawRect(130, 15, 90, 60)brush = QBrush(Qt.Dense2Pattern)qp.setBrush(brush)qp.drawRect(250, 15, 90, 60)brush = QBrush(Qt.Dense3Pattern)qp.setBrush(brush)qp.drawRect(10, 105, 90, 60)brush = QBrush(Qt.HorPattern)qp.setBrush(brush)qp.drawRect(130, 105, 90, 60)qp.end()if __name__ == '__main__':app = QApplication(sys.argv)main = FillRect()main.show()sys.exit(app.exec_())

?課時54 讓控件支持拖拽動作

過程:
A.setDrapEnabled(True)?? 設置A支持拖拽
B. setAcceptDrops(True)?? 設置B可接收


B需要兩個事件:
1. dragEnterEvent???? 將A拖到B觸發
2. dropEvent???????????? 在B的區域放下A時觸發

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 21:10 import sys from PyQt5.QtWidgets import *# 下拉框類 class MyComboBox(QComboBox):def __init__(self):super(MyComboBox, self).__init__()# 設置下拉框可接收self.setAcceptDrops(True)# 別的控件拖進來以后,還沒松鼠標時,下面的函數觸發def dragEnterEvent(self, e):print(e)# 是否是文本if e.mimeData().hasText():e.accept()else:e.ignore()# 當控件拖進來放下時,下面的函數觸發def dropEvent(self, e):# 此時self代表當前下拉列表控件,self.addItem(e.mimeData().text())class DragDropDemo(QWidget):def __init__(self):super(DragDropDemo, self).__init__()formLayout = QFormLayout()formLayout.addRow(QLabel('請將左邊的文本拖到右邊的下拉列表中'))lineEdit = QLineEdit()# 讓QLinEdit控件可拖動lineEdit.setDragEnabled(True)# 第一個類MyComboBox的實例combo = MyComboBox()formLayout.addRow(lineEdit, combo)self.setLayout(formLayout)self.setWindowTitle('拖拽案例')self.resize(400, 100)if __name__ == '__main__':app = QApplication(sys.argv)main = DragDropDemo()main.show()sys.exit(app.exec_())

?課時55 使用剪貼板

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 21:22 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import *class ClipBoardDemo(QDialog):def __init__(self):super(ClipBoardDemo, self).__init__()# 控件# 定義六個復制粘貼按鈕,用來實現復制粘貼文本,圖像和HTML網頁textCopyBtn = QPushButton('復制文本')textPasteBtn = QPushButton('粘貼文本')htmlCopyBtn = QPushButton('復制HTML')htmlPasteBtn = QPushButton('粘貼HTML')imageCopyBtn = QPushButton('復制圖像')imagePasteBtn = QPushButton('粘貼圖像')# 多行文本self.textLabel = QLabel('默認文本')# 標簽用于展示圖片self.imageLabel = QLabel()# 定義網格柵格布局layout = QGridLayout()layout.addWidget(textCopyBtn, 0, 0)layout.addWidget(imageCopyBtn, 0, 1)layout.addWidget(htmlCopyBtn, 0, 2)layout.addWidget(textPasteBtn, 1, 0)layout.addWidget(imagePasteBtn, 1, 1)layout.addWidget(htmlPasteBtn, 1, 2)layout.addWidget(self.textLabel, 2, 0, 1, 2) # 坐標,行占的單位寬度,列占的單位寬度layout.addWidget(self.imageLabel, 2, 2)self.setLayout(layout)# 信號與槽textCopyBtn.clicked.connect(self.copyText)textPasteBtn.clicked.connect(self.pasteText)htmlCopyBtn.clicked.connect(self.copyHtml)htmlPasteBtn.clicked.connect(self.pasteHtml)imageCopyBtn.clicked.connect(self.copyImage)imagePasteBtn.clicked.connect(self.pasteImage)self.setWindowTitle('剪貼板演示')# 槽函數def copyText(self):# 剪貼板對象clipboard = QApplication.clipboard()clipboard.setText('hello csdn')def pasteText(self):clipboard = QApplication.clipboard()self.textLabel.setText(clipboard.text())def copyImage(self):clipboard = QApplication.clipboard()clipboard.setPixmap(QPixmap('./csdnlogo.jpg'))def pasteImage(self):clipboard = QApplication.clipboard()# clipboard.pixmap()是從剪貼板獲得圖像self.imageLabel.setPixmap(clipboard.pixmap())def copyHtml(self):mimeData = QMimeData() # 獲得數據類型mimeData.setHtml('<b>Bold and <font color=red>Red</font></b>')clipboard = QApplication.clipboard()clipboard.setMimeData(mimeData)def pasteHtml(self):clipboard = QApplication.clipboard()mimeData = clipboard.mimeData() # 獲得剪貼板數據# 如果剪貼板數據是html,這里普通文本也可以if mimeData.hasHtml():self.textLabel.setText(mimeData.html())if __name__ == '__main__':app = QApplication(sys.argv)main = ClipBoardDemo()main.show()sys.exit(app.exec_())

課時56 日歷控件

日歷控件:QCalendarWidget

課時57 設置不同風格的日期和時間

控件:QDateTimeEdit

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 21:39 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import *class DateTimeEdit1(QWidget):def __init__(self):super(DateTimeEdit1, self).__init__()self.initUI()def initUI(self):# 垂直布局vlayout = QVBoxLayout()dateTimeEdit1 = QDateTimeEdit()dateTimeEdit2 = QDateTimeEdit(QDateTime.currentDateTimeUtc()) # 傳入當前時間dateEdit = QDateTimeEdit(QDate.currentDate()) # 傳入當前日期timeEdit = QDateTimeEdit(QTime.currentTime()) # 傳入當前日期dateTimeEdit1.setDisplayFormat('yyyy-MM-dd HH:mm:ss')dateTimeEdit2.setDisplayFormat('yyyy/MM/dd HH:mm:ss')dateEdit.setDisplayFormat('yyyy.MM.dd')timeEdit.setDisplayFormat('HH:mm:ss')vlayout.addWidget(dateTimeEdit1)vlayout.addWidget(dateTimeEdit2)vlayout.addWidget(dateEdit)vlayout.addWidget(timeEdit)self.setLayout(vlayout)self.resize(300, 90)self.setWindowTitle('設置不同風格的日期和時間')if __name__ == '__main__':app = QApplication(sys.argv)main = DateTimeEdit1()main.show()sys.exit(app.exec_())

?課時58 日期和時間控件的高級操作

方法?? ?描述
setDisplayFormat?? ?設置日期的時間格式
?? ?yyyy:代表年份,用4為數表示
?? ?MM:代表月份,取值范圍01-12
?? ?dd:代表日,取值范圍01-31
?? ?HH:代表小時,取值范圍00-23
?? ?mm:代表分鐘,取值范圍00-59
?? ?ss:代表秒,取值范圍00-59
setMinimumDate()?? ?設置控件的最小日期
setMaximumDate()?? ?設置控件的最大日期
time()?? ?返回編輯的時間
date()?? ?返回編輯的日期

?

?課時59 創建和使用菜單

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 21:55 import sys from PyQt5.QtWidgets import *class Menu(QMainWindow):def __init__(self):super(Menu, self).__init__()bar = self.menuBar()file = bar.addMenu('文件') # 頂層菜單欄# 文件的子菜單(方法一:直接傳文本,內部會自動創建動作QAction)file.addAction('新建')# 法二:自己用動作來創建子菜單save = QAction('保存', self) # 必須加self,代表在當前窗口加QActionsave.setShortcut('Ctrl+S') # 快捷鍵file.addAction(save)quit = QAction('退出', self)file.addAction(quit)edit = bar.addMenu('Edit') # 頂層菜單edit.addAction('copy') # 子菜單edit.addAction('paste')save.triggered.connect(self.process)self.resize(400, 300)# 槽函數# 事件自動傳給槽函數的一個實參,在本例具體指的是菜單項是否被選中,是一個bool類型的值def process(self, a):print(self.sender().text()) # 注意這里是self.而不是a.if __name__ == '__main__':app = QApplication(sys.argv)main = Menu()main.show()sys.exit(app.exec_())

課時60 創建和使用工具欄

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:06 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import *class Toolbar(QMainWindow):def __init__(self):super(Toolbar, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('工具欄例子')self.resize(300, 200)tb1 = self.addToolBar('File') # 一行工具欄'''工具欄默認按鈕:只顯示圖標,將文本作為懸停提示即鼠標懸停到圖標上之后,提示就是下面的第二個參數'''new = QAction(QIcon('./csdnlogo.jpg'), '新建', self) # self代表放在當前窗口上tb1.addAction(new)open = QAction(QIcon('./csdnlogo.jpg'), '打開', self)tb1.addAction(open)save = QAction(QIcon('./csdnlogo.jpg'), '保存', self)tb1.addAction(save)'''工具欄按鈕有3種顯示狀態1.只顯示圖標2.只顯示文本3.同時顯示文本和圖標'''# 設置工具欄按鈕顯示狀態:既顯示文本又顯示圖標tb1.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) # 設置文本在圖標的下方顯示,還有好多,按ctrl查看自己試試tb2 = self.addToolBar('File1')new1 = QAction(QIcon('./csdnlogo.jpg'), '新建', self)tb2.addAction(new1)tb2.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)tb1.actionTriggered.connect(self.toolbtnpressed)tb2.actionTriggered.connect(self.toolbtnpressed)def toolbtnpressed(self, a):print('按下的工具欄按鈕是', a.text())if __name__ == '__main__':app = QApplication(sys.argv)main = Toolbar()main.show()sys.exit(app.exec_())

課時61 創建和使用狀態欄?

用于顯示狀態信息,一般在窗口的最下方顯示

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:16 import sys from PyQt5.QtWidgets import *class Statusbar(QMainWindow):def __init__(self):super(Statusbar, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('狀態欄演示')self.resize(300, 200)bar = self.menuBar() # 頂層菜單欄file = bar.addMenu('File') # 給菜單欄添加選項file.addAction('show') # 子菜單file.triggered.connect(self.processTrigger)self.setCentralWidget(QTextEdit()) # 多行輸入self.statusBar = QStatusBar()self.setStatusBar(self.statusBar)def processTrigger(self, q):if q.text() == 'show':# 在狀態欄上顯示信息self.statusBar.showMessage(q.text() + '菜單被點擊了', 5000) # 信息顯示5秒if __name__ == '__main__':app = QApplication(sys.argv)main = Statusbar()main.show()sys.exit(app.exec_())

課時62 使用打印機

輸出都是以圖像形式輸出,輸出到打印機

鏈接打印機開始打印 這里就不測試打印機了!

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:21 import sys from PyQt5.QtWidgets import * from PyQt5 import QtGui, QtPrintSupportclass PrintSupport(QMainWindow):def __init__(self):super(PrintSupport, self).__init__()self.setGeometry(500, 200, 300, 300)self.btn = QPushButton('打印QTextEdit控件中的內容', self)self.btn.setGeometry(20, 20, 260, 30) # x,y,w,hself.editor = QTextEdit('默認文本', self)self.editor.setGeometry(20, 60, 260, 200)self.btn.clicked.connect(self.print)def print(self):# 打印機對象printer = QtPrintSupport.QPrinter()painter = QtGui.QPainter()# 將繪制的目標重定向到打印機上painter.begin(printer) # painter畫在begin的參數上,即printer上,若是self,則畫在當前窗口上# 獲得多行輸入控件editor的整個框架screen = self.editor.grab()# 從(10,10)開始將screen上的文字輸出到打印機上# drawPixmap:從圖像文件中提取 Pixmap 并將其顯示在指定位置painter.drawPixmap(10, 10, screen)painter.end()print('print')if __name__ == '__main__':app = QApplication(sys.argv)main = PrintSupport()main.show()sys.exit(app.exec_())

課時63 顯示打印對話框

因為沒有打印機 但是可以輸出為pdf文檔?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:26 import sys from PyQt5.QtPrintSupport import QPrinter, QPageSetupDialog, QPrintDialog from PyQt5.QtWidgets import *class PrintDialog(QMainWindow):def __init__(self):super(PrintDialog, self).__init__()# 打印機對象self.printer = QPrinter()self.initUI()def initUI(self):self.setGeometry(300, 300, 500, 400)self.setWindowTitle('打印對話框')self.editor = QTextEdit(self)self.editor.setGeometry(20, 20, 300, 270)self.openButton = QPushButton('打開文件', self)self.openButton.move(350, 20)self.settingButton = QPushButton('打印設置', self)self.settingButton.move(350, 50)self.printButton = QPushButton('打印文檔', self)self.printButton.move(350, 80)self.openButton.clicked.connect(self.openFile)self.settingButton.clicked.connect(self.showSettingDialog)self.printButton.clicked.connect(self.showPrintDialog)# 打開文件def openFile(self):fname = QFileDialog.getOpenFileName(self, '打開文本文件', './')print(fname)print(fname[0])if fname[0]:with open(fname[0], 'r', encoding='utf-8', errors='ignore') as f:self.editor.setText(f.read())# 顯示打印設置對話框def showSettingDialog(self):printDialog = QPageSetupDialog(self.printer, self)printDialog.exec()# 顯示打印對話框def showPrintDialog(self):printdailog = QPrintDialog(self.printer, self)if QDialog.Accepted == printdailog.exec():# 將editor里的文字輸出到打印機中self.editor.print(self.printer)if __name__ == '__main__':app = QApplication(sys.argv)main = PrintDialog()main.show()sys.exit(app.exec_())

?課時64 顯示二維表數據

顯示二維表數據(QTableVi ew控件)

數據源 Model

需要創建QTableView實例和一個數據源(Model) ,然后將兩者關聯,這個體系類似于MVC模式。

一個QTableView實例可以存放不同的數據源,一個數據源也可以對應不同的QTableView實例。

MVC: Model? Viewer? Controller 即將數據Model和前端視圖Viewer分離,通過控制器Controller 來控制。

MVC的目的是將后端的數據和前端頁面的耦合度降低。

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:36 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import *class TableView(QWidget):def __init__(self):super(TableView, self).__init__()self.setWindowTitle('QTableView表格視圖控件演示')self.resize(500, 300)self.model = QStandardItemModel(4, 3) # 二維表4行3列# 數據表的字段self.model.setHorizontalHeaderLabels(['id', 'name', 'age'])self.tableView = QTableView()# 關聯QTableView控件和Modelself.tableView.setModel(self.model)# 添加數據item11 = QStandardItem('1') # 一個QStandardItem就是一個單元格item12 = QStandardItem('Kobe')item13 = QStandardItem('24')self.model.setItem(0, 0, item11)self.model.setItem(0, 1, item12)self.model.setItem(0, 2, item13)# 可跳行添加數據item31 = QStandardItem('7')item32 = QStandardItem('Durant')item33 = QStandardItem('35')self.model.setItem(2, 0, item31)self.model.setItem(2, 1, item32)self.model.setItem(2, 2, item33)# 垂直布局layout = QVBoxLayout()layout.addWidget(self.tableView)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = TableView()main.show()sys.exit(app.exec_())

?課時65 顯示列數據

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:46 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import QStringListModelclass ListView(QWidget):def __init__(self):super(ListView, self).__init__()self.setWindowTitle('ListView例子')self.resize(300, 270)layout = QVBoxLayout()listView = QListView()# 數據源listModel = QStringListModel()self.list = ['列表項1', '列表項2', '列表項3']listModel.setStringList(self.list)# 關聯視圖與數據源listView.setModel(listModel)listView.clicked.connect(self.clicked)layout.addWidget(listView)self.setLayout(layout)def clicked(self, item):QMessageBox.information(self, 'QListView', '您選擇了:' + self.list[item.row()])if __name__ == '__main__':app = QApplication(sys.argv)main = ListView()main.show()sys.exit(app.exec_())

課時66? 擴展的列表控件

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:50 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import QStringListModel''' QListWidget是QListView的子類 添加了很多API,支持MVC模式,也支持非MVC模式,即數據直接添加到控件上 '''class ListWidget(QMainWindow):def __init__(self):super(ListWidget, self).__init__()self.setWindowTitle('ListWidget例子')self.resize(300, 270)# 直接添加的方式適合少量的數據的時候self.listWidget = QListWidget()# self.listWidget.resize(300,120)self.listWidget.addItem('item1')self.listWidget.addItem('item2')self.listWidget.addItem('item3')self.listWidget.addItem('item4')self.listWidget.addItem('item5')self.listWidget.itemClicked.connect(self.clicked)# 設置中心控件之后,會鋪滿整個屏幕,無需再單獨設置listWidget尺寸self.setCentralWidget(self.listWidget)def clicked(self, index):QMessageBox.information(self, 'ListWidget','您選擇了:' + self.listWidget.item(self.listWidget.row(index)).text())if __name__ == '__main__':app = QApplication(sys.argv)main = ListWidget()main.show()sys.exit(app.exec_())

課時67 擴展的表格控件

每一個Cell (單元格) 是一個QTableWidgetItem

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:52 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import *''' QTableWidget是QTableView的子類 添加了很多API,支持MVC模式,也支持非MVC模式,即數據直接添加到控件上 '''class TableWidget(QWidget):def __init__(self):super(TableWidget, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('QTableWidget演示')self.resize(430, 230)layout = QHBoxLayout()tablewidget = QTableWidget()# 4行3列tablewidget.setRowCount(4)tablewidget.setColumnCount(3)tablewidget.setHorizontalHeaderLabels(['name', 'age', 'address'])nameItem = QTableWidgetItem('文龍')tablewidget.setItem(0, 0, nameItem)ageItem = QTableWidgetItem('23')tablewidget.setItem(0, 1, ageItem)addressItem = QTableWidgetItem('北京')tablewidget.setItem(0, 2, addressItem)# 禁止編輯tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)# 整行選擇tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)# 調整列和行tablewidget.resizeColumnsToContents()tablewidget.resizeRowsToContents()# 隱藏表格頭tablewidget.horizontalHeader().setVisible(False) # 隱藏水平方向的表格頭# tablewidget.verticalHeader().setVisible(False) #隱藏垂直方向的表格頭# 設置表格頭內容tablewidget.setVerticalHeaderLabels(['a', 'b']) # 垂直方向表格頭前兩個設為a,b# 隱藏表格線tablewidget.setShowGrid(False)layout.addWidget(tablewidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = TableWidget()main.show()sys.exit(app.exec_())

課時68 在單元格中放置控件

在單元格中放置控件
setItem:將文本放到單元格中
setCellWidget:將控件放到單元格中
setStyleSheet設置控件的樣式(QSS)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 22:57 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import *''' QTableWidget是QTableView的子類 添加了很多API,支持MVC模式,也支持非MVC模式,即數據直接添加到控件上 '''class TableWidget2(QWidget):def __init__(self):super(TableWidget2, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('在單元格中放置控件')self.resize(430, 300)layout = QHBoxLayout()tableWidget = QTableWidget()# 4行3列tableWidget.setRowCount(4)tableWidget.setColumnCount(3)tableWidget.setHorizontalHeaderLabels(['name', 'age', 'weigh(kg)'])textItem = QTableWidgetItem('小明')# setItem:將文本放到單元格中tableWidget.setItem(0, 0, textItem)# 下拉框combox = QComboBox()combox.addItem('男')combox.addItem('女')# setStyleSheet設置控件的樣式(QSS)(類似于web中的CSS),即Qt StyleSheet(n.樣式表)combox.setStyleSheet('QComboBox{margin:3px};') # 設置控鍵距離上下左右的單元格的距離(距離)# setCellWidget:將控件放到單元格中tableWidget.setCellWidget(0, 1, combox)modifyButton = QPushButton('修改')# 默認是按下的狀態modifyButton.setDown(True)modifyButton.setStyleSheet('QPushButton{margin:3px};')tableWidget.setCellWidget(0, 2, modifyButton)layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = TableWidget2()main.show()sys.exit(app.exec_())

課時69 在表格中搜索Cell和行定位

在表格中快速定位到特定的行
1.數據的定位: findItems ,返回一個列表
2.如果找到了滿足條件的單元格,會定位到單元格所在的行: setSliderPosition(row)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:03 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class DataLocation(QWidget):def __init__(self):super(DataLocation, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('在表格中搜索Cell和行定位')self.resize(600, 800)layout = QHBoxLayout()tableWidget = QTableWidget()tableWidget.setRowCount(40)tableWidget.setColumnCount(4)for i in range(40):for j in range(4):itemContent = '(%d,%d)' % (i, j)tableWidget.setItem(i, j, QTableWidgetItem(itemContent))self.setLayout(layout)# 搜索滿足條件的Celltext = '(13,1)'text1 = '(1,'# 參數一:要匹配的文本 ; 參數二:搜索模式,返回一個列表# items=tableWidget.findItems(text,Qt.MatchExactly)#搜索模式設為精確匹配,必須一模一樣才行items = tableWidget.findItems(text1, Qt.MatchStartsWith) # 搜索模式為匹配以...為開頭的字符串,這里看text1,即以(1,開頭的的字符串length = len(items)if length > 0:print('匹配項個數:', len(items))for i in range(length):item = items[i]# 背景色item.setBackground(QBrush(QColor(0, 255, 0))) # rgb# 前景色,即文字的顏色item.setForeground(QBrush(QColor(255, 0, 0)))# 當前項所在的行row = item.row()# 定位到指定的行tableWidget.verticalScrollBar().setSliderPosition(row)layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = DataLocation()main.show()sys.exit(app.exec_())

課時70 設置單元格字體和顏色

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:19 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class CellFontAndColor(QWidget):def __init__(self):super(CellFontAndColor, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('設置單元格字體和顏色')self.resize(430, 230)layout = QHBoxLayout()tableWidget = QTableWidget()tableWidget.setRowCount(4)tableWidget.setColumnCount(3)tableWidget.setHorizontalHeaderLabels(['name', 'sex', 'weigh(kg)'])newItem = QTableWidgetItem('小明') # 單元格的數據項newItem.setFont(QFont('Times', 14, QFont.Black)) # 字體,字號,顏色newItem.setForeground(QBrush(QColor(255, 0, 0)))tableWidget.setItem(0, 0, newItem)newItem = QTableWidgetItem('女')newItem.setForeground(QBrush(QColor(255, 255, 0)))newItem.setBackground(QBrush(QColor(0, 0, 255))) # rgbtableWidget.setItem(0, 1, newItem)newItem = QTableWidgetItem('100')newItem.setFont(QFont('Times', 20, QFont.Black))newItem.setForeground(QBrush(QColor(0, 0, 255)))tableWidget.setItem(0, 2, newItem)layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = CellFontAndColor()main.show()sys.exit(app.exec_())

課時71 按表格的某一列排序

按列排序
1.按哪一列排序
2.排序類型:升序或降序
sortItems( columnIndex,orderType)

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:23 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class CellFontAndColor(QWidget):def __init__(self):super(CellFontAndColor, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('設置單元格字體和顏色')self.resize(540, 230)layout = QHBoxLayout()self.tableWidget = QTableWidget() # 表格對象self.tableWidget.setRowCount(4)self.tableWidget.setColumnCount(3)self.tableWidget.setHorizontalHeaderLabels(['name', 'sex', 'weigh(kg)'])# 添加數據newItem = QTableWidgetItem('張三')self.tableWidget.setItem(0, 0, newItem)newItem = QTableWidgetItem('男')self.tableWidget.setItem(0, 1, newItem)newItem = QTableWidgetItem('165')self.tableWidget.setItem(0, 2, newItem)newItem = QTableWidgetItem('李四')self.tableWidget.setItem(1, 0, newItem)newItem = QTableWidgetItem('女')self.tableWidget.setItem(1, 1, newItem)newItem = QTableWidgetItem('120')self.tableWidget.setItem(1, 2, newItem)newItem = QTableWidgetItem('王五')self.tableWidget.setItem(2, 0, newItem)newItem = QTableWidgetItem('男')self.tableWidget.setItem(2, 1, newItem)newItem = QTableWidgetItem('130')self.tableWidget.setItem(2, 2, newItem)# 點擊按鈕排序self.btn = QPushButton('升序')self.btn.clicked.connect(self.order)# 常量self.orderType = Qt.DescendingOrderlayout.addWidget(self.tableWidget)layout.addWidget(self.btn)self.setLayout(layout)# 升降序來回切換def order(self):if self.orderType == Qt.DescendingOrder:self.orderType = Qt.AscendingOrderself.btn.setText('降序') # 重命名按鈕名,setText設置按鈕顯示文本else:self.orderType = Qt.DescendingOrderself.btn.setText('升序')# print(Qt.DescendingOrder)# print(self.orderType)self.tableWidget.sortItems(2, self.orderType) # 按照第三列的數據項排序# self.tableWidget.sortItems(2, Qt.DescendingOrder)if __name__ == '__main__':app = QApplication(sys.argv)main = CellFontAndColor()main.show()sys.exit(app.exec_())

課時71 設置單元格的文本對齊方式

setTextAlignment
Qt. AlignRight 右對齊 ? ???? Qt.AlignBottom底端顯示

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:29 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class CellTextAlignment(QWidget):def __init__(self):super(CellTextAlignment, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('設置單元格的文本對齊方式')self.resize(430, 230)layout = QHBoxLayout()# 表格對象tableWidget = QTableWidget()# 四行三列tableWidget.setRowCount(4)tableWidget.setColumnCount(3)# 設置表格字段tableWidget.setHorizontalHeaderLabels(['姓名', '性別', '體重(kg)'])newItem = QTableWidgetItem('小明')# 下面說的對齊與顯示都是指在單元格中# 右對齊 底端顯示,即右下,Qt.AlignRight默認是右上newItem.setTextAlignment(Qt.AlignRight | Qt.AlignBottom)tableWidget.setItem(0, 0, newItem)# 中心對齊,底部顯示newItem = QTableWidgetItem('男')newItem.setTextAlignment(Qt.AlignCenter | Qt.AlignBottom)tableWidget.setItem(0, 1, newItem)newItem = QTableWidgetItem('190')newItem.setTextAlignment(Qt.AlignRight)tableWidget.setItem(0, 2, newItem)layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = CellTextAlignment()main.show()sys.exit(app.exec_())

課時73 合并單元格

setSpan(row, col ,要合并的行數,要合并的列數)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:31 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class MergeCell(QWidget):def __init__(self):super(MergeCell, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('合并單元格')self.resize(430, 230)layout = QHBoxLayout()# 表格對象tableWidget = QTableWidget()# 四行三列tableWidget.setRowCount(4)tableWidget.setColumnCount(3)# 設置表格字段tableWidget.setHorizontalHeaderLabels(['姓名', '性別', '體重(kg)'])newItem = QTableWidgetItem('小明')tableWidget.setItem(0, 0, newItem)# setSpan(row, col, 要合并的行數,要合并的列數)tableWidget.setSpan(0, 0, 3, 1)newItem = QTableWidgetItem('男')tableWidget.setItem(0, 1, newItem)tableWidget.setSpan(0, 1, 2, 1)newItem = QTableWidgetItem('190')tableWidget.setItem(0, 2, newItem)newItem = QTableWidgetItem('test')tableWidget.setItem(2, 1, newItem)tableWidget.setSpan(2, 1, 1, 2)layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = MergeCell()main.show()sys.exit(app.exec_())

課時74 設置單元格的尺寸

單元格大小可手動拖動改變大小,當字體設置很大時,運行之后顯示的單元格大小可能不足夠顯示出文字,只會顯示三個點省略,這時就要設置單元格尺寸了。

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:34 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class MergeCell(QWidget):def __init__(self):super(MergeCell, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('合并單元格')self.resize(600, 400)layout = QHBoxLayout()# 表格對象tableWidget = QTableWidget()# 四行三列tableWidget.setRowCount(4)tableWidget.setColumnCount(3)# 設置表格字段tableWidget.setHorizontalHeaderLabels(['姓名', '性別', '體重(kg)'])newItem = QTableWidgetItem('小明') # 單元格的數據項newItem.setFont(QFont('Times', 40, QFont.Black)) # 字體,字號,顏色newItem.setForeground(QBrush(QColor(255, 0, 0)))tableWidget.setItem(0, 0, newItem)newItem = QTableWidgetItem('女')newItem.setForeground(QBrush(QColor(255, 255, 0)))newItem.setBackground(QBrush(QColor(0, 0, 255))) # rgbtableWidget.setItem(0, 1, newItem)newItem = QTableWidgetItem('100')newItem.setFont(QFont('Times', 60, QFont.Black))newItem.setForeground(QBrush(QColor(0, 0, 255)))tableWidget.setItem(0, 2, newItem)tableWidget.setRowHeight(0, 120) # 設置第一行高度,三個數據項都在第一行上,第一行的單元格高度都變為120tableWidget.setColumnWidth(0, 150) # 設置第一列寬度tableWidget.setRowHeight(2, 200) # 設置第三行高度,注意這是第三行,而不是第三個單元格的高度!!!!!tableWidget.setColumnWidth(2, 180) # 設置第二列寬度layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = MergeCell()main.show()sys.exit(app.exec_())

課時75 在單元格中實現圖文混排的效果

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:38 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class MergeCell(QWidget):def __init__(self):super(MergeCell, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('合并單元格')self.resize(600, 250)layout = QHBoxLayout()# 表格對象tableWidget = QTableWidget()# 四行四列tableWidget.setRowCount(4)tableWidget.setColumnCount(4)# 設置表格字段tableWidget.setHorizontalHeaderLabels(['姓名', '性別', '體重(kg)'])newItem = QTableWidgetItem('李寧')tableWidget.setItem(0, 0, newItem)newItem = QTableWidgetItem('男')tableWidget.setItem(0, 1, newItem)newItem = QTableWidgetItem('160')tableWidget.setItem(0, 2, newItem)newItem = QTableWidgetItem(QIcon('./and.png'), '背包')tableWidget.setItem(0, 3, newItem)layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = MergeCell()main.show()sys.exit(app.exec_())

課時76 改變單元格中圖片的尺寸

setIconSize(QSize(width, height))

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:44 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class CellImageSize(QWidget):def __init__(self):super(CellImageSize, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('改變單元格中圖片尺寸')self.resize(1000, 900)layout = QHBoxLayout()# 表格對象tableWidget = QTableWidget()# 設置單元格中圖片大小tableWidget.setIconSize(QSize(300, 200))# 五行三列tableWidget.setRowCount(5)tableWidget.setColumnCount(3)# 設置表格字段tableWidget.setHorizontalHeaderLabels(['image1', 'image2', 'image3'])# 讓列的寬度和圖片的寬度相同for i in range(3):tableWidget.setColumnWidth(i, 300)# 讓行的高度和圖片的高度相同for i in range(5):tableWidget.setRowHeight(i, 200)for k in range(15):i = k / 3 # 行j = k % 3 # 列item = QTableWidgetItem()item.setIcon(QIcon('./csdn/csdn%d.png' % (k + 1)))tableWidget.setItem(i, j, item)layout.addWidget(tableWidget)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = CellImageSize()main.show()sys.exit(app.exec_())

課時77 在表格中顯示上下文菜單

1.如何彈出菜單
2.如果在滿足條件的情況下彈出菜單
QMenu. exec_()

# @CSDN王家視頻教程圖書館 # @Time 2022/11/23 23:56 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class CellImageSize(QWidget):def __init__(self):super(CellImageSize, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('在表格中顯示上下文菜單')self.resize(500, 200)layout = QHBoxLayout()# 表格對象self.tableWidget = QTableWidget()# 五行三列self.tableWidget.setRowCount(4)self.tableWidget.setColumnCount(3)# 設置表格字段self.tableWidget.setHorizontalHeaderLabels(['name', 'sex', 'weigh'])# 添加數據newItem = QTableWidgetItem('小明')self.tableWidget.setItem(0, 0, newItem)newItem = QTableWidgetItem('男')self.tableWidget.setItem(0, 1, newItem)newItem = QTableWidgetItem('190')self.tableWidget.setItem(0, 2, newItem)newItem = QTableWidgetItem('小亮')self.tableWidget.setItem(1, 0, newItem)newItem = QTableWidgetItem('男')self.tableWidget.setItem(1, 1, newItem)newItem = QTableWidgetItem('100')self.tableWidget.setItem(1, 2, newItem)newItem = QTableWidgetItem('小紅')self.tableWidget.setItem(2, 0, newItem)newItem = QTableWidgetItem('女')self.tableWidget.setItem(2, 1, newItem)newItem = QTableWidgetItem('90')self.tableWidget.setItem(2, 2, newItem)# 設置允許彈出上下文你菜單self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)# 信號與槽self.tableWidget.customContextMenuRequested.connect(self.generateMenu)layout.addWidget(self.tableWidget)self.setLayout(layout)def generateMenu(self, pos):print('pos=', pos)for i in self.tableWidget.selectionModel().selection().indexes():rowNum = i.row()print('選擇了第%d行' % (rowNum + 1))# 如果選擇的行索引小于2,彈出上下文菜單if rowNum < 2:menu = QMenu()item1 = menu.addAction('菜單項1') # 一個動作# print(type(item1))item2 = menu.addAction('菜單項2')item3 = menu.addAction('菜單項3')# pos是相對于整個屏幕的坐標,所以要轉換為窗口坐標screenPos = self.tableWidget.mapToGlobal(pos)print('screenPos=', screenPos)# 被阻塞action = menu.exec_(screenPos)if action == item1:print('選擇了第一個菜單項', self.tableWidget.item(rowNum, 0).text(),self.tableWidget.item(rowNum, 1).text(),self.tableWidget.item(rowNum, 2).text())elif action == item2:print('選擇了第二個菜單項', self.tableWidget.item(rowNum, 0).text(),self.tableWidget.item(rowNum, 1).text(),self.tableWidget.item(rowNum, 2).text())elif action == item3:print('選擇了第三個菜單項', self.tableWidget.item(rowNum, 0).text(),self.tableWidget.item(rowNum, 1).text(),self.tableWidget.item(rowNum, 2).text())else:returnif __name__ == '__main__':app = QApplication(sys.argv)main = CellImageSize()main.show()sys.exit(app.exec_())

?課時78 樹控件(QTreeWidget)的基本用法

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:00 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class BasicTreeWidget(QMainWindow):def __init__(self, parent=None):super(BasicTreeWidget, self).__init__(parent)self.setWindowTitle('樹控件(QTreeWidget)的基本用法')self.resize(500, 300)# 樹self.tree = QTreeWidget()# 為樹控件指定列數self.tree.setColumnCount(2)# 指定列標簽self.tree.setHeaderLabels(['Key', 'Value'])# 根節點root = QTreeWidgetItem(self.tree)root.setText(0, '根節點') # 0代表第一列,即Key列root.setIcon(0, QIcon('./and.png')) # 為節點設置圖標self.tree.setColumnWidth(0, 200) # 第一列列寬設為200# 添加子節點1child1 = QTreeWidgetItem(root)child1.setText(0, '子節點1') # 第一列Key為 子節點1child1.setText(1, '子節點1的數據') # 第二列Value為 子節點1的數據child1.setIcon(0, QIcon('./and.png'))# 設置子節點1開啟復選框狀態child1.setCheckState(0, Qt.Checked)# 添加子節點2child2 = QTreeWidgetItem(root)child2.setText(0, '子節點2')child2.setIcon(0, QIcon('./and.png'))# 為child2添加一個子節點child3 = QTreeWidgetItem(child2)child3.setText(0, '子節點2-1')child3.setText(1, '新的值')child3.setIcon(0, QIcon('./and.png'))# 默認所有節點都處于展開狀態self.tree.expandAll()# 將樹控件設為中心控件,即樹控件會自動鋪滿整個屏幕self.setCentralWidget(self.tree)if __name__ == '__main__':app = QApplication(sys.argv)main = BasicTreeWidget()main.show()sys.exit(app.exec_())

課時79 為樹節點添加響應事件

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:08 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class TreeEvent(QMainWindow):def __init__(self, parent=None):super(TreeEvent, self).__init__(parent)self.setWindowTitle('為樹添加響應事件')self.resize(400, 300)# 樹self.tree = QTreeWidget()# 為樹控件指定列數self.tree.setColumnCount(2)# 指定列標簽self.tree.setHeaderLabels(['Key', 'Value'])# 根節點root = QTreeWidgetItem(self.tree)root.setText(0, 'root') # 0代表第一列,即Key列,值為rootroot.setText(1, '0')# 添加子節點child1child1 = QTreeWidgetItem(root)child1.setText(0, 'child1')child1.setText(1, '1')# 添加子節點child2child2 = QTreeWidgetItem(root)child2.setText(0, 'child2')child2.setText(1, '2')# 為child2添加一個子節點child3child3 = QTreeWidgetItem(child2)child3.setText(0, 'child3')child3.setText(1, '3')# 信號和槽self.tree.clicked.connect(self.onTreeClicked)# 將樹控件設為中心控件,即樹控件會自動鋪滿整個屏幕self.setCentralWidget(self.tree)def onTreeClicked(self, index): # index是被點擊節點的索引item = self.tree.currentItem() # 獲得當前單擊項print('當前處于第%d行' % index.row()) # 輸出當前行(自己父節點的第幾個值)print('key=%s,value=%s' % (item.text(0), item.text(1)))print()if __name__ == '__main__':app = QApplication(sys.argv)main = TreeEvent()main.show()sys.exit(app.exec_())

?課時 80 增加,修改和刪除樹控件的節點

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:14 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class ModifyTree(QWidget):def __init__(self, parent=None):super(ModifyTree, self).__init__(parent)self.setWindowTitle('增加修改和刪除樹控件中的節點')self.resize(400, 300)operatorLayout = QHBoxLayout() # 水平布局addBtn = QPushButton('添加節點')updateBtn = QPushButton('修改節點')deleteBtn = QPushButton('刪除節點')operatorLayout.addWidget(addBtn)operatorLayout.addWidget(updateBtn)operatorLayout.addWidget(deleteBtn)addBtn.clicked.connect(self.addNode)updateBtn.clicked.connect(self.updateNode)deleteBtn.clicked.connect(self.deleteNode)# 樹self.tree = QTreeWidget()# 為樹控件指定列數self.tree.setColumnCount(2)# 指定列標簽self.tree.setHeaderLabels(['Key', 'Value'])# 根節點root = QTreeWidgetItem(self.tree)root.setText(0, 'root') # 0代表第一列,即Key列,值為rootroot.setText(1, '0')# 添加子節點child1child1 = QTreeWidgetItem(root)child1.setText(0, 'child1')child1.setText(1, '1')# 添加子節點child2child2 = QTreeWidgetItem(root)child2.setText(0, 'child2')child2.setText(1, '2')# 為child2添加一個子節點child3child3 = QTreeWidgetItem(child2)child3.setText(0, 'child3')child3.setText(1, '3')# 信號和槽self.tree.clicked.connect(self.onTreeClicked)mainLayout = QVBoxLayout(self)mainLayout.addLayout(operatorLayout)mainLayout.addWidget(self.tree)self.setLayout(mainLayout)def onTreeClicked(self, index): # index是被點擊節點的索引item = self.tree.currentItem() # 獲得當前單擊項print('當前處于第%d行' % index.row()) # 輸出當前行(自己父節點的第幾個值)print('key=%s,value=%s' % (item.text(0), item.text(1)))print()def addNode(self):print('添加節點')item = self.tree.currentItem() # 獲得當前節點print('當前節點是:', item)node = QTreeWidgetItem(item)node.setText(0, '新節點')node.setText(1, '新值')def updateNode(self):print('修改節點')item = self.tree.currentItem()item.setText(0, '修改節點')item.setText(1, '值已經被修改')def deleteNode(self):print('刪除節點')# 防止item是root時,root無父結點報錯,要使用下面的寫法rootFather = self.tree.invisibleRootItem() # 獲得根節點root的不可見的父節點for item in self.tree.selectedItems():# 父節點不為空(item.parent() or rootFather).removeChild(item)if __name__ == '__main__':app = QApplication(sys.argv)main = ModifyTree()main.show()sys.exit(app.exec_())

課時81 QTreeView控件與系統定制模式

一般復雜的樹控件用QTreeView來寫

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:21 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *if __name__ == '__main__':app = QApplication(sys.argv)# 顯示目錄結構的模型model = QDirModel()tree = QTreeView()tree.setModel(model)tree.setWindowTitle('QTreeView')tree.resize(600, 400)tree.show()sys.exit(app.exec_())

課時82 選項卡控件(QTabWidget)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:25 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class TabWidget(QTabWidget): # 直接一整個屏幕就是一個選項卡窗口def __init__(self, parent=None):super(TabWidget, self).__init__(parent)self.setWindowTitle('選項卡控件:QTabWidget')self.resize(400, 200)# 創建用于顯示控件的窗口self.tab1 = QWidget()self.tab2 = QWidget()self.tab3 = QWidget()# 將窗口和選項卡綁定self.addTab(self.tab1, '選項卡1')self.addTab(self.tab2, '選項卡2')self.addTab(self.tab3, '選項卡3')self.tab1UI()self.tab2UI()self.tab3UI()def tab1UI(self):# 表單布局layout = QFormLayout()layout.addRow('姓名', QLineEdit())layout.addRow('地址', QLineEdit())# 將第一個選項卡窗口重命名self.setTabText(0, '聯系方式')self.tab1.setLayout(layout) # 別忘了tab1就是一個窗口def tab2UI(self):layout = QFormLayout()sex = QHBoxLayout() # 水平布局,橫向排列# 單選框sex.addWidget(QRadioButton('男'))sex.addWidget(QRadioButton('女'))layout.addRow(QLabel('性別'), sex)layout.addRow('生日', QLineEdit())self.setTabText(1, '個人詳細信息')self.tab2.setLayout(layout)def tab3UI(self):layout = QHBoxLayout()layout.addWidget(QLabel('科目'))# 復選框layout.addWidget(QCheckBox('物理'))layout.addWidget(QCheckBox('高數'))self.setTabText(2, '教育程度')self.tab3.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = TabWidget()main.show()sys.exit(app.exec_())

?課時83 堆棧窗口控件(QStackedWidget)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:30 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class StackedExample(QWidget): # 直接一整個屏幕就是一個選項卡窗口def __init__(self, parent=None):super(StackedExample, self).__init__(parent)self.setWindowTitle('堆棧窗口控件:QStackedWidget')# self.resize(400,200)self.setGeometry(800, 450, 10, 10)# 列表控件self.list = QListWidget()self.list.insertItem(0, '聯系方式')self.list.insertItem(1, '個人信息')self.list.insertItem(2, '教育程度')self.stack1 = QWidget()self.stack2 = QWidget()self.stack3 = QWidget()self.tab1UI()self.tab2UI()self.tab3UI()# 堆棧窗口控件對象self.stack = QStackedWidget()self.stack.addWidget(self.stack1)self.stack.addWidget(self.stack2)self.stack.addWidget(self.stack3)self.list.currentRowChanged.connect(self.display)hbox = QHBoxLayout()hbox.addWidget(self.list)hbox.addWidget(self.stack)self.setLayout(hbox)def tab1UI(self):# 表單布局layout = QFormLayout()layout.addRow('姓名', QLineEdit())layout.addRow('地址', QLineEdit())self.stack1.setLayout(layout) # 別忘了tab1就是一個窗口def tab2UI(self):layout = QFormLayout()sex = QHBoxLayout() # 水平布局,橫向排列# 單選框sex.addWidget(QRadioButton('男'))sex.addWidget(QRadioButton('女'))layout.addRow(QLabel('性別'), sex)layout.addRow('生日', QLineEdit())self.stack2.setLayout(layout)def tab3UI(self):layout = QHBoxLayout()layout.addWidget(QLabel('科目'))# 復選框layout.addWidget(QCheckBox('物理'))layout.addWidget(QCheckBox('高數'))self.stack3.setLayout(layout)def display(self, index):# 通過索引來切換頁面self.stack.setCurrentIndex(index)if __name__ == '__main__':app = QApplication(sys.argv)main = StackedExample()main.show()sys.exit(app.exec_())

課時84 停靠控件(QDockWidget)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:35 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class DockDemo(QMainWindow): # 直接一整個屏幕就是一個選項卡窗口def __init__(self, parent=None):super(DockDemo, self).__init__(parent)self.setWindowTitle('停靠控件(QDockWidget)')self.setGeometry(800, 450, 500, 500) # x,y,w,h# self.resize(400, 200)layout = QHBoxLayout()# 停靠控件對象self.items = QDockWidget('Dockable', self)# 列表控件self.listWidget = QListWidget()self.listWidget.addItem('item1')self.listWidget.addItem('item2')self.listWidget.addItem('item3')# 將列表放到停靠控件上self.items.setWidget(self.listWidget)self.setCentralWidget(QLineEdit('單行輸入'))# 設置一開始就是懸浮狀態self.items.setFloating(True)# 在窗口上設置停靠控件,且懸浮在右側self.addDockWidget(Qt.RightDockWidgetArea, self.items)if __name__ == '__main__':app = QApplication(sys.argv)main = DockDemo()main.show()sys.exit(app.exec_())

課時85 容納多文檔的窗口

相當于窗口的容器,里面可以有很多子窗口,但子窗口只能在這里面移動。

需要的類:

容納多文檔:QMdiArea
子窗口:?????? QMdiSubWindow

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:44 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class MultiWindows(QMainWindow): # 直接一整個屏幕就是一個選項卡窗口count = 0 # 記錄當前有多少個菜單項def __init__(self, parent=None):super(MultiWindows, self).__init__(parent)self.setWindowTitle('容納多文檔的窗口')self.setGeometry(800, 450, 500, 400) # x,y,w,h# 容納多文檔容器對象self.mdi = QMdiArea()bar = self.menuBar()file = bar.addMenu('File')file.addAction('New')file.addAction('cascade') # 重疊file.addAction('Tiled') # 平鋪file.triggered.connect(self.windowAction)self.setCentralWidget(self.mdi)def windowAction(self, q): # q是當前的單擊菜單項,通過按鈕名來進行不同的操作if q.text() == 'New':self.count = self.count + 1# 子窗口對象sub = QMdiSubWindow()sub.setWidget(QTextEdit())sub.setWindowTitle('子窗口' + str(self.count))self.mdi.addSubWindow(sub)sub.show()# 下面兩個是對mdi中已有的窗口排布進行操作,而不是生成窗口elif q.text() == 'cascade':self.mdi.cascadeSubWindows()elif q.text() == 'Tiled':self.mdi.tileSubWindows()if __name__ == '__main__':app = QApplication(sys.argv)main = MultiWindows()main.show()sys.exit(app.exec_())

課時86 滾動條控件(QScrollBar)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:52 from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * import sysclass ScrollBar(QWidget):def __init__(self):super(ScrollBar, self).__init__()self.initUI()def initUI(self):self.setWindowTitle('滾動條控件演示')self.setGeometry(400, 300, 300, 500)# 水平布局hbox = QHBoxLayout()# 定義控件self.label = QLabel('拖動滾動條去改變文字顏色')self.scrollbar1 = QScrollBar() # 滾動條self.scrollbar1.setMaximum(255) # 滾動條最大值# 信號與槽self.scrollbar1.sliderMoved.connect(self.sliderMoved)self.scrollbar2 = QScrollBar()self.scrollbar2.setMaximum(255)self.scrollbar2.sliderMoved.connect(self.sliderMoved)self.scrollbar3 = QScrollBar()self.scrollbar3.setMaximum(255)self.scrollbar3.sliderMoved.connect(self.sliderMoved)self.scrollbar4 = QScrollBar()self.scrollbar4.setMaximum(255)self.scrollbar4.sliderMoved.connect(self.sliderMoved1)# 向布局中添加控件hbox.addWidget(self.label)hbox.addWidget(self.scrollbar1)hbox.addWidget(self.scrollbar2)hbox.addWidget(self.scrollbar3)hbox.addWidget(self.scrollbar4)self.setLayout(hbox)# 獲得標簽的縱坐標self.y = self.label.pos().y()def sliderMoved(self):print(self.scrollbar1.value(), self.scrollbar2.value(), self.scrollbar3.value())# 調色版palette = QPalette()# 最后一個參數是透明度c = QColor(self.scrollbar1.value(), self.scrollbar2.value(), self.scrollbar3.value(), 255)# 參數一:QPalette.Foreground設置前景色,即標簽的顏色 參數2:顏色palette.setColor(QPalette.Foreground, c)self.label.setPalette(palette)def sliderMoved1(self):# 向下移動標簽self.label.move(self.label.x(), self.y + self.scrollbar4.value())if __name__ == '__main__':app = QApplication(sys.argv)main = ScrollBar()main.show()sys.exit(app.exec_())

課時87 動態顯示當前時間(QTimer)

QTimer定時器,適用于多任務,即每隔一定的時間會調用一次

QThread:完成單個任務可以使用這個

多線程:用于同時完成多個任務

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 10:57 import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import *class showTime(QWidget):def __init__(self, parent=None):super(showTime, self).__init__(parent)self.setWindowTitle('動態顯示當前時間')self.label = QLabel('顯示當前時間')self.startBtn = QPushButton('開始')self.endBtn = QPushButton('結束')# 柵格布局layout = QGridLayout()# 計時器對象self.timer = QTimer()self.timer.timeout.connect(self.showTime)layout.addWidget(self.label, 0, 0, 1, 2) # 占一行兩列layout.addWidget(self.startBtn, 1, 0)layout.addWidget(self.endBtn, 1, 1)self.startBtn.clicked.connect(self.startTimer)self.endBtn.clicked.connect(self.endTimer)self.setLayout(layout)def showTime(self):time = QDateTime.currentDateTime()# dddd是星期幾timeDispaly = time.toString('yyyy-MM-dd hh:mm:ss dddd')# 將標簽設置成當前時間self.label.setText(timeDispaly)def startTimer(self):# 參數是時間間隔,1000毫秒self.timer.start(1000)self.startBtn.setEnabled(False) # 不能按self.endBtn.setEnabled(True) # 可以按def endTimer(self):# 停止計時self.timer.stop()self.startBtn.setEnabled(True)self.endBtn.setEnabled(False)if __name__ == '__main__':app = QApplication(sys.argv)main = showTime()main.show()sys.exit(app.exec_())

?課時88 讓窗口定時關閉

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 11:05 import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import *if __name__ == '__main__':app = QApplication(sys.argv)label = QLabel('<font color=red size=140><b>Hello World,窗口在5秒后自動關閉!</b></font>')# setWindowFlag設置窗口屬性:啟動畫面,無框架label.setWindowFlags(Qt.SplashScreen | Qt.FramelessWindowHint)label.show()# 5秒之后退出整個程序QTimer.singleShot(5000, app.quit)sys.exit(app.exec_())

課時89 使用線程類(QThread)編寫計數器

用到自定義信號,之前用到的信號都是系統已經定義好的,這里需要自己再定義一個。

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 11:09 import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import *# 全局變量,當前計數從0開始 sec = 0class WorkThread(QThread): # 繼承QThread類# 每隔一秒發送一次信號,pyqtSignal()用來定義信號的timer = pyqtSignal()# 計數完成后發送一次信號end = pyqtSignal()def run(self):while True:self.sleep(1) # 休眠一秒if sec == 5:self.end.emit() # 發送end信號,emit()用來發送信號breakself.timer.emit() # 發送timer信號class Counter(QWidget):def __init__(self, parent=None):super(Counter, self).__init__(parent)self.setWindowTitle('使用線程類(QThread)編寫計數器')self.resize(300, 120)layout = QVBoxLayout() # 垂直布局# 數碼管self.lcdNumber = QLCDNumber()layout.addWidget(self.lcdNumber)btn = QPushButton('開始計數')layout.addWidget(btn)self.workThread = WorkThread()self.workThread.timer.connect(self.countTime)self.workThread.end.connect(self.end)btn.clicked.connect(self.work)self.setLayout(layout)def countTime(self):global sec # 聲明一下是全局變量sec += 1self.lcdNumber.display(sec)def end(self):QMessageBox.information(self, '消息', '計數結束', QMessageBox.Ok)def work(self):self.workThread.start()if __name__ == '__main__':app = QApplication(sys.argv)main = Counter()main.show()sys.exit(app.exec_())

課時90 用Web瀏覽器控件(QWebEngineView)顯示網頁

PyQt5和web的交互技術

同時使用Python和web開發程序,混合開發

Python+JavaScript+Html+CSS

運行報錯問題:

from PyQt5.QtWebEngineWidgets import? *
ImportError: DLL load failed while importing QtWebEngineWidgets: 找不到指定的模塊。

參考:(已解決)from PyQt5.QtWebEngineWidgets import *:ImportError: DLL load failed / 找不到指定的模塊_嗨嗨皮皮大bobo的博客-CSDN博客

CSDN和百度了很多

我的解決方案是:將python3.9版本改為3.6版本 想著還是python過高的原因

??右鍵運行

課時91 裝載本地Web頁面

?test.html Html文件

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>測試頁面</title> </head> <body><h1>Hello PyQt5</h1><h2>Hello PyQt5</h2><h3>Hello PyQt5</h3><h4>Hello PyQt5</h4> </body> </html>

localHTML Py文件

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 12:52 import sys import os from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class localHTML(QMainWindow):def __init__(self, parent=None):super(localHTML, self).__init__(parent)self.setWindowTitle('裝載本地Web頁面')self.setGeometry(5, 30, 1355, 730)# os.getcwd()是獲取當前路徑print(os.getcwd())url = os.getcwd() + '/test.html'self.browser = QWebEngineView()# QUrl.fromLocalFile(url)self.browser.load(QUrl.fromLocalFile(url))self.setCentralWidget(self.browser)if __name__ == '__main__':app = QApplication(sys.argv)main = localHTML()main.show()sys.exit(app.exec_())

課時91 顯示嵌入Web頁面

將web頁面的代碼硬編碼到代碼里面,然后顯示

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 12:58 import sys import os from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *class innerHTML(QMainWindow):def __init__(self, parent=None):super(innerHTML, self).__init__(parent)self.setWindowTitle('裝載本地Web頁面')self.setGeometry(5, 30, 1355, 730)self.browser = QWebEngineView()# 直接嵌入頁面源碼self.browser.setHtml(''' <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>測試頁面</title> </head> <body><h1>Hello PyQt5</h1><h2>Hello PyQt5</h2><h3>Hello PyQt5</h3><h4>Hello PyQt5</h4> </body> </html>''')self.setCentralWidget(self.browser)if __name__ == '__main__':app = QApplication(sys.argv)main = innerHTML()main.show()sys.exit(app.exec_())

?課時93 PyQt5調用JavaScript代碼,并返回值

PyQt5和JavaScript交互
什么叫交互
PyQt5 <-> JavaScript

?PyQt5調用JavaScript的函數,然后JavaScript的函數返回了值給PyQt5。

運行結果:功能:分別輸入First name和Last name,然后 PyQt5調用JavaScript的函數,返回全名。

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 13:14 from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtWebEngineWidgets import * import sys import osclass WebEngineView(QWidget):"""PyQt5調用JavaScript代碼PyQt5和JavaScrip交互什么叫交互PyQt5<->JavaScript 即互相調用內部的函數"""def __init__(self):super(WebEngineView, self).__init__()self.setWindowTitle('PyQt5調用JavaScript')self.setGeometry(5, 30, 1355, 730)self.layout = QVBoxLayout()self.setLayout(self.layout)self.browser = QWebEngineView()url = os.getcwd() + '/pyqt5calljs.html'self.browser.load(QUrl.fromLocalFile(url))self.layout.addWidget(self.browser)button = QPushButton('設置全名')button.clicked.connect(self.fullname)self.layout.addWidget(button)# 接受js返回值 即pyqt5calljs.html文件中的fullname函數返回值def js_callback(self, result):print(result)def fullname(self):self.value = 'hello world'self.browser.page().runJavaScript('fullname("' + self.value + '");', self.js_callback)if __name__ == '__main__':app = QApplication(sys.argv)main = WebEngineView()print(main.__doc__)main.show()sys.exit(app.exec_())

課時94 JavaScript調用PyhtonAPI計算階乘

階乘小知識:

階乘是基斯頓·卡曼(Christian Kramp,1760~1826)于 1808 年發明的運算符號,是數學術語。

一個正整數的階乘(factorial)是所有小于及等于該數的正整數的積,并且0的階乘為1。自然數n的階乘寫作n!。1808年,基斯頓·卡曼引進這個表示法。

階乘指從1乘以2乘以3乘以4一直乘到所要求的數。
例如所要求的數是4,則階乘式是1×2×3×4,得到的積是24,24就是4的階乘。 例如所要求的數是6,則階乘式是1×2×3×……×6,得到的積是720,720就是6的階乘。例如所要求的數是n,則階乘式是1×2×3×……×n,設得到的積是x,x就是n的階乘。

將Python的一個對象映射到JavaScript中
將槽函數映射到JavaScript中

總共有四個文件:

文件1????????pyqt5calljs.html

文件2????????js調用py文件(js_call_py.html)

文件3????????階乘功能類(factorial.py)

文件4????????調用類(PyFactorial.py)

?對應的pyqt5calljs.html文件如下:

qwebchannel.js?

/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Copyright (C) 2014 Klar?lvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWebChannel module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** As a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ ** ****************************************************************************/"use strict";var QWebChannelMessageTypes = {signal: 1,propertyUpdate: 2,init: 3,idle: 4,debug: 5,invokeMethod: 6,connectToSignal: 7,disconnectFromSignal: 8,setProperty: 9,response: 10, };var QWebChannel = function(transport, initCallback) {if (typeof transport !== "object" || typeof transport.send !== "function") {console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." +" Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send));return;}var channel = this;this.transport = transport;this.send = function(data){if (typeof(data) !== "string") {data = JSON.stringify(data);}channel.transport.send(data);}this.transport.onmessage = function(message){var data = message.data;if (typeof data === "string") {data = JSON.parse(data);}switch (data.type) {case QWebChannelMessageTypes.signal:channel.handleSignal(data);break;case QWebChannelMessageTypes.response:channel.handleResponse(data);break;case QWebChannelMessageTypes.propertyUpdate:channel.handlePropertyUpdate(data);break;default:console.error("invalid message received:", message.data);break;}}this.execCallbacks = {};this.execId = 0;this.exec = function(data, callback){if (!callback) {// if no callback is given, send directlychannel.send(data);return;}if (channel.execId === Number.MAX_VALUE) {// wrapchannel.execId = Number.MIN_VALUE;}if (data.hasOwnProperty("id")) {console.error("Cannot exec message with property id: " + JSON.stringify(data));return;}data.id = channel.execId++;channel.execCallbacks[data.id] = callback;channel.send(data);};this.objects = {};this.handleSignal = function(message){var object = channel.objects[message.object];if (object) {object.signalEmitted(message.signal, message.args);} else {console.warn("Unhandled signal: " + message.object + "::" + message.signal);}}this.handleResponse = function(message){if (!message.hasOwnProperty("id")) {console.error("Invalid response message received: ", JSON.stringify(message));return;}channel.execCallbacks[message.id](message.data);delete channel.execCallbacks[message.id];}this.handlePropertyUpdate = function(message){for (var i in message.data) {var data = message.data[i];var object = channel.objects[data.object];if (object) {object.propertyUpdate(data.signals, data.properties);} else {console.warn("Unhandled property update: " + data.object + "::" + data.signal);}}channel.exec({type: QWebChannelMessageTypes.idle});}this.debug = function(message){channel.send({type: QWebChannelMessageTypes.debug, data: message});};channel.exec({type: QWebChannelMessageTypes.init}, function(data) {for (var objectName in data) {var object = new QObject(objectName, data[objectName], channel);}// now unwrap properties, which might reference other registered objectsfor (var objectName in channel.objects) {channel.objects[objectName].unwrapProperties();}if (initCallback) {initCallback(channel);}channel.exec({type: QWebChannelMessageTypes.idle});}); };function QObject(name, data, webChannel) {this.__id__ = name;webChannel.objects[name] = this;// List of callbacks that get invoked upon signal emissionthis.__objectSignals__ = {};// Cache of all properties, updated when a notify signal is emittedthis.__propertyCache__ = {};var object = this;// ----------------------------------------------------------------------this.unwrapQObject = function(response){if (response instanceof Array) {// support list of objectsvar ret = new Array(response.length);for (var i = 0; i < response.length; ++i) {ret[i] = object.unwrapQObject(response[i]);}return ret;}if (!response|| !response["__QObject*__"]|| response.id === undefined) {return response;}var objectId = response.id;if (webChannel.objects[objectId])return webChannel.objects[objectId];if (!response.data) {console.error("Cannot unwrap unknown QObject " + objectId + " without data.");return;}var qObject = new QObject( objectId, response.data, webChannel );qObject.destroyed.connect(function() {if (webChannel.objects[objectId] === qObject) {delete webChannel.objects[objectId];// reset the now deleted QObject to an empty {} object// just assigning {} though would not have the desired effect, but the// below also ensures all external references will see the empty map// NOTE: this detour is necessary to workaround QTBUG-40021var propertyNames = [];for (var propertyName in qObject) {propertyNames.push(propertyName);}for (var idx in propertyNames) {delete qObject[propertyNames[idx]];}}});// here we are already initialized, and thus must directly unwrap the propertiesqObject.unwrapProperties();return qObject;}this.unwrapProperties = function(){for (var propertyIdx in object.__propertyCache__) {object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]);}}function addSignal(signalData, isPropertyNotifySignal){var signalName = signalData[0];var signalIndex = signalData[1];object[signalName] = {connect: function(callback) {if (typeof(callback) !== "function") {console.error("Bad callback given to connect to signal " + signalName);return;}object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];object.__objectSignals__[signalIndex].push(callback);if (!isPropertyNotifySignal && signalName !== "destroyed") {// only required for "pure" signals, handled separately for properties in propertyUpdate// also note that we always get notified about the destroyed signalwebChannel.exec({type: QWebChannelMessageTypes.connectToSignal,object: object.__id__,signal: signalIndex});}},disconnect: function(callback) {if (typeof(callback) !== "function") {console.error("Bad callback given to disconnect from signal " + signalName);return;}object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];var idx = object.__objectSignals__[signalIndex].indexOf(callback);if (idx === -1) {console.error("Cannot find connection of signal " + signalName + " to " + callback.name);return;}object.__objectSignals__[signalIndex].splice(idx, 1);if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {// only required for "pure" signals, handled separately for properties in propertyUpdatewebChannel.exec({type: QWebChannelMessageTypes.disconnectFromSignal,object: object.__id__,signal: signalIndex});}}};}/*** Invokes all callbacks for the given signalname. Also works for property notify callbacks.*/function invokeSignalCallbacks(signalName, signalArgs){var connections = object.__objectSignals__[signalName];if (connections) {connections.forEach(function(callback) {callback.apply(callback, signalArgs);});}}this.propertyUpdate = function(signals, propertyMap){// update property cachefor (var propertyIndex in propertyMap) {var propertyValue = propertyMap[propertyIndex];object.__propertyCache__[propertyIndex] = propertyValue;}for (var signalName in signals) {// Invoke all callbacks, as signalEmitted() does not. This ensures the// property cache is updated before the callbacks are invoked.invokeSignalCallbacks(signalName, signals[signalName]);}}this.signalEmitted = function(signalName, signalArgs){invokeSignalCallbacks(signalName, signalArgs);}function addMethod(methodData){var methodName = methodData[0];var methodIdx = methodData[1];object[methodName] = function() {var args = [];var callback;for (var i = 0; i < arguments.length; ++i) {if (typeof arguments[i] === "function")callback = arguments[i];elseargs.push(arguments[i]);}webChannel.exec({"type": QWebChannelMessageTypes.invokeMethod,"object": object.__id__,"method": methodIdx,"args": args}, function(response) {if (response !== undefined) {var result = object.unwrapQObject(response);if (callback) {(callback)(result);}}});};}function bindGetterSetter(propertyInfo){var propertyIndex = propertyInfo[0];var propertyName = propertyInfo[1];var notifySignalData = propertyInfo[2];// initialize property cache with current value// NOTE: if this is an object, it is not directly unwrapped as it might// reference other QObject that we do not know yetobject.__propertyCache__[propertyIndex] = propertyInfo[3];if (notifySignalData) {if (notifySignalData[0] === 1) {// signal name is optimized away, reconstruct the actual namenotifySignalData[0] = propertyName + "Changed";}addSignal(notifySignalData, true);}Object.defineProperty(object, propertyName, {configurable: true,get: function () {var propertyValue = object.__propertyCache__[propertyIndex];if (propertyValue === undefined) {// This shouldn't happenconsole.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__);}return propertyValue;},set: function(value) {if (value === undefined) {console.warn("Property setter for " + propertyName + " called with undefined value!");return;}object.__propertyCache__[propertyIndex] = value;webChannel.exec({"type": QWebChannelMessageTypes.setProperty,"object": object.__id__,"property": propertyIndex,"value": value});}});}// ----------------------------------------------------------------------data.methods.forEach(addMethod);data.properties.forEach(bindGetterSetter);data.signals.forEach(function(signal) { addSignal(signal, false); });for (var name in data.enums) {object[name] = data.enums[name];} }//required for use with nodejs if (typeof module === 'object') {module.exports = {QWebChannel: QWebChannel}; }

?js調用py文件(js_call_py.html)

<html><head><title>A Demo Page</title><meta charset="UTF-8"><script src="./qwebchannel.js"></script><script language="javascript">function callback(result) {alert('計算結果:' + result)}document.addEventListener("DOMContentLoaded", function () {new QWebChannel( qt.webChannelTransport, function(channel) {window.obj = channel.objects.obj;});});function onFactorial() {if ( window.obj) {var n = parseInt(document.getElementById('n').value);window.obj.factorial(n,callback)}}</script></head><body><form><label >請輸入N:</label><input type="text" id="n"></input><br /><input type="button" value="計算階乘" onclick="onFactorial()"></form></body></html>

?階乘功能類(factorial.py)

from PyQt5.QtCore import *class Factorial(QObject):@pyqtSlot(int, result=int)def factorial(self,n):if n == 0 or n == 1:return 1else:return self.factorial(n - 1) * n

調用類(PyFactorial.py)

from PyQt5.QtWebChannel import QWebChannel from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtWebEngineWidgets import * import sys import os from factorial import *channel = QWebChannel() factorial = Factorial() class PyFactorial(QWidget):def __init__(self):super(PyFactorial, self).__init__()self.setWindowTitle('Python計算階乘')self.resize(600,300)layout=QVBoxLayout()self.browser = QWebEngineView()url = os.getcwd() + '/js_call_py.html'#裝載本地html文件self.browser.load(QUrl.fromLocalFile(url))channel.registerObject("obj",factorial)self.browser.page().setWebChannel(channel)layout.addWidget(self.browser)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)win = PyFactorial()win.show()sys.exit(app.exec_())

課時95 絕對布局

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:29 import sys, math from PyQt5.QtWidgets import *class AbsoluteLayout(QWidget):def __init__(self):super(AbsoluteLayout, self).__init__()self.setWindowTitle('絕對布局')self.resize(300, 200)self.label1 = QLabel('歡迎', self)self.label1.move(15, 20)self.label2 = QLabel('學習', self)self.label2.move(35, 40)self.label3 = QLabel('PyQt5', self)self.label3.move(55, 60)self.label4 = QLabel('JavaEE', self)self.label4.move(75, 80)self.label5 = QLabel('Uniapp', self)self.label5.move(95, 100)self.label6 = QLabel('大數據', self)self.label6.move(115, 120)self.label2 = QLabel('區塊鏈', self)self.label2.move(135, 140)if __name__ == '__main__':app = QApplication(sys.argv)main = AbsoluteLayout()main.show()sys.exit(app.exec_())

課時96 水平盒布局(QHBoxLayout)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:34 import sys, math from PyQt5.QtWidgets import *class HBoxLayout(QWidget):def __init__(self):super(HBoxLayout, self).__init__()self.setWindowTitle('水平盒布局')self.resize(300, 200)hlayout = QHBoxLayout()hlayout.addWidget(QPushButton('JavaEE'))hlayout.addWidget(QPushButton('Uniapp'))hlayout.addWidget(QPushButton('大數據'))hlayout.addWidget(QPushButton('區塊鏈'))hlayout.addWidget(QPushButton('人工智能'))# 設置控件之間的間距hlayout.setSpacing(20)self.setLayout(hlayout)if __name__ == '__main__':app = QApplication(sys.argv)main = HBoxLayout()main.show()sys.exit(app.exec_())

課時97 設置控件的對齊方式

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:37 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class HBoxLayout(QWidget):def __init__(self):super(HBoxLayout, self).__init__()self.setWindowTitle('水平盒布局')self.resize(300, 200)hlayout = QHBoxLayout()'''參數二:拉伸量(幾個單位),eg:按鈕1后面有2個單位的拉伸,按鈕2后面有4個單位的拉伸參數三:對齊方式,eg:按鈕1是按照左上方對齊,其他以此類推'''hlayout.addWidget(QPushButton('按鈕1'), 2, Qt.AlignLeft | Qt.AlignTop)hlayout.addWidget(QPushButton('按鈕2'), 4, Qt.AlignLeft | Qt.AlignTop)hlayout.addWidget(QPushButton('按鈕3'), 1, Qt.AlignLeft | Qt.AlignTop)hlayout.addWidget(QPushButton('按鈕4'), 1, Qt.AlignLeft | Qt.AlignBottom)hlayout.addWidget(QPushButton('按鈕5'), 1, Qt.AlignLeft | Qt.AlignBottom)# 設置控件之間的間距hlayout.setSpacing(40)self.setLayout(hlayout)if __name__ == '__main__':app = QApplication(sys.argv)main = HBoxLayout()main.show()sys.exit(app.exec_())

課時98? 垂直盒布局

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:42 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class VBoxLayout(QWidget):def __init__(self):super(VBoxLayout, self).__init__()self.setWindowTitle('垂直盒布局')self.resize(300, 200)hlayout = QVBoxLayout()hlayout.addWidget(QPushButton('JavaEE'))hlayout.addWidget(QPushButton('Uniapp'))hlayout.addWidget(QPushButton('大數據'))hlayout.addWidget(QPushButton('區塊鏈'))hlayout.addWidget(QPushButton('人工智能'))# 設置控件之間的間距hlayout.setSpacing(40)self.setLayout(hlayout)if __name__ == '__main__':app = QApplication(sys.argv)main = VBoxLayout()main.show()sys.exit(app.exec_())

課時99 設置布局的伸縮量

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:45 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class Stretch(QWidget):def __init__(self):super(Stretch, self).__init__()self.setWindowTitle('設置伸縮量')self.resize(800, 100)btn1 = QPushButton(self)btn2 = QPushButton(self)btn3 = QPushButton(self)btn1.setText('JavaEE')btn2.setText('Uniapp')btn3.setText('大數據')layout = QHBoxLayout()# 伸縮量,在水平布局里有講過layout.addStretch(1) # 在按鈕前面添加伸縮單位layout.addWidget(btn1)layout.addStretch(2)layout.addWidget(btn2)layout.addStretch(3)layout.addWidget(btn3)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = Stretch()main.show()sys.exit(app.exec_())

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:47 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class Stretch(QWidget):def __init__(self):super(Stretch, self).__init__()self.setWindowTitle('設置伸縮量')self.resize(1000, 100)btn1 = QPushButton(self)btn2 = QPushButton(self)btn3 = QPushButton(self)btn4 = QPushButton(self)btn5 = QPushButton(self)btn1.setText('JavaEE')btn2.setText('Uniapp')btn3.setText('大數據')btn4.setText('區塊鏈')btn5.setText('人工智能')layout = QHBoxLayout()layout.addStretch(0) # 伸縮量設置為0,是先排列layout.addWidget(btn1)layout.addWidget(btn2)layout.addWidget(btn3)layout.addWidget(btn4)layout.addWidget(btn5)btnOK = QPushButton(self)btnOK.setText('確定')btnCancel = QPushButton(self)btnCancel.setText('取消')layout.addStretch(1)layout.addWidget(btnOK)layout.addWidget(btnCancel)self.setLayout(layout)if __name__ == '__main__':app = QApplication(sys.argv)main = Stretch()main.show()sys.exit(app.exec_())

課時100 讓按鈕永遠在窗口的右下角

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:50 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class RBBtn(QWidget):def __init__(self):super(RBBtn, self).__init__()self.setWindowTitle('讓按鈕永遠在右下角')self.resize(400, 300)okBtn = QPushButton('確定')cancelBtn = QPushButton('取消')hbox = QHBoxLayout()hbox.addStretch(1)hbox.addWidget(okBtn)hbox.addWidget(cancelBtn)vbox = QVBoxLayout()btn1 = QPushButton('按鈕1')btn2 = QPushButton('按鈕2')btn3 = QPushButton('按鈕3')vbox.addStretch(0)vbox.addWidget(btn1)vbox.addWidget(btn2)vbox.addWidget(btn3)vbox.addStretch(1)# 布局之間的疊加,用addLayoutvbox.addLayout(hbox)self.setLayout(vbox)if __name__ == '__main__':app = QApplication(sys.argv)main = RBBtn()main.show()sys.exit(app.exec_())

課時101 柵格布局:用循環方式實現計算器UI

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 14:57 import sys, math from PyQt5.QtWidgets import *class Calc(QWidget):def __init__(self):super(Calc, self).__init__()self.setWindowTitle('柵格布局:用循環方式實現計算器UI')grid = QGridLayout()self.setLayout(grid)names = ['Cls', 'Back', '', 'Close','7', '8', '9', '/','4', '5', '6', '*','1', '2', '3', '-','0', '.', '=', '+']positions = [(i, j) for i in range(5) for j in range(4)]print(positions)#輸出 按鈕名稱和坐標文職# 在元組前面加星號可將元組變成兩個單個的值print(*(1, 2)) # 輸出的不是元組,而是兩個值# zip函數返回一個可迭代的對象,接受多個可迭代的序列,將相應的元素組合成一對元組for position, name in zip(positions, names):if name == '':continue# print(position)# print(name)btn = QPushButton(name)grid.addWidget(btn, *position)if __name__ == '__main__':app = QApplication(sys.argv)main = Calc()main.show()sys.exit(app.exec_())

?課時102 柵格布局:進行表單UI設計

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:09 import sys, math from PyQt5.QtWidgets import *class GridForm(QWidget):def __init__(self):super(GridForm, self).__init__()self.setWindowTitle('柵格布局:進行表單UI設計')# 標簽titleLabel = QLabel('標題')authorLabel = QLabel('作者')contentLabel = QLabel('內容')# 單行輸入titleEdit = QLineEdit()authorEdit = QLineEdit()# 多行輸入contentEdit = QTextEdit()grid = QGridLayout()# 控件間距grid.setSpacing(10)grid.addWidget(titleLabel, 1, 0) # 位置兩個軸都是從0開始,這里沒用而已grid.addWidget(titleEdit, 1, 1)grid.addWidget(authorLabel, 2, 0)grid.addWidget(authorEdit, 2, 1)grid.addWidget(contentLabel, 3, 0)grid.addWidget(contentEdit, 3, 1, 5, 1) # 空間上占五行一列self.setLayout(grid)self.resize(400, 300)if __name__ == '__main__':app = QApplication(sys.argv)main = GridForm()main.show()sys.exit(app.exec_())

課時103 表單布局

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:15 import sys, math from PyQt5.QtWidgets import *class FormLayout(QWidget):def __init__(self):super(FormLayout, self).__init__()self.setWindowTitle('表單布局')self.resize(350, 300)# 標簽titleLabel = QLabel('標題')authorLabel = QLabel('作者')contentLabel = QLabel('內容')# 單行輸入titleEdit = QLineEdit()authorEdit = QLineEdit()# 多行輸入contentEdit = QTextEdit()formLayout = QFormLayout()formLayout.addRow(titleLabel, titleEdit)formLayout.addRow(authorLabel, authorEdit)formLayout.addRow(contentLabel, contentEdit)self.setLayout(formLayout)if __name__ == '__main__':app = QApplication(sys.argv)main = FormLayout()main.show()sys.exit(app.exec_())

課時104 拖動控件之間的邊界(QSplitter)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:16 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import Qtclass Splitter(QWidget):def __init__(self):super(Splitter, self).__init__()self.setWindowTitle('Splitter例子')self.setGeometry(400, 300, 300, 200)topLeft = QFrame()topLeft.setFrameShape(QFrame.StyledPanel) # 面板類型bottom = QFrame()bottom.setFrameShape(QFrame.StyledPanel)splitter1 = QSplitter(Qt.Horizontal) # 水平拖動textEdit = QTextEdit()splitter1.addWidget(topLeft)splitter1.addWidget(textEdit)# 設置里面的控件的初始尺寸,eg:topLeft占100,textEdit占200splitter1.setSizes([100, 200])splitter2 = QSplitter(Qt.Vertical) # 垂直拖動splitter2.addWidget(splitter1)splitter2.addWidget(bottom)hbox = QHBoxLayout()hbox.addWidget(splitter2)self.setLayout(hbox)if __name__ == '__main__':app = QApplication(sys.argv)main = Splitter()main.show()sys.exit(app.exec_())

課時105 信號與槽基礎

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:24 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class Demo(QWidget):def __init__(self):super(Demo, self).__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 300, 100)self.setWindowTitle('信號(Signal)與槽(Slot)')self.btn = QPushButton('我的按鈕', self)self.btn.clicked.connect(self.onClick)def onClick(self):self.btn.setText('信號已經發出')self.btn.setStyleSheet('QPushButton(max-width:500px;min-width:500px)')if __name__ == '__main__':app = QApplication(sys.argv)main = Demo()main.show()sys.exit(app.exec_())

課時106 自定義信號實現對象之間的通信

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:30 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class MyTypeSignal(QObject):# 定義一個信號sendmsg = pyqtSignal(object)# 調用run來實現觸發def run(self):self.sendmsg.emit('Hello PyQt5') # 給槽傳遞一個參數class MySlot(QObject):# 槽函數def get(self, msg):print('信息:' + msg)if __name__ == '__main__':send = MyTypeSignal()slot = MySlot()send.sendmsg.connect(slot.get) # 連接信號與槽函數send.run() # 發送信號# 斷開信號與槽的連接# send.sendmsg.disconnect(slot.get)

課時107 可以傳遞多個參數的信號

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:38 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class MyTypeSignal(QObject):# 定義一個信號sendmsg = pyqtSignal(object)# 發送三個參數的信號sendmsg1 = pyqtSignal(str, int, int)# 調用run來實現觸發def run(self):self.sendmsg.emit('Hello PyQt5') # 給槽傳遞一個參數def run1(self):self.sendmsg1.emit('hello', 3, 4)class MySlot(QObject):# 槽函數def get(self, msg):print('信息:' + msg)def get1(self, msg, a, b):print(msg)print(a + b)if __name__ == '__main__':send = MyTypeSignal()slot = MySlot()send.sendmsg.connect(slot.get) # 連接信號與槽函數send.sendmsg1.connect(slot.get1)send.run() # 發送信號send.run1() # 別忘了調用相應的觸發函數!!!!# 斷開信號與槽的連接# send.sendmsg.disconnect(slot.get)

課時108 為類添加多個信號(重載形式的信號)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:43 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class MultiSignal(QObject):# 無參數signal1 = pyqtSignal()# 有一個整型的參數signal2 = pyqtSignal(int)# 參數一是整型,參數二是字符型signal3 = pyqtSignal(int, str)# 參數是一個列表signal4 = pyqtSignal(list)# 參數是一個字典signal5 = pyqtSignal(dict)# 聲明一個重載版本的信號,中括號之間是或的意思,也就是槽函數可以是兩個參數:int和str類型,也可以是一個參數:str類型signal6 = pyqtSignal([int, str], [str])def __init__(self):super(MultiSignal, self).__init__()self.signal1.connect(self.signalcall1)self.signal2.connect(self.signalcall2)self.signal3.connect(self.signalcall3)self.signal4.connect(self.signalcall4)self.signal5.connect(self.signalcall5)# self.signal6.connect(self.signalcall6)#默認關聯到重構的第一個槽函數上# 為了可讀性,可像下面那樣寫self.signal6[str].connect(self.signalcall6Overload)self.signal6[int, str].connect(self.signalcall6)self.signal1.emit()self.signal2.emit(10)self.signal3.emit(1, 'hello world')self.signal4.emit([1, 2, 3, 4, 5])self.signal5.emit({'name': 'Bill', 'age': 30})self.signal6[str].emit('test')self.signal6[int, str].emit(20, 'mytest')# 槽函數def signalcall1(self):print('signal1 emit')def signalcall2(self, val):print('signa2 emit,value:', val)def signalcall3(self, val, text):print('signa3 emit,value:', val, text)def signalcall4(self, val):print('signa4 emit,value:', val)def signalcall5(self, val):print('signa5 emit,value:', val)def signalcall6(self, val, text):print('signa6 emit,value:', val, text)def signalcall6Overload(self, val):print('signa6 overload emit,value:', val)if __name__ == '__main__':multiSignal = MultiSignal()

課時109 信號與槽的N對N連接與斷開連接

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 15:54 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class NNSignal(QObject):signal1 = pyqtSignal() # 無參數signal2 = pyqtSignal(int)signal3 = pyqtSignal()def __init__(self):super(NNSignal, self).__init__()# 一個信號對應多個槽self.signal1.connect(self.call1)self.signal1.connect(self.call11)self.signal1.emit()# 信號綁定到槽上self.signal2.connect(self.signal1)print('*****************************')self.signal2.emit(2) # 觸發了信號1'''以上操作的運行結果call1 emitcall11 emitcall1 emitcall11 emit'''print('************************************')# 解綁self.signal1.disconnect(self.call1)self.signal1.disconnect(self.call11)self.signal2.disconnect(self.signal1)# 重新綁定self.signal1.connect(self.call1)self.signal2.connect(self.call2)# 一個槽函數綁定到多個信號上self.signal3.connect(self.call1)self.signal1.emit()self.signal2.emit(100)self.signal3.emit()def call1(self):print('call1 emit')def call11(self):print('call11 emit')def call2(self, val):print('call2 emit', val)if __name__ == '__main__':nnSignal = NNSignal()

課時110 為窗口添加信號

本質就是為一個類添加信號,只不過這個類是窗口類

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:02 import sys, math from PyQt5.QtWidgets import * from PyQt5.QtCore import *class WinSignal(QWidget):# 定義一個信號btn_clicked_signal = pyqtSignal()def __init__(self):super(WinSignal, self).__init__()self.setWindowTitle('為窗口添加信號')self.resize(300, 100)btn = QPushButton('關閉窗口', self)btn.clicked.connect(self.btn_clicked)self.btn_clicked_signal.connect(self.btn_close)# 起觸發函數作用的槽函數def btn_clicked(self):self.btn_clicked_signal.emit()# 關閉窗口作用的槽函數def btn_close(self):self.close()if __name__ == '__main__':app = QApplication(sys.argv)main = WinSignal()main.show()sys.exit(app.exec_())

?課時111 多線程更新UI數據

多線程更新UI數據,兩個線程中傳遞數據

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:09 import sys, math import time from PyQt5.QtWidgets import QApplication, QDialog, QLineEdit from PyQt5.QtCore import QThread, pyqtSignal, QDateTimeclass BackendThread(QThread):# 更新日期的信號update_date = pyqtSignal(str)def run(self):while True:date = QDateTime.currentDateTime()currentTime = date.toString('yyyy-MM-dd hh:mm:ss')# 信號參數是當前時間self.update_date.emit(str(currentTime))time.sleep(1) # 隔1s就發送一次信號class ThreadUpdateUI(QDialog):def __init__(self):QDialog.__init__(self)self.setWindowTitle('多線程更新UI數據')self.resize(400, 100)# 存放當前時間self.input = QLineEdit(self)self.input.resize(400, 100)self.initUI()def initUI(self):self.backend = BackendThread()self.backend.update_date.connect(self.handleDisplay)self.backend.start() # 開啟線程,自動調用run# 槽函數是主線程def handleDisplay(self, data): # data是當前時間self.input.setText(data)if __name__ == '__main__':app = QApplication(sys.argv)main = ThreadUpdateUI()main.show()sys.exit(app.exec_())

課時112 信號與槽自動連接

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:22 from PyQt5 import QtCore from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton import sysclass AutoSignalSlot(QWidget):def __init__(self):super(AutoSignalSlot, self).__init__()self.resize(300, 100)self.okBtn = QPushButton('ok', self)self.okBtn1 = QPushButton('cancel', self)# 設置自動連接self.okBtn.setObjectName('okBtn')self.okBtn1.setObjectName('cancelBtn')QtCore.QMetaObject.connectSlotsByName(self)layout = QHBoxLayout()layout.addWidget(self.okBtn)layout.addWidget(self.okBtn1)self.setLayout(layout)# 傳統連接信號與槽# self.okBtn.clicked.connect(self.on_okBtn_clicked)# 命名規則:on_發送者對象(objectname)名稱_發射信號名稱(self,參數)@QtCore.pyqtSlot() # 標注為槽函數,以供自動連接使用def on_okBtn_clicked(self):print('點擊了ok按鈕')@QtCore.pyqtSlot()def on_cancelBtn_clicked(self):print('點擊了cancel按鈕')if __name__ == '__main__':app = QApplication(sys.argv)main = AutoSignalSlot()main.show()sys.exit(app.exec_())

課時113 用Lambda表達式為槽函數傳遞參數

Lambda表達式:匿名函數,也就是沒有名字的函數。

將Lambda賦給一個變量,這個變量就成為了一個函數引用。或者將Lambda表達式作為一個參數傳入函數。

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:32 # Lambda表達式示例 fun = lambda: print('hello world') fun()fun = lambda x, y: print(x, y) fun('a', 'b')from PyQt5.QtWidgets import * import sysclass LambdaSlotArg(QMainWindow):def __init__(self):super(LambdaSlotArg, self).__init__()self.setWindowTitle('用Lambda表達式為槽函數傳遞參數')btn1 = QPushButton('按鈕1')btn2 = QPushButton('按鈕2')ok = 200btn1.clicked.connect(lambda: self.onButtonClick(10, ok))btn2.clicked.connect(lambda: self.onButtonClick(ok, -20))btn1.clicked.connect(lambda: QMessageBox.information(self, '結果', '單擊了btn1'))layout = QHBoxLayout()layout.addWidget(btn1)layout.addWidget(btn2)mainFrame = QWidget()mainFrame.setLayout(layout)self.setCentralWidget(mainFrame)def onButtonClick(self, m, n):print('m+n=', m + n)QMessageBox.information(self, '結果', str(m + n))if __name__ == '__main__':app = QApplication(sys.argv)main = LambdaSlotArg()main.show()sys.exit(app.exec_())

?課時114 用partial對象為槽函數傳遞參數

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:43 from PyQt5.QtWidgets import * from functools import partial import sysclass PartialSlotArg(QMainWindow):def __init__(self):super(PartialSlotArg, self).__init__()self.setWindowTitle('用partial對象為槽函數傳遞參數')btn1 = QPushButton('按鈕1')btn2 = QPushButton('按鈕2')x = 20y = -123btn1.clicked.connect(partial(self.onButtonClick, 10, 20))btn2.clicked.connect(partial(self.onButtonClick, x, y))layout = QHBoxLayout()layout.addWidget(btn1)layout.addWidget(btn2)mainFrame = QWidget()mainFrame.setLayout(layout)self.setCentralWidget(mainFrame)def onButtonClick(self, m, n):print('m+n=', m + n)QMessageBox.information(self, '結果', str(m + n))if __name__ == '__main__':app = QApplication(sys.argv)main = PartialSlotArg()main.show()sys.exit(app.exec_())

課時115 override(覆蓋)槽函數

系統已經定義了很多槽函數,我們能可以覆蓋重寫這些槽函數

我們通過覆蓋keyPressEvent槽函數修改了按ESC和ALT鍵的行為。當我們按ESC的時候,窗口關閉,當按ALT鍵的時候窗口標題修改為"按下了Alt鍵"。

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:49 from PyQt5.QtWidgets import * from PyQt5.QtCore import * import sysclass OverrideSlot(QWidget):def __init__(self):super().__init__()self.setWindowTitle('override(覆蓋)槽函數')# 鍵盤按下的槽函數,不需要連接,系統已經給連接了def keyPressEvent(self, e):# 如果按下Esc鍵,則關閉窗口if e.key() == Qt.Key_Escape:self.close()# 如果按下Alt鍵,修改窗口標題為 按下Alt鍵elif e.key() == Qt.Key_Alt:self.setWindowTitle('按下Alt鍵')if __name__ == '__main__':app = QApplication(sys.argv)main = OverrideSlot()main.show()sys.exit(app.exec_())

?課時116 多窗口交互(1):不使用信號與槽

所謂的交互就是數據的傳遞。不使用信號與槽就是強耦合的方式,即兩個窗口之間相互調用控件。

?

DateDialog.py?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:55 from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import *class DateDialog(QDialog):def __init__(self, parent=None):super(DateDialog, self).__init__(parent)# 當這里面傳入self,相當于 self.setLayout(layout),而且上面的parent必須有layout = QVBoxLayout(self)'''QDateTimeEdit是一個允許用戶編輯日期時間的控件,可以使用鍵盤上的上下鍵頭按鈕來增加或減少日期的時間值,QDateTimeEdit通過setDisplayFormat()函數來設置顯示的日期時間格式'''# 日期時間輸入框self.datetime = QDateTimeEdit(self)# print(isinstance(datetime,DateDialog))# popup (n.) 彈出;彈跳裝置;發射self.datetime.setCalendarPopup(True)# 顯示當前日期self.datetime.setDateTime(QDateTime.currentDateTime())layout.addWidget(self.datetime)# 兩個按鈕buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)# 下面兩個槽函數是系統已經定義好的buttons.accepted.connect(self.accept)# reject (v.)拒絕buttons.rejected.connect(self.reject)layout.addWidget(buttons)def dateTime(self):# 返回當前日期return self.datetime.dateTime()@staticmethod # 靜態方法def getDateTime(parent=None):dialog = DateDialog(parent)# 顯示對話框result = dialog.exec_()date = dialog.dateTime()# print('date.date():',date.date()) #日期:年月日# print('date.time():',date.time())#時間:時分秒# 第三個參數是:是否點擊了okreturn (date.date(), date.time(), result == QDialog.Accepted)

MutilWindow1.py

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 16:57 import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from DateDialog import DateDialogclass MutilWindow1(QWidget):def __init__(self):super(MutilWindow1, self).__init__()self.setWindowTitle('多窗口交互(1):不使用信號與槽')# 單行輸入self.lineEdit = QLineEdit(self)self.btn1 = QPushButton('彈出對話框1')self.btn1.clicked.connect(self.onButton1Click)self.btn2 = QPushButton('彈出對話框2')self.btn2.clicked.connect(self.onButton2Click)# 柵格布局gridLayout = QGridLayout()gridLayout.addWidget(self.lineEdit)gridLayout.addWidget(self.btn1)gridLayout.addWidget(self.btn2)self.setLayout(gridLayout)def onButton1Click(self):dialog = DateDialog(self)result = dialog.exec_()date = dialog.dateTime()self.lineEdit.setText(date.date().toString())# 銷毀窗口dialog.destroy()def onButton2Click(self):date, time, result = DateDialog.getDateTime()self.lineEdit.setText(date.toString())if result == QDialog.Accepted:print('點擊確定按鈕')else:print('點擊取消按鈕')if __name__ == '__main__':app = QApplication(sys.argv)main = MutilWindow1()main.show()sys.exit(app.exec_())

課時117 多窗口交互(2):使用信號與槽

低耦合:
如果一個窗口A與另一個窗口B交互,那么A盡量不要直接訪問B窗口中的控件,
應該在窗口A中訪問B窗口中的信號,并指定與信號綁定的槽函數

例:如果A直接訪問B窗口的控件,一旦B窗口控件發生改變,那么A和B的代碼都需要變化

如果A訪問的是B中的信號,那么B中的控件發生了改變,只需要修改B中的代碼即可。信號就是為此而生

NewDateDialog.py # @CSDN王家視頻教程圖書館 # @Time 2022/11/24 17:40 from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import *class NewDateDialog(QDialog):# 定義一個信號,有一個字符串型的參數Signal_OneParameter = pyqtSignal(str)def __init__(self, parent=None):super(NewDateDialog, self).__init__(parent)self.setWindowTitle('子窗口:用來發射信號')# 在布局中添加部件,垂直布局layout = QVBoxLayout(self)self.label = QLabel(self)self.label.setText('前者發射內置信號\n后者發射自定義信號')# 定義兩個日期時間編輯框self.datetime_inner = QDateTimeEdit(self)# 彈出模式self.datetime_inner.setCalendarPopup(True)# 設置為當前時間self.datetime_inner.setDateTime(QDateTime.currentDateTime())self.datetime_emit = QDateTimeEdit(self)self.datetime_emit.setCalendarPopup(True)self.datetime_emit.setDateTime(QDateTime.currentDateTime())# 放入垂直布局layout.addWidget(self.label)layout.addWidget(self.datetime_inner)layout.addWidget(self.datetime_emit)# 使用兩個button(ok和cancel)分別連接accept()和reject()槽函數buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel,Qt.Horizontal, self)buttons.accepted.connect(self.accept)buttons.rejected.connect(self.reject)layout.addWidget(buttons)self.datetime_emit.dateTimeChanged.connect(self.emit_signal)def emit_signal(self):date_str = self.datetime_emit.dateTime().toString()print(date_str)# 發出信號self.Signal_OneParameter.emit(date_str)

MutilWindow2.py # @CSDN王家視頻教程圖書館 # @Time 2022/11/24 17:40 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * from NewDateDialog import NewDateDialogclass MultiWindow2(QWidget):def __init__(self, parent=None):super(MultiWindow2, self).__init__(parent)self.resize(400, 90)self.setWindowTitle('多窗口交互(2):使用信號與槽')self.open_btn = QPushButton('獲取時間')self.lineEdit_inner = QLineEdit(self)self.lineEdit_emit = QLineEdit(self)self.open_btn.clicked.connect(self.openDialog)self.lineEdit_inner.setText('接收子窗口內置信號的時間')self.lineEdit_emit.setText('接收子窗口自定義信號的時間')grid = QGridLayout()grid.addWidget(self.lineEdit_inner)grid.addWidget(self.lineEdit_emit)grid.addWidget(self.open_btn)self.setLayout(grid)def openDialog(self):dialog = NewDateDialog(self)# dateTimeChanged 是時間改變信號,即手動使日期時間發生改變就會發出信號# 連接子窗口的內置信號與主窗口的槽函數dialog.datetime_inner.dateTimeChanged.connect(self.deal_inner_slot)# 連接子窗口的自定義信號與主窗口的槽函數(推薦用這種)dialog.Signal_OneParameter.connect(self.deal_emit_slot)dialog.show()def deal_inner_slot(self, date):self.lineEdit_inner.setText(date.toString())def deal_emit_slot(self, dateStr):self.lineEdit_emit.setText(dateStr)if __name__ == "__main__":app = QApplication(sys.argv)form = MultiWindow2()form.show()sys.exit(app.exec_())

?課時118 設置窗口中控件的風格

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 18:13 import sys from PyQt5.QtWidgets import * from PyQt5 import QtCore# 窗口可以顯示的風格樣式 print('窗口可以顯示的風格樣式:', QStyleFactory.keys())class WindowStyle(QWidget):def __init__(self):super().__init__()self.setWindowTitle('設置窗口風格')horizontalLayout = QHBoxLayout()self.styleLabel = QLabel('設置窗口風格:')# 下拉框self.styleComboBox = QComboBox()self.styleComboBox.addItems(QStyleFactory.keys())# 獲取當前窗口的風格print('當前窗口的風格:', QApplication.style().objectName())# 獲取當前窗口的風格的索引index = self.styleComboBox.findText(QApplication.style().objectName(), QtCore.Qt.MatchFixedString)# 將下拉框初始設置為當前窗口的風格的名字self.styleComboBox.setCurrentIndex(index)self.styleComboBox.activated[str].connect(self.handleStyleChanged)horizontalLayout.addWidget(self.styleLabel)horizontalLayout.addWidget(self.styleComboBox)self.setLayout(horizontalLayout)def handleStyleChanged(self, style):# 設置風格QApplication.setStyle(style)if __name__ == "__main__":app = QApplication(sys.argv)form = WindowStyle()form.show()sys.exit(app.exec_())

?課時119 設置窗口樣式

setWindowFlags ????????( WindowFlags type )
FrameWindowHint????????沒有邊框的窗口
WindowStaysOnTopHint????????總在最上面的窗口
CustomizeWindowHint????????自定義窗口標題欄,以下標志必須與這個標志一起使用才有效,否則窗口將有默認的標題欄
WindowTitleHint????????顯示窗口標題欄
WindowSystemMenuHint????????顯示系統菜單
WindowMinimizeButtonHint????????顯示最小化按鈕
WindowMaximizeButtonHint????????顯示最大化按鈕
WindowMinMaxButtonsHint????????顯示最小化按鈕和最大化按鈕
WindowCloseButtonHint????????顯示關閉按鈕
setWindowFlags(FramelessWindowHint)????????直接隱藏掉

?課時120 用代碼設置窗口的最大化和最小化

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 18:43 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import *### 自定義窗口類 class WindowMaxMin(QWidget):# 構造函數def __init__(self, parent=None):'''構造函數'''# 調用父類構造函數super(WindowMaxMin, self).__init__(parent)self.resize(300, 400)self.setWindowTitle("用代碼控制窗口的最大化和最小化")self.setWindowFlags(Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowMinMaxButtonsHint)layout = QVBoxLayout()maxButton1 = QPushButton()maxButton1.setText('窗口最大化1 使用自己的方法')maxButton1.clicked.connect(self.maximized1)maxButton2 = QPushButton()maxButton2.setText('窗口最大化2 使用系統提供的方法')maxButton2.clicked.connect(self.showMaximized)minButton = QPushButton()minButton.setText('窗口最小化')minButton.clicked.connect(self.showMinimized)layout.addWidget(maxButton1)layout.addWidget(maxButton2)layout.addWidget(minButton)self.setLayout(layout)def maximized1(self):# 獲得桌面desktop = QApplication.desktop()# 獲取桌面可用尺寸rect = desktop.availableGeometry()self.setGeometry(rect)if __name__ == "__main__":app = QApplication(sys.argv)window = WindowMaxMin()window.show()# 應用程序事件循環sys.exit(app.exec_())

課時121 項目實戰:實現繪圖應用

需要解決3個核心內容
1. 如何繪圖

在paintEvent方法中繪圖,通過調用update方法觸發painEvent的調用

2. 在哪里繪圖

在白色背景的QPixmap對象中繪圖

3. 如何通過移動鼠標進行繪圖

鼠標擁有3個事件:
(1)鼠標按下:mousePressEvent
(2)鼠標移動:mouseMoveEvent
(3)鼠標抬起:mouseReleaseEvent

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 18:57 import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QPainter, QPixmap from PyQt5.QtCore import Qt, QPointclass Drawing(QWidget):def __init__(self, parent=None):super(Drawing, self).__init__(parent)self.setWindowTitle("繪圖應用")self.pix = QPixmap()self.lastPoint = QPoint()self.endPoint = QPoint()self.initUi()def initUi(self):self.resize(600, 600)'''QPixmap 類用于繪圖設備的圖像顯示,可作為一個 QPaintDevice 對象,也可以加載到一個控件中。QPixmap 可以讀取的圖像文件類型有:BMP、GIF、JPG、JPEG、PNG、PBM、PGM、PPM、XBM、XPM 等。'''# 畫布大小為600*600,背景為白色self.pix = QPixmap(600, 600)self.pix.fill(Qt.white)# 下面的方法都是自動調用的def paintEvent(self, event):# 畫筆pp = QPainter(self.pix)# 根據鼠標指針前后兩個位置繪制直線pp.drawLine(self.lastPoint, self.endPoint)# 讓前一個坐標值等于后一個坐標值,# 這樣就能實現畫出連續的線self.lastPoint = self.endPointpainter = QPainter(self)# pixmap (n.)像素映射,象圖# 即先畫在QPixmap上,再從圖像文件中提取 Pixmap 并將其顯示在指定位置painter.drawPixmap(0, 0, self.pix)# 鼠標按下def mousePressEvent(self, event):# 如果鼠標左鍵按下if event.button() == Qt.LeftButton:# 獲得當前坐標self.lastPoint = event.pos()# 鼠標移動def mouseMoveEvent(self, event):# 如果鼠標左鍵一直按著if event.buttons() and Qt.LeftButton:self.endPoint = event.pos()self.update() # 觸發paintEvent# 鼠標抬起def mouseReleaseEvent(self, event):# 鼠標左鍵釋放if event.button() == Qt.LeftButton:self.endPoint = event.pos()# 進行重新繪制self.update() # 每次調用paintEvent都會重新觸發一次if __name__ == "__main__":app = QApplication(sys.argv)form = Drawing()form.show()sys.exit(app.exec_())

課時122? QSS基礎

QSS (Qt Style Sheets)
Qt樣式表
用于設置控件的樣式

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 19:37 from PyQt5.QtWidgets import * import sysclass BasicQSS(QWidget):def __init__(self):super().__init__()self.setWindowTitle("QSS樣式")btn1 = QPushButton(self)btn1.setText("按鈕1")btn2 = QPushButton(self)btn2.setText("按鈕2")btn3 = QPushButton(self)btn3.setText("按鈕3")vbox = QVBoxLayout()vbox.addWidget(btn1)vbox.addWidget(btn2)vbox.addWidget(btn3)self.setLayout(vbox)if __name__ == "__main__":app = QApplication(sys.argv)form = BasicQSS()# 選擇器# 所有的QPushButton控件都設置為背景顏色為紅色qssStyle = '''QPushButton {background-color:red}'''form.setStyleSheet(qssStyle)form.show()sys.exit(app.exec_())

?課時123 使用QSS選擇器設置控件樣式

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 19:41 from PyQt5.QtWidgets import * import sysclass QSSSelector(QWidget):def __init__(self):super().__init__()self.setWindowTitle("QSS樣式")btn1 = QPushButton(self)btn1.setText("按鈕1")btn2 = QPushButton(self)# 設置name屬性,可根據屬性來指定按鈕btn2.setProperty('name', 'btn2')btn2.setText("按鈕2")btn3 = QPushButton(self)btn3.setProperty('name', 'btn3')btn3.setText("按鈕3")vbox = QVBoxLayout()vbox.addWidget(btn1)vbox.addWidget(btn2)vbox.addWidget(btn3)self.setLayout(vbox)if __name__ == "__main__":app = QApplication(sys.argv)form = QSSSelector()# 選擇器# 指定按鈕qssStyle = '''QPushButton[name="btn2"] { background-color:red;color:yellow;height:120;font-size:60px;}QPushButton[name="btn3"] {background-color:blue;color:yellow;height:60;font-size:30px;}'''form.setStyleSheet(qssStyle)form.show()sys.exit(app.exec_())

課時124 QSS子控件選擇器

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 19:46 from PyQt5.QtWidgets import * import sysclass QSSSubControl(QWidget):def __init__(self):super().__init__()self.setWindowTitle("QSS子控件選擇器")combo = QComboBox(self)# 設置下拉框名字combo.setObjectName("myComboBox")combo.addItem("Window")combo.addItem("Linux")combo.addItem("Mac OS X")combo.move(50, 50)# 窗口的尺寸和位置self.setGeometry(250, 200, 320, 150)if __name__ == "__main__":app = QApplication(sys.argv)form = QSSSubControl()'''通過名字來引用,#myComboBox相當于web里通過id來引用drop-down是下拉子控件'''qssStyle = '''QComboBox#myComboBox::drop-down {image:url(./csdnlogo.jpg)}'''form.setStyleSheet(qssStyle)form.show()sys.exit(app.exec_())

課時125 使用QSS為標簽和按鈕添加背景圖

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 19:54 from PyQt5.QtWidgets import * import sysclass LabelButtonBackground(QWidget):def __init__(self):super().__init__()label1 = QLabel(self)# 鼠標放在上面就提示label1.setToolTip('這是一個文本標簽')# QSS方式在label1上設置背景圖label1.setStyleSheet('QLabel{border-image:url(./csdnlogo.jpg);}')label1.setFixedWidth(476)label1.setFixedHeight(259)btn1 = QPushButton(self)btn1.setObjectName('btn1')btn1.setMaximumSize(60, 60)btn1.setMinimumSize(60, 60)# 正常狀態和按下狀態時按鈕圖標不同style = '''#btn1{border-radius:4px;background-image:url('./csdnlogo.jpg');}#btn1:Pressed {background-image:url('./and.png');}'''btn1.setStyleSheet(style)vbox = QVBoxLayout()vbox.addWidget(label1)vbox.addStretch()vbox.addWidget(btn1)self.setLayout(vbox)self.setWindowTitle('使用QSS為標簽和按鈕添加背景圖')if __name__ == "__main__":app = QApplication(sys.argv)form = LabelButtonBackground()form.show()sys.exit(app.exec_())

?課時126 裝載QSS文件

這里報了一個文件找不到的錯誤 目前還沒有解決

QSS文件 style.qss

QMainWindow{border-image:url(./and.png); }QToolTip{border:1px solid rgb(45,45,45);background:white;color:red }

裝載類 CommonHelper.py

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 20:20 #裝載類 class CommonHelper:@staticmethoddef readQSS(style):with open(style,'r') as f:return f.read()

??loadQSS.py

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 20:21 import sys from PyQt5.QtWidgets import * from CommonHelper import CommonHelperclass MainWindow(QMainWindow):def __init__(self, parent=None):super(MainWindow, self).__init__(parent)self.resize(477, 258)self.setWindowTitle("加載QSS文件")btn = QPushButton()btn.setText('裝載QSS文件')# 鼠標放到上面會有提示信息btn.setToolTip('提示文本')vbox = QVBoxLayout()vbox.addWidget(btn)btn.clicked.connect(self.onClick)self.setLayout(vbox)widget = QWidget(self)self.setCentralWidget(widget)widget.setLayout(vbox)def onClick(self):styleFile = './style.qss'qssStyle = CommonHelper.readQSS(styleFile)win.setStyleSheet(qssStyle)if __name__ == "__main__":app = QApplication(sys.argv)win = MainWindow()win.show()sys.exit(app.exec_())

?課時127 三種設置背景色和背景圖片的方式

1. QSS 2. QPalette 3. 直接繪制

方式一 QSS?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 20:50 ''' 使用多種方式設置窗口背景色和背景圖片 1. QSS 2. QPalette 3. 直接繪制 '''import sys from PyQt5.QtWidgets import *app = QApplication(sys.argv) win = QMainWindow() win.setWindowTitle("背景圖片") win.resize(350, 250) win.setObjectName("MainWindow")# 通過QSS動態修改窗口的背景顏色和背景圖片win.setStyleSheet("#MainWindow{border-image:url(./csdnlogo.jpg);}") #win.setStyleSheet("#MainWindow{background-color:yellow}")win.show() sys.exit(app.exec())

?方式二 QPalette

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 20:54 import sysfrom PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import *app = QApplication(sys.argv) win = QMainWindow() win.setWindowTitle("背景圖片") win.resize(350, 250) win.setObjectName("MainWindow")# 通過QPalette設置背景圖片和背景顏色 # palette調色板 palette = QPalette() # 設置畫刷 palette.setBrush(QPalette.Background, QBrush(QPixmap("./csdnlogo.jpg"))) # palette.setColor(QPalette.Background,Qt.red) win.setPalette(palette)win.show() sys.exit(app.exec())

方式三 直接繪制

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 20:57 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import *class Background1(QWidget):def __init__(self):super().__init__()self.setWindowTitle("繪制背景顏色")def paintEvent(self, event):painter = QPainter(self)painter.setBrush(Qt.yellow)painter.drawRect(self.rect())if __name__ == "__main__":app = QApplication(sys.argv)form = Background1()form.show()sys.exit(app.exec_())

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 20:58 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import *class Background2(QWidget):def __init__(self):super().__init__()self.setWindowTitle("繪制背景圖片")def paintEvent(self, event):painter = QPainter(self)pixmap = QPixmap('./csdnlogo.jpg')painter.drawPixmap(self.rect(), pixmap)if __name__ == "__main__":app = QApplication(sys.argv)form = Background2()form.show()sys.exit(app.exec_())

課時127 實現不規則窗口(異形窗口)注意只對windowse系統有效果

通過mask實現異形窗口

需要一張透明的png圖,透明部分被扣出,形成一個非矩形的區域

?

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 21:03 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import *class AbnormityWindow(QWidget):def __init__(self):super().__init__()self.setWindowTitle("異形窗口")self.pix = QBitmap('mask/mask1.png')self.resize(self.pix.size())# 設置掩膜,窗口就是掩膜的形狀self.setMask(self.pix)def paintEvent(self, event):painter = QPainter(self)painter.drawPixmap(0, 0, self.pix.width(), self.pix.height(), QPixmap('./csdnlogo.jpg'))if __name__ == "__main__":app = QApplication(sys.argv)form = AbnormityWindow()form.show()sys.exit(app.exec_())

?課時128 移動和關閉不規則窗口(異形窗口)

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 21:26 import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import *class AbnormityWindow(QWidget):def __init__(self):super().__init__()self.setWindowTitle("異形窗口")self.pix = QBitmap('./mask/mask1.png')self.resize(self.pix.size())self.setMask(self.pix)# 鼠標按下def mousePressEvent(self, event):if event.button() == Qt.LeftButton:# 鼠標按下或抬起標志位self.m_drag = True# 當前單擊點相對于窗口本身的坐標,永遠是正的self.m_DragPosition = event.globalPos() - self.pos()# print(self.m_DragPosition)# 設置光標形狀self.setCursor(QCursor(Qt.OpenHandCursor))'''# 當前單擊點相對于屏幕的坐標,包括標題欄和邊框print(event.globalPos())# 當前單擊點相對于窗口的坐標,忽略標題欄和邊框print(event.pos())'''# 左上角坐標相對于屏幕的坐標,包括標題欄和邊框print(self.pos())# 按下右鍵if event.button() == Qt.RightButton:self.close()# 鼠標移動def mouseMoveEvent(self, QMouseEvent):if Qt.LeftButton and self.m_drag:# 當左鍵移動窗體修改偏移值# QPoint'''實時計算窗口左上角坐標,注意是左上角!!!!!!這個移動是從上次的窗口位置往現在到達的位置移動,所以是現在的globalPos()減去移動之前的單擊點到窗口邊框的距離,就是當前左上角坐標'''self.move(QMouseEvent.globalPos() - self.m_DragPosition)# 鼠標抬起def mouseReleaseEvent(self, QMouseEvent):self.m_drag = False# cursor(n.)光標self.setCursor(QCursor(Qt.ArrowCursor))def paintEvent(self, event):painter = QPainter(self)painter.drawPixmap(0, 0, self.pix.width(), self.pix.height(), QPixmap('./csdnlogo.jpg'))if __name__ == "__main__":app = QApplication(sys.argv)form = AbnormityWindow()form.show()sys.exit(app.exec_())

?課時129 實現異形窗口動畫效果

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 21:48 import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtGui import QPixmap, QPainter, QCursor from PyQt5.QtCore import Qt, QTimerclass AnimationWindows(QWidget):def __init__(self, parent=None):super(AnimationWindows, self).__init__(parent)self.i = 1self.mypix() # 顯示第一張的圖self.timer = QTimer() # 定時器self.timer.setInterval(500) # 即500毫秒換一幀self.timer.timeout.connect(self.timeChange)self.timer.start()# 顯示不規則 picdef mypix(self):# 通過立即調用paintEvent()來直接重新繪制窗口部件self.update()if self.i == 5:self.i = 1self.mypic = {1: './rotate/left.png', 2: "./rotate/top.png", 3: './rotate/right.png',4: './rotate/buttom.png'}self.pix = QPixmap(self.mypic[self.i])self.resize(self.pix.size())# 設置掩膜self.setMask(self.pix.mask())self.dragPosition = Nonedef mousePressEvent(self, event):if event.button() == Qt.LeftButton:self.m_drag = Trueself.m_DragPosition = event.globalPos() - self.pos()# 設置光標形狀self.setCursor(QCursor(Qt.OpenHandCursor))def mouseMoveEvent(self, QMouseEvent):if Qt.LeftButton and self.m_drag:self.move(QMouseEvent.globalPos() - self.m_DragPosition)def mouseReleaseEvent(self, QMouseEvent):self.m_drag = Falseself.setCursor(QCursor(Qt.ArrowCursor))def paintEvent(self, event):painter = QPainter(self)painter.drawPixmap(0, 0, self.pix.width(), self.pix.height(), self.pix)# 鼠標雙擊事件def mouseDoubleClickEvent(self, event):if event.button() == 1:self.i += 1self.mypix()# 每500毫秒修改paint,即換一張圖def timeChange(self):self.i += 1self.mypix()if __name__ == '__main__':app = QApplication(sys.argv)form = AnimationWindows()form.show()sys.exit(app.exec_())

課時130 裝載gif動畫文件

效果暫時沒有顯示出來,后續測試

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 22:08 import sys from PyQt5.QtWidgets import QApplication,QLabel,QWidget from PyQt5.QtCore import Qt from PyQt5.QtGui import QMovieclass loadingGif(QWidget):def __init__(self):super(loadingGif, self).__init__()self.label = QLabel("", self)self.setFixedSize(128, 128)self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint)self.movie = QMovie('../loding2.gif')self.label.setMovie(self.movie)self.movie.start()if __name__ == "__main__":app = QApplication(sys.argv)form = loadingGif()form.show()sys.exit(app.exec_())

課時131 縮放圖片

QImage.scaled

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 22:39 from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout from PyQt5.QtGui import QImage, QPixmap from PyQt5.QtCore import Qt import sysclass ScaleImage(QWidget):def __init__(self):super().__init__()self.setWindowTitle("圖片大小縮放例子")filename = './csdnlogo.jpg'img = QImage(filename)label1 = QLabel(self)label1.setFixedWidth(200)label1.setFixedHeight(200)# 參數三四:忽略比例,平滑顯示result = img.scaled(label1.width(), label1.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)label1.setPixmap(QPixmap.fromImage(result))vbox = QVBoxLayout()vbox.addWidget(label1)self.setLayout(vbox)if __name__ == "__main__":app = QApplication(sys.argv)win = ScaleImage()win.show()sys.exit(app.exec_())

課時132 用動畫效果改變窗口的尺寸

QPropertyAnimation可以控制任何可視控件的尺寸的動態的變化,只要我們把控件的對象通過構造方法傳入即可

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 22:48 from PyQt5.QtCore import * from PyQt5.QtWidgets import * import sysclass AnimWindow(QWidget):def __init__(self):super(AnimWindow, self).__init__()self.OrigHeight = 50self.ChangeHeight = 150self.setGeometry(QRect(500, 400, 150, self.OrigHeight))self.btn = QPushButton('展開', self) # 沒用布局,直接將按鈕放入self.btn.setGeometry(10, 10, 60, 35)self.btn.clicked.connect(self.change)def change(self):currentHeight = self.height()if self.OrigHeight == currentHeight:startHeight = self.OrigHeightendHeight = self.ChangeHeightself.btn.setText('收縮')else:startHeight = self.ChangeHeightendHeight = self.OrigHeightself.btn.setText('展開')self.animation = QPropertyAnimation(self, b'geometry') # 將當前窗口傳入self.animation.setDuration(500) # 間隔時間:500毫秒# 初始尺寸self.animation.setStartValue(QRect(500, 400, 150, startHeight))# 變化后的尺寸self.animation.setEndValue(QRect(500, 400, 150, endHeight))self.animation.start()returnif __name__ == '__main__':app = QApplication(sys.argv)window = AnimWindow()window.show()sys.exit(app.exec_())

課時133用動畫效果以不同速度移動窗口

# @CSDN王家視頻教程圖書館 # @Time 2022/11/24 22:55 from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * import sysapp = QApplication(sys.argv)window1 = QMainWindow() window1.show() window2 = QMainWindow() window2.show()animation1 = QPropertyAnimation(window1, b'geometry') animation2 = QPropertyAnimation(window2, b'geometry')group = QParallelAnimationGroup() # 并行 動畫組 并行,同時運行多個動畫 # group = QSequentialAnimationGroup() # 串行group.addAnimation(animation1) group.addAnimation(animation2)animation1.setDuration(3000) animation1.setStartValue(QRect(0, 0, 100, 30)) animation1.setEndValue(QRect(250, 250, 100, 30)) animation1.setEasingCurve(QEasingCurve.OutBounce) # 動畫特效animation2.setDuration(4000) animation2.setStartValue(QRect(250, 150, 100, 30)) animation2.setEndValue(QRect(850, 250, 100, 30)) animation2.setEasingCurve(QEasingCurve.CosineCurve)group.start()sys.exit(app.exec())

?課時134 用PyInstaller打包PyQt5應用

安裝:pip3 install pyinstaller

代碼:

直接在命令行下操作

常用:pyinstaller -Fw python文件名

pyinstaller -Fw Calc. py
-W:不顯示終端
-F:將所有的庫打包成-個單獨的文件

?pip3 install pyinstaller安裝

使用pyinstaller查看可選參數

開始打包????? pyinstaller -Fw .\ScaleImage.py

打包程序完成


打包成功后項目目錄下多了兩個文件夾,包括build和dist。exe文件就存在于dist目錄下。將文件中調用的文件手動放到exe同目錄下雙擊exe文件運行即可!

課時135 操作SQLite數據庫

#輕量級數據庫,支持多種接口,跨平臺

#現在很多移動應用 安卓 iOS 都使用SQLite作為本地數據庫

#本地數據庫只需要提供文件名,而不需要IP,用戶名,密碼啥的

#數據庫可視化工具DB Browser for SQLite:

#官網:DB Browser for SQLite

#下載:Downloads - DB Browser for SQLite

?右鍵運行生成數據庫db文件

?

課時136 使用可視化的方式對SQLite數據庫進行增刪改查操作

QTableView
QSql TableModel

?

# @CSDN王家視頻教程圖書館 # @Time 2022/11/25 0:27 import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtSql import *# 初始化 def initializeModel(model):model.setTable('people')# 當字段變化時會觸發一些事件model.setEditStrategy(QSqlTableModel.OnFieldChange)# 將整個數據裝載到model中model.select()# 設置字段頭model.setHeaderData(0, Qt.Horizontal, 'ID')model.setHeaderData(1, Qt.Horizontal, '姓名')model.setHeaderData(2, Qt.Horizontal, '地址')# 創建視圖 def createView(title, model):view = QTableView()view.setModel(model)view.setWindowTitle(title)return viewdef findrow(i):# 當前選中的行delrow = i.row()print('del row=%s' % str(delrow))def addrow():# 不是在QTableView上添加,而是在模型上添加,會自動將數據保存到數據庫中!# 參數一:數據庫共有幾行數據 參數二:添加幾行ret = model.insertRows(model.rowCount(), 1) # 返回是否插入print('數據庫共有%d行數據' % model.rowCount())print('insertRow=%s' % str(ret))if __name__ == '__main__':app = QApplication(sys.argv)db = QSqlDatabase.addDatabase('QSQLITE')db.setDatabaseName('./db1.db')model = QSqlTableModel() # MVC模式中的模型delrow = -1# 初始化將數據裝載到模型當中initializeModel(model)view = createView("展示數據", model)view.clicked.connect(findrow)dlg = QDialog()layout = QVBoxLayout()layout.addWidget(view)addBtn = QPushButton('添加一行')addBtn.clicked.connect(addrow)delBtn = QPushButton('刪除一行')delBtn.clicked.connect(lambda: model.removeRow(view.currentIndex().row()))layout.addWidget(view)layout.addWidget(addBtn)layout.addWidget(delBtn)dlg.setLayout(layout)dlg.setWindowTitle("Database Demo")dlg.resize(500, 400)dlg.show()sys.exit(app.exec())

課時137 分頁顯示數據

limit關鍵字

limit n,m

n是起始點(不含),m是偏移量,例如 limit 10,20代表從11開始的20條數據,即11-30

# @CSDN王家視頻教程圖書館 # @Time 2022/11/25 0:58 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt from PyQt5.QtSql import *class DataGrid(QWidget):def createTableAndInit(self):# 添加數據庫self.db = QSqlDatabase.addDatabase('QSQLITE')# 設置數據庫名稱self.db.setDatabaseName('./database.db')# 判斷是否打開if not self.db.open():return False# 聲明數據庫查詢對象query = QSqlQuery()# 創建表query.exec("create table student(id int primary key, name vchar, sex vchar, age int, deparment vchar)")# 添加記錄query.exec("insert into student values(1,'張三1','男',20,'計算機')")query.exec("insert into student values(2,'李四1','男',19,'經管')")query.exec("insert into student values(3,'王五1','男',22,'機械')")query.exec("insert into student values(4,'趙六1','男',21,'法律')")query.exec("insert into student values(5,'小明1','男',20,'英語')")query.exec("insert into student values(6,'小李1','女',19,'計算機')")query.exec("insert into student values(7,'小張1','男',20,'機械')")query.exec("insert into student values(8,'小剛1','男',19,'經管')")query.exec("insert into student values(9,'張三2','男',21,'計算機')")query.exec("insert into student values(10,'張三3','女',20,'法律')")query.exec("insert into student values(11,'王五2','男',19,'經管')")query.exec("insert into student values(12,'張三4','男',20,'計算機')")query.exec("insert into student values(13,'小李2','男',20,'機械')")query.exec("insert into student values(14,'李四2','女',19,'經管')")query.exec("insert into student values(15,'趙六3','男',21,'英語')")query.exec("insert into student values(16,'李四2','男',19,'法律')")query.exec("insert into student values(17,'小張2','女',22,'經管')")query.exec("insert into student values(18,'李四3','男',21,'英語')")query.exec("insert into student values(19,'小李3','女',19,'法律')")query.exec("insert into student values(20,'王五3','女',20,'機械')")query.exec("insert into student values(21,'張三4','男',22,'計算機')")query.exec("insert into student values(22,'小李2','男',20,'法律')")query.exec("insert into student values(23,'張三5','男',19,'經管')")query.exec("insert into student values(24,'小張3','女',20,'計算機')")query.exec("insert into student values(25,'李四4','男',22,'英語')")query.exec("insert into student values(26,'趙六2','男',20,'機械')")query.exec("insert into student values(27,'小李3','女',19,'英語')")query.exec("insert into student values(28,'王五4','男',21,'經管')")return Truedef __init__(self):super().__init__()self.setWindowTitle("分頁查詢例子")self.resize(750, 350)self.createTableAndInit()# 當前頁self.currentPage = 0# 總頁數self.totalPage = 0# 總記錄數self.totalRecrodCount = 0# 每頁顯示記錄數self.PageRecordCount = 6self.initUI()def initUI(self):# 創建窗口self.createWindow()# 設置表格self.setTableView()# 信號槽連接self.prevButton.clicked.connect(self.onPrevButtonClick)self.nextButton.clicked.connect(self.onNextButtonClick)self.switchPageButton.clicked.connect(self.onSwitchPageButtonClick)def closeEvent(self, event):# 關閉數據庫self.db.close()# 創建窗口def createWindow(self):# 操作布局operatorLayout = QHBoxLayout()self.prevButton = QPushButton("前一頁")self.nextButton = QPushButton("后一頁")self.switchPageButton = QPushButton("Go")self.switchPageLineEdit = QLineEdit()self.switchPageLineEdit.setFixedWidth(40)switchPage = QLabel("轉到第")page = QLabel("頁")operatorLayout.addWidget(self.prevButton)operatorLayout.addWidget(self.nextButton)operatorLayout.addWidget(switchPage)operatorLayout.addWidget(self.switchPageLineEdit)operatorLayout.addWidget(page)operatorLayout.addWidget(self.switchPageButton)operatorLayout.addWidget(QSplitter())# 狀態布局statusLayout = QHBoxLayout()self.totalPageLabel = QLabel()self.totalPageLabel.setFixedWidth(70)self.currentPageLabel = QLabel()self.currentPageLabel.setFixedWidth(70)self.totalRecordLabel = QLabel()self.totalRecordLabel.setFixedWidth(70)statusLayout.addWidget(self.totalPageLabel)statusLayout.addWidget(self.currentPageLabel)statusLayout.addWidget(QSplitter())statusLayout.addWidget(self.totalRecordLabel)# 設置表格屬性self.tableView = QTableView()# 表格寬度的自適應調整self.tableView.horizontalHeader().setStretchLastSection(True)self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)# 創建界面mainLayout = QVBoxLayout(self);mainLayout.addLayout(operatorLayout);mainLayout.addWidget(self.tableView);mainLayout.addLayout(statusLayout);self.setLayout(mainLayout)# 設置表格def setTableView(self):# 聲明查詢模型self.queryModel = QSqlQueryModel(self)# 設置當前頁self.currentPage = 1;# 得到總記錄數self.totalRecrodCount = self.getTotalRecordCount()# 得到總頁數self.totalPage = self.getPageCount()# 刷新狀態self.updateStatus()# 設置總頁數文本self.setTotalPageLabel()# 設置總記錄數self.setTotalRecordLabel()# 記錄查詢self.recordQuery(0)# 設置模型self.tableView.setModel(self.queryModel)print('totalRecrodCount=' + str(self.totalRecrodCount))print('totalPage=' + str(self.totalPage))# 設置表格表頭self.queryModel.setHeaderData(0, Qt.Horizontal, "編號")self.queryModel.setHeaderData(1, Qt.Horizontal, "姓名")self.queryModel.setHeaderData(2, Qt.Horizontal, "性別")self.queryModel.setHeaderData(3, Qt.Horizontal, "年齡")self.queryModel.setHeaderData(4, Qt.Horizontal, "院系")# 得到記錄數def getTotalRecordCount(self):self.queryModel.setQuery("select * from student")rowCount = self.queryModel.rowCount()print('rowCount=' + str(rowCount))return rowCount# 得到頁數def getPageCount(self):if self.totalRecrodCount % self.PageRecordCount == 0:return (self.totalRecrodCount / self.PageRecordCount)else:return (self.totalRecrodCount / self.PageRecordCount + 1)# 記錄查詢def recordQuery(self, limitIndex):szQuery = ("select * from student limit %d,%d" % (limitIndex, self.PageRecordCount))print('query sql=' + szQuery)self.queryModel.setQuery(szQuery)# 刷新狀態def updateStatus(self):szCurrentText = ("當前第%d頁" % self.currentPage)self.currentPageLabel.setText(szCurrentText)# 設置按鈕是否可用if self.currentPage == 1:self.prevButton.setEnabled(False)self.nextButton.setEnabled(True)elif self.currentPage == self.totalPage:self.prevButton.setEnabled(True)self.nextButton.setEnabled(False)else:self.prevButton.setEnabled(True)self.nextButton.setEnabled(True)# 設置總數頁文本def setTotalPageLabel(self):szPageCountText = ("總共%d頁" % self.totalPage)self.totalPageLabel.setText(szPageCountText)# 設置總記錄數def setTotalRecordLabel(self):szTotalRecordText = ("共%d條" % self.totalRecrodCount)print('*** setTotalRecordLabel szTotalRecordText=' + szTotalRecordText)self.totalRecordLabel.setText(szTotalRecordText)# 前一頁按鈕按下def onPrevButtonClick(self):print('*** onPrevButtonClick ');limitIndex = (self.currentPage - 2) * self.PageRecordCountself.recordQuery(limitIndex)self.currentPage -= 1self.updateStatus()# 后一頁按鈕按下def onNextButtonClick(self):print('*** onNextButtonClick ');limitIndex = self.currentPage * self.PageRecordCountself.recordQuery(limitIndex)self.currentPage += 1self.updateStatus()# 轉到頁按鈕按下def onSwitchPageButtonClick(self):# 得到輸入字符串szText = self.switchPageLineEdit.text()# 得到頁數pageIndex = int(szText)# 判斷是否有指定頁if pageIndex > self.totalPage or pageIndex < 1:QMessageBox.information(self, "提示", "沒有指定的頁面,請重新輸入")return# 得到查詢起始行號limitIndex = (pageIndex - 1) * self.PageRecordCount# 記錄查詢self.recordQuery(limitIndex);# 設置當前頁self.currentPage = pageIndex# 刷新狀態self.updateStatus();if __name__ == '__main__':app = QApplication(sys.argv)# 創建窗口example = DataGrid()# 顯示窗口example.show()sys.exit(app.exec_())

?課時138 使用PyQtGraph進行數據可視化

首先安裝 pip3 install pyqtgraph

?右鍵運行報錯 暫未解決!

pyqtgraph_pyqt.py

# @CSDN王家視頻教程圖書館 # @Time 2022/11/25 1:15 # -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'pyqtgraph_pyqt.ui' # # Created by: PyQt5 UI code generator 5.9.2 # # WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(800, 600)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.pyqtgraph1 = GraphicsLayoutWidget(self.centralwidget)self.pyqtgraph1.setGeometry(QtCore.QRect(10, 10, 721, 251))self.pyqtgraph1.setObjectName("pyqtgraph1")self.pyqtgraph2 = GraphicsLayoutWidget(self.centralwidget)self.pyqtgraph2.setGeometry(QtCore.QRect(10, 290, 501, 281))self.pyqtgraph2.setObjectName("pyqtgraph2")MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))from pyqtgraph import GraphicsLayoutWidget

Graph.py

# @CSDN王家視頻教程圖書館 # @Time 2022/11/25 1:16 ''' 使用PyQtGraph繪圖 pip Install pyqtgraph '''from PyQt5.QtCore import pyqtSlot from PyQt5.QtWidgets import QMainWindow, QApplication import pyqtgraph as pg from pyqtgraph_pyqt import Ui_MainWindow import numpy as npclass MainWindow(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MainWindow, self).__init__(parent)pg.setConfigOption('background', '#f0f0f0')pg.setConfigOption('foreground', 'd')self.setupUi(self)self.draw1()self.draw2()def draw1(self):self.pyqtgraph1.clear()'''第一種繪圖方式'''print(np.random.normal(size=120))self.pyqtgraph1.addPlot(title="繪圖單條線", y=np.random.normal(size=120), pen=pg.mkPen(color='b', width=2))'''第二種繪圖方式'''plt2 = self.pyqtgraph1.addPlot(title='繪制多條線')plt2.plot(np.random.normal(size=150), pen=pg.mkPen(color='r', width=2),name="Red curve")plt2.plot(np.random.normal(size=110) + 5, pen=(0, 255, 0), name="Green curve")plt2.plot(np.random.normal(size=120) + 10, pen=(0, 0, 255), name="Blue curve")def draw2(self):plt = self.pyqtgraph2.addPlot(title='繪制條狀圖')x = np.arange(10)print(x)y1 = np.sin(x)y2 = 1.1 * np.sin(x + 1)y3 = 1.2 * np.sin(x + 2)bg1 = pg.BarGraphItem(x=x, height=y1, width=0.3, brush='r')bg2 = pg.BarGraphItem(x=x + 0.33, height=y2, width=0.3, brush='g')bg3 = pg.BarGraphItem(x=x + 0.66, height=y3, width=0.3, brush='b')plt.addItem(bg1)plt.addItem(bg2)plt.addItem(bg3)self.pyqtgraph2.nextRow()p4 = self.pyqtgraph2.addPlot(title="參數圖+顯示網格")x = np.cos(np.linspace(0, 2 * np.pi, 1000))y = np.sin(np.linspace(0, 4 * np.pi, 1000))p4.plot(x, y, pen=pg.mkPen(color='d', width=2))# p4.showGrid(x=True, y=True) # 顯示網格if __name__ == "__main__":import sysapp = QApplication(sys.argv)ui = MainWindow()ui.show()sys.exit(app.exec_())

總結

以上是生活随笔為你收集整理的python【PyQt5】的环境搭建和使用(全网最全)其一的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

中文字幕无码av波多野吉衣 | 中文字幕 亚洲精品 第1页 | 亚洲精品久久久久中文第一幕 | 亚洲欧美精品伊人久久 | 国产在线一区二区三区四区五区 | 国产一区二区三区影院 | 日韩精品成人一区二区三区 | 人人爽人人澡人人人妻 | 亚洲国产av美女网站 | 国产午夜福利100集发布 | 99久久亚洲精品无码毛片 | 中文字幕乱码人妻二区三区 | 人妻中文无码久热丝袜 | 老司机亚洲精品影院无码 | 亚洲精品无码国产 | 98国产精品综合一区二区三区 | 精品国精品国产自在久国产87 | 精品 日韩 国产 欧美 视频 | 久久99精品国产麻豆蜜芽 | 牲欲强的熟妇农村老妇女视频 | 中文字幕 人妻熟女 | 国产另类ts人妖一区二区 | 水蜜桃亚洲一二三四在线 | 亚洲自偷自拍另类第1页 | 国产精品第一国产精品 | 国内丰满熟女出轨videos | 中文字幕日韩精品一区二区三区 | 人妻与老人中文字幕 | 国产精品沙发午睡系列 | 性啪啪chinese东北女人 | 国产午夜无码精品免费看 | 国产精品无套呻吟在线 | 在线视频网站www色 | 欧美三级a做爰在线观看 | 激情内射亚州一区二区三区爱妻 | 国产午夜福利亚洲第一 | 欧美真人作爱免费视频 | 蜜臀av无码人妻精品 | 国产精品久久国产精品99 | 丰满肥臀大屁股熟妇激情视频 | 99精品国产综合久久久久五月天 | 久久精品国产日本波多野结衣 | 人妻无码久久精品人妻 | 国产亚洲精品精品国产亚洲综合 | 一本加勒比波多野结衣 | 2019nv天堂香蕉在线观看 | 欧美日韩精品 | 欧美 日韩 亚洲 在线 | 在线播放无码字幕亚洲 | 成人精品视频一区二区 | 一个人看的www免费视频在线观看 | 国产精品内射视频免费 | 亚洲成在人网站无码天堂 | 欧美老人巨大xxxx做受 | 无码av最新清无码专区吞精 | 国产婷婷色一区二区三区在线 | 亚洲精品国偷拍自产在线麻豆 | 国产精品理论片在线观看 | 亚洲自偷自拍另类第1页 | 国产又爽又黄又刺激的视频 | 成人欧美一区二区三区 | 在线精品亚洲一区二区 | 久久久精品国产sm最大网站 | 免费国产成人高清在线观看网站 | 一区二区三区乱码在线 | 欧洲 | 沈阳熟女露脸对白视频 | 精品久久久无码中文字幕 | 曰韩少妇内射免费播放 | 亚洲一区二区三区含羞草 | 国产在线无码精品电影网 | 天天爽夜夜爽夜夜爽 | 最近免费中文字幕中文高清百度 | 日本爽爽爽爽爽爽在线观看免 | 亚洲色大成网站www | 伊人久久大香线焦av综合影院 | 少妇性l交大片欧洲热妇乱xxx | 国产日产欧产精品精品app | 国产成人一区二区三区在线观看 | 激情人妻另类人妻伦 | 久久精品国产一区二区三区肥胖 | 精品 日韩 国产 欧美 视频 | 好屌草这里只有精品 | 国产成人精品三级麻豆 | 婷婷丁香五月天综合东京热 | 性做久久久久久久久 | 97精品国产97久久久久久免费 | 婷婷综合久久中文字幕蜜桃三电影 | 伊人色综合久久天天小片 | 日韩少妇内射免费播放 | 性开放的女人aaa片 | 中文字幕无码av波多野吉衣 | 伊人久久大香线焦av综合影院 | 东京热无码av男人的天堂 | 久久精品人妻少妇一区二区三区 | 又大又紧又粉嫩18p少妇 | 成人精品天堂一区二区三区 | 99久久婷婷国产综合精品青草免费 | 久久久久久九九精品久 | 欧美人与禽猛交狂配 | 久久精品中文字幕一区 | 亚洲精品成人福利网站 | 精品少妇爆乳无码av无码专区 | 人人超人人超碰超国产 | 在线播放免费人成毛片乱码 | 日本熟妇浓毛 | 亚洲乱码日产精品bd | 久青草影院在线观看国产 | 伊在人天堂亚洲香蕉精品区 | 国产免费无码一区二区视频 | 麻豆av传媒蜜桃天美传媒 | 欧美人与动性行为视频 | 又大又硬又爽免费视频 | 日韩av无码一区二区三区 | 国产一精品一av一免费 | 国产激情艳情在线看视频 | 亚洲中文字幕va福利 | 久久久久久av无码免费看大片 | 西西人体www44rt大胆高清 | 欧美xxxx黑人又粗又长 | 欧美日本免费一区二区三区 | 国产亲子乱弄免费视频 | 色综合视频一区二区三区 | 最新国产乱人伦偷精品免费网站 | 精品亚洲韩国一区二区三区 | 欧美猛少妇色xxxxx | 日本一区二区三区免费高清 | 波多野结衣一区二区三区av免费 | 99精品视频在线观看免费 | 日韩无码专区 | 强开小婷嫩苞又嫩又紧视频 | 久久久无码中文字幕久... | 国产精品亚洲专区无码不卡 | 无码一区二区三区在线 | 欧美日韩一区二区三区自拍 | 欧美黑人乱大交 | 久久久精品人妻久久影视 | 日产精品高潮呻吟av久久 | 女人和拘做爰正片视频 | 黑人巨大精品欧美黑寡妇 | 一本久久伊人热热精品中文字幕 | 夫妻免费无码v看片 | 日本熟妇浓毛 | 欧美色就是色 | 少妇愉情理伦片bd | 亚洲欧美色中文字幕在线 | 国产精品美女久久久网av | 国产av一区二区三区最新精品 | 内射巨臀欧美在线视频 | 人人爽人人澡人人人妻 | 亚洲中文字幕在线观看 | 丰满岳乱妇在线观看中字无码 | 给我免费的视频在线观看 | 国内精品人妻无码久久久影院蜜桃 | 99久久婷婷国产综合精品青草免费 | 娇妻被黑人粗大高潮白浆 | 天天av天天av天天透 | 亚洲欧洲日本综合aⅴ在线 | 亚洲成a人一区二区三区 | 草草网站影院白丝内射 | 国产成人久久精品流白浆 | 少妇性l交大片 | 国产无遮挡又黄又爽免费视频 | 狠狠色噜噜狠狠狠7777奇米 | 国产办公室秘书无码精品99 | 成人精品天堂一区二区三区 | 中文字幕乱码人妻二区三区 | 55夜色66夜色国产精品视频 | 色欲久久久天天天综合网精品 | 国产午夜亚洲精品不卡下载 | 欧洲熟妇精品视频 | 精品水蜜桃久久久久久久 | 久久亚洲中文字幕精品一区 | 精品国产一区二区三区四区在线看 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲第一无码av无码专区 | 色综合天天综合狠狠爱 | 性欧美熟妇videofreesex | 一个人看的视频www在线 | 国产尤物精品视频 | 色综合视频一区二区三区 | 妺妺窝人体色www婷婷 | 蜜桃视频插满18在线观看 | 天天综合网天天综合色 | 风流少妇按摩来高潮 | 国产激情无码一区二区 | 国产偷抇久久精品a片69 | 精品欧美一区二区三区久久久 | 任你躁国产自任一区二区三区 | 性开放的女人aaa片 | 亚洲国产av美女网站 | 精品国产一区二区三区四区在线看 | 曰韩少妇内射免费播放 | 亚洲精品午夜国产va久久成人 | 欧美亚洲日韩国产人成在线播放 | 国产黄在线观看免费观看不卡 | 亚洲熟熟妇xxxx | 午夜精品久久久内射近拍高清 | 日韩欧美成人免费观看 | 一二三四在线观看免费视频 | 鲁大师影院在线观看 | 粗大的内捧猛烈进出视频 | 精品一区二区三区无码免费视频 | 无码纯肉视频在线观看 | 无码一区二区三区在线 | 国产suv精品一区二区五 | 色老头在线一区二区三区 | 伊人久久婷婷五月综合97色 | 色婷婷香蕉在线一区二区 | 久久综合九色综合欧美狠狠 | 久久久www成人免费毛片 | 日韩在线不卡免费视频一区 | 欧美成人免费全部网站 | 骚片av蜜桃精品一区 | 国产激情精品一区二区三区 | 国产情侣作爱视频免费观看 | 亚洲小说图区综合在线 | 极品尤物被啪到呻吟喷水 | 成人无码精品1区2区3区免费看 | 久久精品99久久香蕉国产色戒 | 久久久婷婷五月亚洲97号色 | 久久精品女人的天堂av | 欧美亚洲日韩国产人成在线播放 | 国产香蕉尹人视频在线 | 国产成人人人97超碰超爽8 | 国产精品.xx视频.xxtv | 国产亚洲精品久久久久久久 | 鲁一鲁av2019在线 | 久久无码中文字幕免费影院蜜桃 | 妺妺窝人体色www婷婷 | 国产精品嫩草久久久久 | 内射后入在线观看一区 | 亚洲日本在线电影 | 亚洲a无码综合a国产av中文 | 大胆欧美熟妇xx | 精品人妻av区 | 熟女体下毛毛黑森林 | 澳门永久av免费网站 | 日本一卡2卡3卡四卡精品网站 | 精品熟女少妇av免费观看 | 性生交大片免费看女人按摩摩 | 婷婷丁香六月激情综合啪 | 久久人人爽人人爽人人片av高清 | 亚洲一区二区三区无码久久 | 日韩人妻无码一区二区三区久久99 | 国产凸凹视频一区二区 | а√天堂www在线天堂小说 | 99在线 | 亚洲 | 国产人妻人伦精品1国产丝袜 | 成人无码精品一区二区三区 | 国产日产欧产精品精品app | 任你躁国产自任一区二区三区 | √天堂中文官网8在线 | 精品人妻人人做人人爽夜夜爽 | 午夜丰满少妇性开放视频 | 亚洲精品无码国产 | 亚洲中文字幕va福利 | 妺妺窝人体色www婷婷 | 亚洲欧洲日本无在线码 | 爱做久久久久久 | 国产熟妇高潮叫床视频播放 | 亚洲区小说区激情区图片区 | 亚洲色大成网站www | 国产肉丝袜在线观看 | av无码不卡在线观看免费 | 丝袜美腿亚洲一区二区 | 亚洲精品国偷拍自产在线观看蜜桃 | 玩弄人妻少妇500系列视频 | 中文字幕乱码人妻无码久久 | 欧美日韩亚洲国产精品 | 欧美激情一区二区三区成人 | 日韩人妻无码中文字幕视频 | 亚洲精品一区二区三区大桥未久 | 成人欧美一区二区三区 | 荫蒂被男人添的好舒服爽免费视频 | 夜精品a片一区二区三区无码白浆 | 精品国产一区av天美传媒 | 激情亚洲一区国产精品 | 51国偷自产一区二区三区 | 亚洲熟妇色xxxxx亚洲 | 久久亚洲日韩精品一区二区三区 | 精品无码国产自产拍在线观看蜜 | 国产精品第一国产精品 | 天天摸天天透天天添 | 乱人伦中文视频在线观看 | 国产成人无码av在线影院 | 国产精品18久久久久久麻辣 | 免费人成在线观看网站 | 久久久国产精品无码免费专区 | 亚洲一区二区三区播放 | 蜜臀av无码人妻精品 | 欧美国产日韩久久mv | 俄罗斯老熟妇色xxxx | 永久免费观看国产裸体美女 | 国产免费久久久久久无码 | 日韩少妇白浆无码系列 | 西西人体www44rt大胆高清 | 老太婆性杂交欧美肥老太 | 无套内谢老熟女 | 亚洲精品一区二区三区婷婷月 | 国产精品亚洲а∨无码播放麻豆 | 蜜臀aⅴ国产精品久久久国产老师 | 日日摸日日碰夜夜爽av | 日本爽爽爽爽爽爽在线观看免 | 特级做a爰片毛片免费69 | 精品久久久无码中文字幕 | 一个人免费观看的www视频 | 人人妻人人澡人人爽欧美精品 | 午夜性刺激在线视频免费 | 久久久久亚洲精品中文字幕 | 久久99精品国产.久久久久 | 亚洲一区av无码专区在线观看 | 国产免费久久久久久无码 | 国产人妻久久精品二区三区老狼 | 国产亚洲精品久久久闺蜜 | 色综合视频一区二区三区 | 日本精品人妻无码77777 天堂一区人妻无码 | 强开小婷嫩苞又嫩又紧视频 | 久久精品国产99久久6动漫 | 人人妻人人澡人人爽人人精品 | 激情爆乳一区二区三区 | 国产精品丝袜黑色高跟鞋 | 天天躁夜夜躁狠狠是什么心态 | 国产一精品一av一免费 | 国产激情无码一区二区app | 久久久久成人精品免费播放动漫 | 精品国产一区二区三区四区 | 人人爽人人澡人人高潮 | 国产精品亚洲专区无码不卡 | 亚洲人成网站免费播放 | 国内少妇偷人精品视频免费 | 亚洲色大成网站www国产 | а√天堂www在线天堂小说 | 大乳丰满人妻中文字幕日本 | 国产一精品一av一免费 | 久久人妻内射无码一区三区 | 亚洲中文字幕无码中文字在线 | 久久久久成人精品免费播放动漫 | 乱人伦人妻中文字幕无码久久网 | 亚洲熟妇色xxxxx欧美老妇y | 无码人妻精品一区二区三区下载 | 国产小呦泬泬99精品 | 99视频精品全部免费免费观看 | 中文字幕人成乱码熟女app | 波多野结衣aⅴ在线 | 国产舌乚八伦偷品w中 | 成人免费视频一区二区 | 熟女少妇人妻中文字幕 | 成熟妇人a片免费看网站 | 四虎国产精品免费久久 | 亚洲综合无码久久精品综合 | 99久久人妻精品免费一区 | 小sao货水好多真紧h无码视频 | 99麻豆久久久国产精品免费 | 一个人看的www免费视频在线观看 | 国产激情艳情在线看视频 | 亚洲成色在线综合网站 | 美女极度色诱视频国产 | 狠狠亚洲超碰狼人久久 | 国产精品第一区揄拍无码 | 亚洲阿v天堂在线 | 女人被男人爽到呻吟的视频 | 熟妇人妻无乱码中文字幕 | 亚洲精品综合五月久久小说 | 少妇性l交大片欧洲热妇乱xxx | 午夜男女很黄的视频 | 少妇无码av无码专区在线观看 | 国产猛烈高潮尖叫视频免费 | 成 人 网 站国产免费观看 | 日本一区二区三区免费高清 | 国产肉丝袜在线观看 | 国产极品美女高潮无套在线观看 | 国产精品嫩草久久久久 | 久久久久久久人妻无码中文字幕爆 | 国产精品久久久久7777 | 波多野结衣av一区二区全免费观看 | 76少妇精品导航 | 亚洲综合久久一区二区 | 亚洲成av人影院在线观看 | 妺妺窝人体色www在线小说 | 一二三四在线观看免费视频 | 女人和拘做爰正片视频 | 国产成人精品久久亚洲高清不卡 | 国产精品a成v人在线播放 | 国产精品久久久久久无码 | 亚洲色大成网站www国产 | 国产精品国产自线拍免费软件 | 一区二区三区乱码在线 | 欧洲 | 妺妺窝人体色www在线小说 | 久久综合网欧美色妞网 | 白嫩日本少妇做爰 | 亚洲综合在线一区二区三区 | 久久精品99久久香蕉国产色戒 | 一本久道久久综合狠狠爱 | 99久久亚洲精品无码毛片 | 国产黄在线观看免费观看不卡 | 老熟女乱子伦 | av在线亚洲欧洲日产一区二区 | 亚洲色欲色欲欲www在线 | 内射老妇bbwx0c0ck | 99精品视频在线观看免费 | 最近免费中文字幕中文高清百度 | 性欧美videos高清精品 | 少妇人妻偷人精品无码视频 | 永久免费精品精品永久-夜色 | 超碰97人人做人人爱少妇 | 国产午夜视频在线观看 | 欧美人妻一区二区三区 | 男女性色大片免费网站 | 国产日产欧产精品精品app | www国产精品内射老师 | 国产九九九九九九九a片 | 国产精品久久精品三级 | 无码国产激情在线观看 | 国产熟女一区二区三区四区五区 | 日韩欧美中文字幕在线三区 | 激情爆乳一区二区三区 | 免费人成网站视频在线观看 | 巨爆乳无码视频在线观看 | 国产热a欧美热a在线视频 | 亚洲中文字幕无码中字 | 日本一卡二卡不卡视频查询 | 久久 国产 尿 小便 嘘嘘 | 欧美日韩一区二区三区自拍 | 国产亚洲精品久久久久久久久动漫 | 99久久久无码国产精品免费 | 欧美亚洲日韩国产人成在线播放 | 51国偷自产一区二区三区 | 丁香啪啪综合成人亚洲 | 女人高潮内射99精品 | 性史性农村dvd毛片 | 少妇的肉体aa片免费 | 欧美怡红院免费全部视频 | 国产av人人夜夜澡人人爽麻豆 | 99麻豆久久久国产精品免费 | 成 人 网 站国产免费观看 | 日本在线高清不卡免费播放 | 亚洲色无码一区二区三区 | 国产艳妇av在线观看果冻传媒 | 色婷婷欧美在线播放内射 | 久久精品女人天堂av免费观看 | 精品午夜福利在线观看 | 欧美三级a做爰在线观看 | 欧美丰满少妇xxxx性 | 四十如虎的丰满熟妇啪啪 | 日韩av无码一区二区三区 | 免费观看的无遮挡av | 午夜福利不卡在线视频 | 人妻插b视频一区二区三区 | www国产亚洲精品久久久日本 | 99在线 | 亚洲 | 中文无码精品a∨在线观看不卡 | 色情久久久av熟女人妻网站 | 99久久久无码国产精品免费 | 国产av无码专区亚洲awww | 精品久久久久香蕉网 | 内射巨臀欧美在线视频 | 秋霞成人午夜鲁丝一区二区三区 | 日日碰狠狠躁久久躁蜜桃 | 熟女少妇人妻中文字幕 | 亚洲爆乳大丰满无码专区 | 亚洲 激情 小说 另类 欧美 | 亚洲啪av永久无码精品放毛片 | 久久 国产 尿 小便 嘘嘘 | 亚洲大尺度无码无码专区 | 老熟女乱子伦 | 亚洲欧美综合区丁香五月小说 | 久激情内射婷内射蜜桃人妖 | 精品无码一区二区三区爱欲 | 无套内谢的新婚少妇国语播放 | 亚洲国产精品成人久久蜜臀 | 日韩 欧美 动漫 国产 制服 | 乱码av麻豆丝袜熟女系列 | 久久久久成人片免费观看蜜芽 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 亚洲爆乳大丰满无码专区 | 人妻少妇精品久久 | 中文字幕久久久久人妻 | 国产成人无码专区 | 四虎国产精品免费久久 | 亚洲一区二区三区四区 | 国产综合在线观看 | 成人精品视频一区二区 | 国产无遮挡吃胸膜奶免费看 | 久久久久免费精品国产 | 欧美日韩综合一区二区三区 | 久久人人爽人人爽人人片av高清 | 中文字幕乱码亚洲无线三区 | 国产精品视频免费播放 | 天海翼激烈高潮到腰振不止 | 性开放的女人aaa片 | 午夜福利电影 | 鲁鲁鲁爽爽爽在线视频观看 | 一本久道高清无码视频 | 国产在热线精品视频 | 亚洲欧美国产精品专区久久 | 欧洲vodafone精品性 | 亚洲精品国产精品乱码不卡 | 日本精品少妇一区二区三区 | 国产在线无码精品电影网 | 亚洲国产成人a精品不卡在线 | 99久久精品午夜一区二区 | 国内综合精品午夜久久资源 | 久久天天躁夜夜躁狠狠 | 人妻尝试又大又粗久久 | 无码人妻丰满熟妇区毛片18 | 国产av无码专区亚洲a∨毛片 | 无码人妻出轨黑人中文字幕 | 一本大道久久东京热无码av | 2019午夜福利不卡片在线 | 免费观看的无遮挡av | 中文久久乱码一区二区 | 国产成人无码av片在线观看不卡 | 51国偷自产一区二区三区 | 日韩少妇白浆无码系列 | 综合网日日天干夜夜久久 | 婷婷六月久久综合丁香 | 中文字幕乱码中文乱码51精品 | 丰满妇女强制高潮18xxxx | 亚洲爆乳精品无码一区二区三区 | 色五月丁香五月综合五月 | 一本大道伊人av久久综合 | 无遮挡啪啪摇乳动态图 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 日本在线高清不卡免费播放 | 18黄暴禁片在线观看 | 无码人妻久久一区二区三区不卡 | 久久精品国产大片免费观看 | 国产精品爱久久久久久久 | 少妇性俱乐部纵欲狂欢电影 | 人人爽人人澡人人人妻 | 亚洲中文字幕无码一久久区 | 乱人伦人妻中文字幕无码 | 国产疯狂伦交大片 | 精品欧美一区二区三区久久久 | 无码午夜成人1000部免费视频 | 18禁止看的免费污网站 | 一本加勒比波多野结衣 | 亚洲中文字幕在线观看 | 丰满肥臀大屁股熟妇激情视频 | 牲欲强的熟妇农村老妇女视频 | 性啪啪chinese东北女人 | 色婷婷久久一区二区三区麻豆 | 国产精品沙发午睡系列 | 国产另类ts人妖一区二区 | 内射后入在线观看一区 | 久久午夜无码鲁丝片午夜精品 | 久久久中文久久久无码 | 午夜精品一区二区三区在线观看 | 中文字幕av伊人av无码av | 欧美一区二区三区视频在线观看 | 女高中生第一次破苞av | 曰本女人与公拘交酡免费视频 | 国精产品一区二区三区 | 乱人伦人妻中文字幕无码久久网 | 亚洲精品一区二区三区大桥未久 | 国产熟妇高潮叫床视频播放 | 精品乱码久久久久久久 | 亚洲日本在线电影 | 国产精品爱久久久久久久 | 久久亚洲中文字幕无码 | 精品无码国产一区二区三区av | 国产亚洲人成a在线v网站 | 波多野结衣av在线观看 | 99re在线播放 | 国产特级毛片aaaaaa高潮流水 | 女人被男人爽到呻吟的视频 | 亚洲欧美色中文字幕在线 | 未满成年国产在线观看 | 老熟妇仑乱视频一区二区 | 激情亚洲一区国产精品 | 九一九色国产 | 国产偷国产偷精品高清尤物 | 亚洲精品成a人在线观看 | 日本又色又爽又黄的a片18禁 | 日本精品人妻无码77777 天堂一区人妻无码 | 国产午夜亚洲精品不卡下载 | 偷窥村妇洗澡毛毛多 | 男女超爽视频免费播放 | 欧美黑人乱大交 | 国产偷国产偷精品高清尤物 | 亚洲一区二区三区在线观看网站 | 樱花草在线社区www | 色五月丁香五月综合五月 | 狠狠色欧美亚洲狠狠色www | 免费人成在线观看网站 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 最近的中文字幕在线看视频 | 亚洲男人av香蕉爽爽爽爽 | 亚洲小说春色综合另类 | 久久精品国产日本波多野结衣 | 国产免费久久精品国产传媒 | 亚洲色偷偷偷综合网 | 无码人中文字幕 | 国产欧美亚洲精品a | 国产精品无码永久免费888 | 国产成人无码专区 | 丰满肥臀大屁股熟妇激情视频 | 国产精品无码一区二区桃花视频 | 高清无码午夜福利视频 | 高清无码午夜福利视频 | 成年女人永久免费看片 | 青青青手机频在线观看 | 国产精品美女久久久 | 蜜臀av在线播放 久久综合激激的五月天 | 麻豆蜜桃av蜜臀av色欲av | 婷婷丁香五月天综合东京热 | 天天做天天爱天天爽综合网 | 国产无套内射久久久国产 | 六月丁香婷婷色狠狠久久 | 亚欧洲精品在线视频免费观看 | 亚洲综合伊人久久大杳蕉 | 亚洲 另类 在线 欧美 制服 | 丝袜美腿亚洲一区二区 | 67194成是人免费无码 | 欧美成人免费全部网站 | 亚洲国产av美女网站 | 水蜜桃av无码 | 久激情内射婷内射蜜桃人妖 | 成 人影片 免费观看 | 日本欧美一区二区三区乱码 | 97夜夜澡人人爽人人喊中国片 | 国产精品久久久av久久久 | 99精品国产综合久久久久五月天 | 自拍偷自拍亚洲精品被多人伦好爽 | 国产97人人超碰caoprom | 久久综合久久自在自线精品自 | 色婷婷香蕉在线一区二区 | 日韩欧美成人免费观看 | 久久久久99精品国产片 | 樱花草在线播放免费中文 | 亚洲国产精品久久久久久 | 欧美黑人乱大交 | 亚洲人成影院在线无码按摩店 | 日日噜噜噜噜夜夜爽亚洲精品 | 久久人人97超碰a片精品 | 国产在线一区二区三区四区五区 | 欧美成人高清在线播放 | 亚洲国产精品久久久久久 | 亚洲午夜无码久久 | 人人爽人人澡人人高潮 | 97精品国产97久久久久久免费 | 性做久久久久久久久 | 亚洲乱码中文字幕在线 | 人人妻人人澡人人爽精品欧美 | 日本护士xxxxhd少妇 | 久久久久人妻一区精品色欧美 | 久久99久久99精品中文字幕 | 欧美高清在线精品一区 | 麻豆av传媒蜜桃天美传媒 | 久久精品国产一区二区三区肥胖 | 国产精品无码一区二区桃花视频 | 日韩 欧美 动漫 国产 制服 | 红桃av一区二区三区在线无码av | 亚洲精品综合五月久久小说 | 国产三级精品三级男人的天堂 | 国产精品成人av在线观看 | 装睡被陌生人摸出水好爽 | 亚洲第一网站男人都懂 | 亚洲成av人片在线观看无码不卡 | 亚洲乱码国产乱码精品精 | 永久黄网站色视频免费直播 | 少妇人妻偷人精品无码视频 | 国产黄在线观看免费观看不卡 | 一个人看的视频www在线 | 夜精品a片一区二区三区无码白浆 | av小次郎收藏 | 国产成人无码av片在线观看不卡 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 2020久久香蕉国产线看观看 | 久久99精品国产.久久久久 | 亚洲一区av无码专区在线观看 | 国模大胆一区二区三区 | 综合人妻久久一区二区精品 | 大胆欧美熟妇xx | 久久国产精品_国产精品 | 国产手机在线αⅴ片无码观看 | 亚洲国产一区二区三区在线观看 | 久久97精品久久久久久久不卡 | 国产精品美女久久久久av爽李琼 | 女人被男人躁得好爽免费视频 | 成人综合网亚洲伊人 | 纯爱无遮挡h肉动漫在线播放 | 亚洲中文字幕无码一久久区 | 欧美 日韩 亚洲 在线 | 麻豆国产人妻欲求不满 | 300部国产真实乱 | 全黄性性激高免费视频 | 黑人粗大猛烈进出高潮视频 | 激情国产av做激情国产爱 | 一本久道久久综合婷婷五月 | 一个人看的www免费视频在线观看 | 中文无码精品a∨在线观看不卡 | 99久久精品国产一区二区蜜芽 | 日韩人妻无码一区二区三区久久99 | 欧美阿v高清资源不卡在线播放 | 国产香蕉尹人综合在线观看 | 熟女体下毛毛黑森林 | 国产日产欧产精品精品app | 国产精品久久久久7777 | 日本丰满熟妇videos | 成在人线av无码免观看麻豆 | 日韩少妇白浆无码系列 | 无遮挡国产高潮视频免费观看 | 国内丰满熟女出轨videos | 国产美女极度色诱视频www | 免费人成在线观看网站 | 欧美性猛交xxxx富婆 | 国产乱人伦av在线无码 | 蜜桃无码一区二区三区 | 无码福利日韩神码福利片 | 人妻少妇精品无码专区动漫 | 亚洲国产精品无码久久久久高潮 | 人人妻人人澡人人爽欧美一区九九 | 国产成人无码av一区二区 | 乱码av麻豆丝袜熟女系列 | 亚洲精品综合五月久久小说 | 日日夜夜撸啊撸 | 欧美国产日韩亚洲中文 | 久久熟妇人妻午夜寂寞影院 | 熟妇女人妻丰满少妇中文字幕 | 成人无码影片精品久久久 | 国产口爆吞精在线视频 | 国产精品二区一区二区aⅴ污介绍 | 国产97色在线 | 免 | 免费观看黄网站 | 国内综合精品午夜久久资源 | 国産精品久久久久久久 | 在线播放免费人成毛片乱码 | 国产情侣作爱视频免费观看 | 在教室伦流澡到高潮hnp视频 | 正在播放东北夫妻内射 | 久久亚洲精品中文字幕无男同 | 久久午夜无码鲁丝片午夜精品 | 日韩人妻少妇一区二区三区 | 日产精品高潮呻吟av久久 | 免费观看黄网站 | 久久久久久久久888 | 成熟人妻av无码专区 | 午夜福利不卡在线视频 | 少妇人妻av毛片在线看 | 日韩精品无码一区二区中文字幕 | 亚洲精品国产品国语在线观看 | 国内精品久久毛片一区二区 | 给我免费的视频在线观看 | 亚洲日本一区二区三区在线 | 国产成人无码一二三区视频 | 亚洲色无码一区二区三区 | 一个人免费观看的www视频 | 东京热男人av天堂 | 人妻互换免费中文字幕 | 欧美一区二区三区视频在线观看 | 欧美激情内射喷水高潮 | 76少妇精品导航 | 黑人巨大精品欧美一区二区 | 中文字幕人妻无码一区二区三区 | 国产女主播喷水视频在线观看 | 玩弄少妇高潮ⅹxxxyw | 少妇人妻偷人精品无码视频 | 精品久久久中文字幕人妻 | 亚洲爆乳大丰满无码专区 | 色五月丁香五月综合五月 | 亚洲精品一区二区三区大桥未久 | 奇米影视7777久久精品人人爽 | 欧美精品在线观看 | 日韩精品无码一本二本三本色 | 久久精品国产日本波多野结衣 | 久久久国产精品无码免费专区 | 日韩精品成人一区二区三区 | 我要看www免费看插插视频 | 精品久久久无码人妻字幂 | 亚洲中文字幕无码中字 | 日本精品人妻无码免费大全 | 少妇高潮一区二区三区99 | 亚洲国产一区二区三区在线观看 | 四虎影视成人永久免费观看视频 | 99视频精品全部免费免费观看 | 精品无码成人片一区二区98 | 久久99精品久久久久久动态图 | 成人无码视频免费播放 | 国产精品成人av在线观看 | 日日天干夜夜狠狠爱 | 樱花草在线社区www | 亚洲欧美国产精品久久 | 久久熟妇人妻午夜寂寞影院 | 婷婷综合久久中文字幕蜜桃三电影 | 国产精品美女久久久久av爽李琼 | 亚洲精品综合五月久久小说 | 伊人久久婷婷五月综合97色 | 老熟妇仑乱视频一区二区 | 东京一本一道一二三区 | 精品一区二区不卡无码av | 理论片87福利理论电影 | 欧美放荡的少妇 | 成年女人永久免费看片 | 国产9 9在线 | 中文 | 中文字幕av伊人av无码av | 色综合久久久无码中文字幕 | 99国产欧美久久久精品 | 亚洲人成网站色7799 | 欧美国产亚洲日韩在线二区 | 一个人看的www免费视频在线观看 | 亚洲区欧美区综合区自拍区 | 亚洲中文字幕成人无码 | 国产97色在线 | 免 | 亚洲中文字幕乱码av波多ji | 国产又爽又猛又粗的视频a片 | 成年美女黄网站色大免费全看 | 无码纯肉视频在线观看 | 欧洲熟妇色 欧美 | a片免费视频在线观看 | 无套内谢的新婚少妇国语播放 | 国产成人无码av片在线观看不卡 | 成人免费视频一区二区 | 国产精品无码成人午夜电影 | 亚洲伊人久久精品影院 | 久久午夜夜伦鲁鲁片无码免费 | 成人片黄网站色大片免费观看 | 国产午夜精品一区二区三区嫩草 | 久久精品国产99久久6动漫 | 亚洲人成无码网www | 精品一区二区不卡无码av | 国产精品久久久久7777 | 亚洲国产精品久久久天堂 | 国产午夜视频在线观看 | 久久zyz资源站无码中文动漫 | 人人妻人人澡人人爽人人精品浪潮 | 久久久精品成人免费观看 | 欧美 日韩 亚洲 在线 | 免费看男女做好爽好硬视频 | 综合激情五月综合激情五月激情1 | 日本又色又爽又黄的a片18禁 | 熟妇人妻无乱码中文字幕 | 国产极品美女高潮无套在线观看 | 午夜福利一区二区三区在线观看 | 综合激情五月综合激情五月激情1 | 亚洲国产精品一区二区美利坚 | 国产午夜无码视频在线观看 | 欧美性生交xxxxx久久久 | 久久久亚洲欧洲日产国码αv | 55夜色66夜色国产精品视频 | 高清无码午夜福利视频 | 国产香蕉97碰碰久久人人 | 亚洲国产欧美在线成人 | 亚洲成av人综合在线观看 | 精品偷自拍另类在线观看 | 中文亚洲成a人片在线观看 | 奇米影视888欧美在线观看 | 国产精品久久福利网站 | 狂野欧美性猛xxxx乱大交 | 少妇性俱乐部纵欲狂欢电影 | 天堂а√在线中文在线 | 久久国产精品萌白酱免费 | 亚洲色欲色欲欲www在线 | 国产黑色丝袜在线播放 | 波多野结衣一区二区三区av免费 | √8天堂资源地址中文在线 | 国产97色在线 | 免 | 日本欧美一区二区三区乱码 | 亚洲精品一区二区三区大桥未久 | 亚洲精品中文字幕久久久久 | 撕开奶罩揉吮奶头视频 | 77777熟女视频在线观看 а天堂中文在线官网 | 久久精品一区二区三区四区 | 久久精品国产一区二区三区 | 亚洲国产一区二区三区在线观看 | 久久久久99精品成人片 | 成人无码影片精品久久久 | 午夜福利试看120秒体验区 | 成人免费视频视频在线观看 免费 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 东京一本一道一二三区 | 亚洲第一无码av无码专区 | 国产精品久久福利网站 | 久久久久久久久888 | 夜夜躁日日躁狠狠久久av | 亚洲国产一区二区三区在线观看 | 色综合久久久无码网中文 | 中文字幕亚洲情99在线 | 精品成在人线av无码免费看 | 精品少妇爆乳无码av无码专区 | 国产精品亚洲专区无码不卡 | 奇米影视7777久久精品 | 国产精品无码久久av | av在线亚洲欧洲日产一区二区 | 性色欲情网站iwww九文堂 | 中文字幕中文有码在线 | 亚洲色欲色欲天天天www | 亚洲gv猛男gv无码男同 | 野外少妇愉情中文字幕 | 丰满诱人的人妻3 | 成人无码影片精品久久久 | 国产精品亚洲综合色区韩国 | 无码人中文字幕 | 一本久道久久综合婷婷五月 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 亚洲人成网站在线播放942 | 国产精品无码一区二区桃花视频 | 色婷婷av一区二区三区之红樱桃 | 性欧美熟妇videofreesex | 亚洲s色大片在线观看 | 国产97色在线 | 免 | 久久久久免费看成人影片 | 亚洲区小说区激情区图片区 | 天堂久久天堂av色综合 | 国产内射爽爽大片视频社区在线 | 香港三级日本三级妇三级 | 久久综合色之久久综合 | 一区二区三区高清视频一 | 国产精品自产拍在线观看 | 国产乱码精品一品二品 | 国产精品-区区久久久狼 | 中文字幕乱妇无码av在线 | 精品久久综合1区2区3区激情 | 国産精品久久久久久久 | 国产真实伦对白全集 | 亚洲国产精品久久人人爱 | 中文字幕人成乱码熟女app | 欧美自拍另类欧美综合图片区 | 强伦人妻一区二区三区视频18 | 亚洲va中文字幕无码久久不卡 | 国产午夜福利100集发布 | 久久亚洲中文字幕精品一区 | 日韩视频 中文字幕 视频一区 | 国产小呦泬泬99精品 | 国产福利视频一区二区 | 综合网日日天干夜夜久久 | 国内少妇偷人精品视频免费 | 国产国产精品人在线视 | 亚洲爆乳大丰满无码专区 | 黑人巨大精品欧美一区二区 | 国产精品成人av在线观看 | 鲁一鲁av2019在线 | av小次郎收藏 | 欧美性猛交xxxx富婆 | 亚洲国产精品久久久天堂 | 无码福利日韩神码福利片 | 亚洲经典千人经典日产 | 国产精品久久久久久无码 | 激情爆乳一区二区三区 | 亚洲成色www久久网站 | 中文字幕av无码一区二区三区电影 | 国产超碰人人爽人人做人人添 | 中文字幕乱码人妻二区三区 | 欧美国产亚洲日韩在线二区 | 无码帝国www无码专区色综合 | 无码人妻久久一区二区三区不卡 | 欧美成人免费全部网站 | 亚洲精品久久久久久一区二区 | 国产成人综合色在线观看网站 | aa片在线观看视频在线播放 | 乌克兰少妇性做爰 | 精品无码国产自产拍在线观看蜜 | 日韩成人一区二区三区在线观看 | 女人高潮内射99精品 | 久久久久久九九精品久 | 国产精品久久久久久亚洲影视内衣 | 久久人人爽人人爽人人片av高清 | 奇米影视7777久久精品 | 无码精品人妻一区二区三区av | 精品国产成人一区二区三区 | 国产精品a成v人在线播放 | 中文字幕色婷婷在线视频 | 欧美熟妇另类久久久久久不卡 | 一区二区三区乱码在线 | 欧洲 | 欧美一区二区三区 | 波多野结衣av在线观看 | 国产无套内射久久久国产 | 欧美国产日产一区二区 | 欧美精品国产综合久久 | 午夜成人1000部免费视频 | 亚洲gv猛男gv无码男同 | 欧美日韩在线亚洲综合国产人 | 美女黄网站人色视频免费国产 | 欧美 丝袜 自拍 制服 另类 | 丰满人妻被黑人猛烈进入 | 国产又粗又硬又大爽黄老大爷视 | 成人免费视频在线观看 | 无码人妻av免费一区二区三区 | 少女韩国电视剧在线观看完整 | 高潮毛片无遮挡高清免费 | 中文字幕人成乱码熟女app | 国产精品沙发午睡系列 | 久久综合九色综合欧美狠狠 | 久久综合久久自在自线精品自 | 鲁大师影院在线观看 | 荫蒂被男人添的好舒服爽免费视频 | 国产熟妇另类久久久久 | 国产精品人人妻人人爽 | 夜精品a片一区二区三区无码白浆 | 亚洲综合久久一区二区 | 亚洲综合无码久久精品综合 | 熟妇女人妻丰满少妇中文字幕 | 亚洲精品一区二区三区在线 | 久久久中文字幕日本无吗 | 久久国产精品二国产精品 | 男女下面进入的视频免费午夜 | 377p欧洲日本亚洲大胆 | 亚洲精品无码人妻无码 | 亚洲s码欧洲m码国产av | 精品无码国产自产拍在线观看蜜 | 日本成熟视频免费视频 | 中文精品久久久久人妻不卡 | аⅴ资源天堂资源库在线 | 无码精品国产va在线观看dvd | 成人无码精品一区二区三区 | 人人妻人人澡人人爽欧美一区九九 | 国产午夜精品一区二区三区嫩草 | 国产成人综合色在线观看网站 | 最近的中文字幕在线看视频 | 日韩亚洲欧美中文高清在线 | 亚洲伊人久久精品影院 | 激情爆乳一区二区三区 | 成人欧美一区二区三区黑人 | 巨爆乳无码视频在线观看 | 99精品视频在线观看免费 | 97夜夜澡人人爽人人喊中国片 | 自拍偷自拍亚洲精品被多人伦好爽 | 久久人妻内射无码一区三区 | 97夜夜澡人人爽人人喊中国片 | 红桃av一区二区三区在线无码av | 亚洲精品一区二区三区四区五区 | 国产卡一卡二卡三 | 无码人妻久久一区二区三区不卡 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 99久久精品午夜一区二区 | 日本护士毛茸茸高潮 | 欧美喷潮久久久xxxxx | 丰满少妇弄高潮了www | 成 人 网 站国产免费观看 | 国产人妻精品午夜福利免费 | 人人超人人超碰超国产 | 无码福利日韩神码福利片 | 久久精品国产日本波多野结衣 | av无码电影一区二区三区 | 国产情侣作爱视频免费观看 | 亚洲精品国产精品乱码视色 | 中文字幕无线码免费人妻 | 成人试看120秒体验区 | 中文字幕久久久久人妻 | 日韩成人一区二区三区在线观看 | 无码人妻少妇伦在线电影 | 亚洲精品一区二区三区婷婷月 | 一本久道久久综合婷婷五月 | 国产偷抇久久精品a片69 | 中国女人内谢69xxxxxa片 | 动漫av一区二区在线观看 | 又粗又大又硬又长又爽 | 乌克兰少妇xxxx做受 | 2020久久超碰国产精品最新 | 日本乱偷人妻中文字幕 | 久久精品丝袜高跟鞋 | 国产农村乱对白刺激视频 | 夫妻免费无码v看片 | 国产绳艺sm调教室论坛 | 久久精品人人做人人综合试看 | 成 人影片 免费观看 | 午夜福利试看120秒体验区 | 亚洲码国产精品高潮在线 | 国产明星裸体无码xxxx视频 | 四虎国产精品免费久久 | 久久97精品久久久久久久不卡 | 中文亚洲成a人片在线观看 | 国产疯狂伦交大片 | 国产深夜福利视频在线 | 免费视频欧美无人区码 | 窝窝午夜理论片影院 | 亚洲国产精品无码一区二区三区 | 亚洲日本一区二区三区在线 | 三上悠亚人妻中文字幕在线 | √8天堂资源地址中文在线 | 激情综合激情五月俺也去 | 国产在线一区二区三区四区五区 | 无码国模国产在线观看 | 亚洲欧洲中文日韩av乱码 | 国产精品va在线观看无码 | 国产激情精品一区二区三区 | 亚洲国产午夜精品理论片 | 伊人久久婷婷五月综合97色 | 久久久精品456亚洲影院 | 国产精品第一国产精品 | 初尝人妻少妇中文字幕 | 国产精品久久久久久亚洲毛片 | 成年女人永久免费看片 | 大肉大捧一进一出视频出来呀 | 1000部啪啪未满十八勿入下载 | 色偷偷人人澡人人爽人人模 | 亚洲国产欧美日韩精品一区二区三区 | 久久久中文字幕日本无吗 | 亚洲欧美国产精品久久 | 亚洲伊人久久精品影院 | 中文字幕av无码一区二区三区电影 | 成人欧美一区二区三区 | 伊人久久大香线焦av综合影院 | 亚洲色偷偷男人的天堂 | 久久午夜夜伦鲁鲁片无码免费 | 奇米影视7777久久精品人人爽 | 国产成人亚洲综合无码 | 成人免费视频在线观看 | 精品水蜜桃久久久久久久 | 欧洲熟妇精品视频 | 亚洲国产成人av在线观看 | 在线精品亚洲一区二区 | 99精品国产综合久久久久五月天 | 蜜臀av在线播放 久久综合激激的五月天 | 无码人妻久久一区二区三区不卡 | 日韩在线不卡免费视频一区 | 国产av一区二区精品久久凹凸 | 成人欧美一区二区三区黑人 | 国产明星裸体无码xxxx视频 | 国产亚洲欧美在线专区 | 国产尤物精品视频 | 成人精品天堂一区二区三区 | 无码人妻出轨黑人中文字幕 | 亚洲热妇无码av在线播放 | 欧洲欧美人成视频在线 | 性色欲网站人妻丰满中文久久不卡 | 一区二区传媒有限公司 | 久久精品99久久香蕉国产色戒 | 亚洲精品国偷拍自产在线麻豆 | 377p欧洲日本亚洲大胆 | 亚洲成a人片在线观看日本 | 亚洲成av人综合在线观看 | 婷婷五月综合激情中文字幕 | 激情国产av做激情国产爱 | 三上悠亚人妻中文字幕在线 | 国产精品手机免费 | 久久五月精品中文字幕 | 一本一道久久综合久久 | 午夜精品一区二区三区在线观看 | 少妇高潮一区二区三区99 | 四虎4hu永久免费 | 日本熟妇人妻xxxxx人hd | 国产网红无码精品视频 | 色综合久久久无码中文字幕 | 亚洲精品国产品国语在线观看 | 夜精品a片一区二区三区无码白浆 | 亚洲热妇无码av在线播放 | 国产欧美亚洲精品a | 久青草影院在线观看国产 | 性开放的女人aaa片 | 亚洲精品成a人在线观看 | 99er热精品视频 | 亚拍精品一区二区三区探花 | 久久国产36精品色熟妇 | 亚洲国产av精品一区二区蜜芽 | 一个人看的视频www在线 | 日日碰狠狠躁久久躁蜜桃 | 中文字幕无码乱人伦 | 欧美黑人巨大xxxxx | 午夜福利试看120秒体验区 | 久久国语露脸国产精品电影 | 无码中文字幕色专区 | 久久熟妇人妻午夜寂寞影院 | 2020久久香蕉国产线看观看 | 水蜜桃亚洲一二三四在线 | 高潮毛片无遮挡高清免费 | 久久精品女人的天堂av | 内射老妇bbwx0c0ck | 精品成在人线av无码免费看 | 妺妺窝人体色www在线小说 | 学生妹亚洲一区二区 | 男女下面进入的视频免费午夜 | 狠狠cao日日穞夜夜穞av | 亚洲日韩av一区二区三区四区 | 正在播放老肥熟妇露脸 | 色欲av亚洲一区无码少妇 | 一二三四在线观看免费视频 | 无码一区二区三区在线观看 | 免费国产成人高清在线观看网站 | 亚洲经典千人经典日产 | 亚洲一区二区三区在线观看网站 | 天堂久久天堂av色综合 | 久久99热只有频精品8 | 香蕉久久久久久av成人 | 水蜜桃亚洲一二三四在线 | 亚洲成a人片在线观看日本 | 福利一区二区三区视频在线观看 | 精品国精品国产自在久国产87 | 精品无码成人片一区二区98 | 亚洲自偷自偷在线制服 | 亚洲熟悉妇女xxx妇女av | 大肉大捧一进一出视频出来呀 | 亚洲最大成人网站 | 国产成人无码区免费内射一片色欲 | 97夜夜澡人人爽人人喊中国片 | 水蜜桃av无码 | 激情人妻另类人妻伦 | 波多野结衣高清一区二区三区 | 亚洲成av人片在线观看无码不卡 | 欧美人与禽猛交狂配 | 国产亚洲精品久久久久久久久动漫 | 精品国产一区二区三区av 性色 | 无套内谢的新婚少妇国语播放 | 亚洲 欧美 激情 小说 另类 | 性啪啪chinese东北女人 | 国产乱人偷精品人妻a片 | 人妻中文无码久热丝袜 | 亚洲一区二区三区播放 | 久久精品国产亚洲精品 | 国产香蕉97碰碰久久人人 | 久久精品国产亚洲精品 | 久久这里只有精品视频9 | 激情五月综合色婷婷一区二区 | 亚洲精品国产精品乱码不卡 | 精品人妻av区 | 亚洲精品一区二区三区大桥未久 | 青青草原综合久久大伊人精品 | 亚洲精品一区国产 | 狠狠噜狠狠狠狠丁香五月 | 色爱情人网站 | 波多野结衣av一区二区全免费观看 | 婷婷色婷婷开心五月四房播播 | 亚洲国产精品美女久久久久 | 亚洲国产精品久久人人爱 | 国产一区二区三区影院 | 人妻无码αv中文字幕久久琪琪布 | 久久久av男人的天堂 | 亚洲成在人网站无码天堂 | 欧美三级不卡在线观看 | 国产一区二区不卡老阿姨 | 国产精品无码成人午夜电影 | 欧洲熟妇色 欧美 | 亚洲精品成人av在线 | 成人性做爰aaa片免费看 | 成年美女黄网站色大免费视频 | 性啪啪chinese东北女人 | 中文字幕无码av激情不卡 | 狠狠色色综合网站 | 欧美日韩在线亚洲综合国产人 | 国产激情无码一区二区 | 无码精品国产va在线观看dvd | 国产麻豆精品一区二区三区v视界 | 精品久久久久香蕉网 | 波多野结衣av一区二区全免费观看 | 一本久久伊人热热精品中文字幕 | 国内精品九九久久久精品 | 精品久久综合1区2区3区激情 | 亚洲熟女一区二区三区 | 狠狠色噜噜狠狠狠7777奇米 | 成人免费视频一区二区 | 55夜色66夜色国产精品视频 | 漂亮人妻洗澡被公强 日日躁 | 全黄性性激高免费视频 | 女人被爽到呻吟gif动态图视看 | 麻豆人妻少妇精品无码专区 | 中文字幕日韩精品一区二区三区 | 一本久道久久综合狠狠爱 | 久久国产自偷自偷免费一区调 | 国产精品亚洲综合色区韩国 | 亚洲男人av香蕉爽爽爽爽 | 中文字幕人妻无码一区二区三区 | 欧美成人午夜精品久久久 | 最新国产乱人伦偷精品免费网站 | 国产精品美女久久久网av | 亚洲综合在线一区二区三区 | 亚洲天堂2017无码中文 | 国产精品亚洲一区二区三区喷水 | 国产sm调教视频在线观看 | 亚洲精品成人av在线 | 亚洲爆乳大丰满无码专区 | 欧美午夜特黄aaaaaa片 | 欧美老人巨大xxxx做受 | 高潮毛片无遮挡高清免费 | 国产日产欧产精品精品app | 久久综合香蕉国产蜜臀av | 亚洲一区二区三区在线观看网站 | 国产精品久久国产三级国 | 欧美人与善在线com | 国产精品无码mv在线观看 | 亚洲日韩中文字幕在线播放 | 欧美日韩视频无码一区二区三 | 国产高清av在线播放 | 秋霞成人午夜鲁丝一区二区三区 | 18禁止看的免费污网站 | 久久精品中文闷骚内射 | 亚洲日韩av一区二区三区四区 | 国产真实伦对白全集 | 国产黑色丝袜在线播放 | 强开小婷嫩苞又嫩又紧视频 | 国产成人人人97超碰超爽8 | 伊人色综合久久天天小片 | 亚洲一区二区三区偷拍女厕 | 久久精品国产一区二区三区肥胖 | 免费无码av一区二区 | 2020最新国产自产精品 | 免费网站看v片在线18禁无码 | 国产口爆吞精在线视频 | 国产精品久久久午夜夜伦鲁鲁 | 成人精品视频一区二区三区尤物 | 又大又硬又黄的免费视频 | 男人的天堂av网站 | 日本熟妇乱子伦xxxx | 中文字幕无码人妻少妇免费 | 55夜色66夜色国产精品视频 | 国内揄拍国内精品少妇国语 | 精品一区二区三区波多野结衣 | 亚洲综合久久一区二区 | 正在播放东北夫妻内射 | 亚洲国产精品久久人人爱 | 99久久婷婷国产综合精品青草免费 | 亚洲精品午夜无码电影网 | 国产超级va在线观看视频 | 国产国语老龄妇女a片 | 久久亚洲中文字幕无码 | 国产真人无遮挡作爱免费视频 | 在线成人www免费观看视频 | 精品少妇爆乳无码av无码专区 | 东京无码熟妇人妻av在线网址 | 日本一本二本三区免费 | 久久人人爽人人爽人人片av高清 | 丰满少妇人妻久久久久久 | 强开小婷嫩苞又嫩又紧视频 | 青草青草久热国产精品 | 人妻有码中文字幕在线 | 成人亚洲精品久久久久 | 午夜福利不卡在线视频 | 久久99国产综合精品 | 中文字幕无码日韩欧毛 | 久久综合激激的五月天 | 精品国产一区二区三区四区在线看 | 人妻尝试又大又粗久久 | 人妻少妇精品久久 | 中文字幕 亚洲精品 第1页 | 亚洲日本一区二区三区在线 | 国产精品毛多多水多 | 婷婷色婷婷开心五月四房播播 | 国内揄拍国内精品少妇国语 | 亚洲人成网站色7799 | 精品亚洲成av人在线观看 | 男女性色大片免费网站 | 婷婷色婷婷开心五月四房播播 | 精品欧美一区二区三区久久久 | 国产卡一卡二卡三 | 久久国产精品萌白酱免费 | 亚洲精品无码人妻无码 | 中文字幕无线码 | 天堂а√在线地址中文在线 | 久久久精品欧美一区二区免费 | 精品无人区无码乱码毛片国产 | 欧洲欧美人成视频在线 | 色爱情人网站 | 夜夜高潮次次欢爽av女 | 亚洲欧美国产精品久久 | 久久久久99精品成人片 | 18禁黄网站男男禁片免费观看 | aa片在线观看视频在线播放 | 2020久久超碰国产精品最新 | 四虎永久在线精品免费网址 | 性生交片免费无码看人 | 亚洲国产精品无码久久久久高潮 | 狂野欧美性猛xxxx乱大交 | 亚洲区欧美区综合区自拍区 | 国产成人一区二区三区别 | 欧美精品国产综合久久 | 亚洲中文字幕在线无码一区二区 | 中文字幕+乱码+中文字幕一区 | 性欧美牲交在线视频 | 波多野结衣av一区二区全免费观看 | 暴力强奷在线播放无码 | 国产精品毛片一区二区 | 国产香蕉97碰碰久久人人 | 老子影院午夜精品无码 | 亚洲 另类 在线 欧美 制服 | 性做久久久久久久久 | 人人妻人人澡人人爽人人精品 | 色婷婷av一区二区三区之红樱桃 | 300部国产真实乱 | 亚洲国产成人a精品不卡在线 | 婷婷六月久久综合丁香 | 亚洲一区二区三区含羞草 | 亚洲成a人片在线观看日本 | 亚洲成在人网站无码天堂 | 免费人成网站视频在线观看 | 欧洲欧美人成视频在线 | 欧美日本精品一区二区三区 | 久久99精品久久久久久 | 激情内射亚州一区二区三区爱妻 | 欧美老妇与禽交 | 亚洲成av人影院在线观看 | 99国产精品白浆在线观看免费 | 全球成人中文在线 | 97夜夜澡人人双人人人喊 | 嫩b人妻精品一区二区三区 | 国产九九九九九九九a片 | 国产麻豆精品一区二区三区v视界 | 丰满护士巨好爽好大乳 | 小鲜肉自慰网站xnxx | 欧美丰满熟妇xxxx | 漂亮人妻洗澡被公强 日日躁 | 一本久道久久综合婷婷五月 | 欧美人与牲动交xxxx | 亚洲中文字幕无码中文字在线 | 亚洲娇小与黑人巨大交 | √8天堂资源地址中文在线 | av无码不卡在线观看免费 | 亚洲欧洲中文日韩av乱码 | 成在人线av无码免观看麻豆 | 98国产精品综合一区二区三区 | 5858s亚洲色大成网站www | 国产人妻大战黑人第1集 | 色婷婷av一区二区三区之红樱桃 | 国产午夜视频在线观看 | 亚洲国产一区二区三区在线观看 | 久久人人97超碰a片精品 | 国产综合在线观看 | 黑人粗大猛烈进出高潮视频 | 国产精品多人p群无码 | 一二三四在线观看免费视频 | 久久天天躁狠狠躁夜夜免费观看 | 久久久久免费看成人影片 | 中文字幕日韩精品一区二区三区 | 国产精品美女久久久 | 国产成人综合色在线观看网站 | 亚洲娇小与黑人巨大交 | 欧美国产亚洲日韩在线二区 | 国产一区二区三区影院 | 四虎国产精品免费久久 | 国产 浪潮av性色四虎 | 啦啦啦www在线观看免费视频 | 丰满少妇熟乱xxxxx视频 | 天堂无码人妻精品一区二区三区 | 欧美乱妇无乱码大黄a片 | 未满小14洗澡无码视频网站 | 2019午夜福利不卡片在线 | 日本爽爽爽爽爽爽在线观看免 | 久久久国产精品无码免费专区 | 人人妻人人澡人人爽欧美一区 | 久久午夜无码鲁丝片午夜精品 | 青青久在线视频免费观看 | 美女张开腿让人桶 | 久久综合网欧美色妞网 | 国产办公室秘书无码精品99 | 国产精品亚洲а∨无码播放麻豆 | 国产精品久久久久久亚洲影视内衣 | 国产sm调教视频在线观看 | 55夜色66夜色国产精品视频 | 欧美日韩色另类综合 | 少妇无码吹潮 | 国产成人av免费观看 | 久久亚洲精品成人无码 | 久久五月精品中文字幕 | 日本乱人伦片中文三区 | 清纯唯美经典一区二区 | 国产亚洲精品久久久久久久久动漫 | 伊人久久大香线蕉亚洲 | 亚洲中文字幕无码中文字在线 | 国产精品香蕉在线观看 | 无码国内精品人妻少妇 | 丝袜 中出 制服 人妻 美腿 | 少妇高潮喷潮久久久影院 | 激情人妻另类人妻伦 | 日日碰狠狠躁久久躁蜜桃 | 永久免费观看国产裸体美女 | 亚洲自偷自拍另类第1页 | 精品一区二区三区波多野结衣 | 丝袜人妻一区二区三区 | 国产精品成人av在线观看 | 红桃av一区二区三区在线无码av | 色婷婷香蕉在线一区二区 | 在教室伦流澡到高潮hnp视频 | 少妇人妻av毛片在线看 | 在线成人www免费观看视频 | 日韩精品无码免费一区二区三区 | 超碰97人人射妻 | 亚洲国产精品一区二区美利坚 | 亚洲成色www久久网站 | 国产深夜福利视频在线 | 99久久精品国产一区二区蜜芽 | 国产精品怡红院永久免费 | 一本色道婷婷久久欧美 | 正在播放东北夫妻内射 | 国产麻豆精品一区二区三区v视界 | 扒开双腿疯狂进出爽爽爽视频 | 无码国产色欲xxxxx视频 | 欧洲熟妇色 欧美 | 精品人妻人人做人人爽 | 玩弄中年熟妇正在播放 | 日本精品少妇一区二区三区 | 人妻少妇精品无码专区动漫 | 亚洲精品www久久久 | 国产艳妇av在线观看果冻传媒 | 国产午夜亚洲精品不卡下载 | 色情久久久av熟女人妻网站 | 国产精品二区一区二区aⅴ污介绍 | 国产国产精品人在线视 | 男人的天堂av网站 | 少妇无码吹潮 | 最新版天堂资源中文官网 | 婷婷丁香五月天综合东京热 | 亚洲大尺度无码无码专区 | 欧美大屁股xxxxhd黑色 | 一本久道久久综合婷婷五月 | 一本精品99久久精品77 | 日韩人妻无码一区二区三区久久99 | 久久人人97超碰a片精品 | 人人爽人人爽人人片av亚洲 | 日韩精品一区二区av在线 | 久久精品国产亚洲精品 | 鲁鲁鲁爽爽爽在线视频观看 | 国产精品va在线观看无码 | 午夜精品一区二区三区的区别 | 精品国产成人一区二区三区 | 人妻少妇精品久久 | 高清国产亚洲精品自在久久 | 久久综合狠狠综合久久综合88 | 扒开双腿吃奶呻吟做受视频 | 亚洲欧美日韩国产精品一区二区 | 国产人成高清在线视频99最全资源 | 久久精品女人的天堂av | 麻豆av传媒蜜桃天美传媒 | 曰韩无码二三区中文字幕 | 少妇高潮喷潮久久久影院 | 国产成人无码av一区二区 | 亚洲中文字幕在线观看 | 无码纯肉视频在线观看 | 日日噜噜噜噜夜夜爽亚洲精品 | 夜精品a片一区二区三区无码白浆 | 人人妻人人澡人人爽精品欧美 | 久久精品国产一区二区三区肥胖 | 国产美女极度色诱视频www | 国产精品久久精品三级 | 男女猛烈xx00免费视频试看 | 国产亚洲人成在线播放 | 日产精品高潮呻吟av久久 | 亚洲欧洲无卡二区视頻 | 特黄特色大片免费播放器图片 | av无码电影一区二区三区 | 性啪啪chinese东北女人 | 久久综合狠狠综合久久综合88 | 国产午夜手机精彩视频 | 一本色道久久综合狠狠躁 | 日本精品人妻无码免费大全 | 亚洲一区二区三区播放 | 国产亲子乱弄免费视频 | 一二三四社区在线中文视频 | 少妇邻居内射在线 | 樱花草在线社区www | 激情综合激情五月俺也去 | 亚洲国产午夜精品理论片 | 国产激情一区二区三区 | 亚洲日本va中文字幕 | 乱码午夜-极国产极内射 | 亚洲狠狠婷婷综合久久 | 一本无码人妻在中文字幕免费 | 日本护士xxxxhd少妇 | 亚洲狠狠婷婷综合久久 | 国产超级va在线观看视频 | 成人欧美一区二区三区 | 国产人妻人伦精品 | 大地资源网第二页免费观看 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产高潮视频在线观看 | 少妇人妻偷人精品无码视频 | 18黄暴禁片在线观看 | 亚洲精品中文字幕 | 日本爽爽爽爽爽爽在线观看免 | 亚洲人成网站在线播放942 | 狠狠色丁香久久婷婷综合五月 | 色婷婷综合中文久久一本 | 俺去俺来也在线www色官网 | 亚洲精品久久久久久久久久久 | 国产午夜无码视频在线观看 | 亚洲日韩av一区二区三区四区 | 亚洲色成人中文字幕网站 | 丰满人妻精品国产99aⅴ | 精品偷拍一区二区三区在线看 | 一个人看的www免费视频在线观看 | 午夜不卡av免费 一本久久a久久精品vr综合 | 成人免费无码大片a毛片 | 亚洲精品美女久久久久久久 | 国产成人无码av片在线观看不卡 | 精品国产av色一区二区深夜久久 | 亚洲精品一区二区三区婷婷月 | 无套内谢的新婚少妇国语播放 | 国产日产欧产精品精品app | 日韩精品一区二区av在线 | 久久天天躁狠狠躁夜夜免费观看 | 亚洲自偷自拍另类第1页 | 国产激情无码一区二区app | 国产成人精品三级麻豆 | 国产欧美精品一区二区三区 | 亚洲国产精品无码一区二区三区 | 一本加勒比波多野结衣 | 秋霞特色aa大片 | 国产成人精品一区二区在线小狼 | 国产无套粉嫩白浆在线 | 国产高清av在线播放 | 99国产欧美久久久精品 | 成人精品天堂一区二区三区 | 精品午夜福利在线观看 | 国产一精品一av一免费 | 熟妇女人妻丰满少妇中文字幕 | 毛片内射-百度 | 欧美精品无码一区二区三区 | 国产精品资源一区二区 | 免费人成在线视频无码 | 99久久精品午夜一区二区 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 熟妇人妻无码xxx视频 | 欧美性猛交内射兽交老熟妇 | 亚洲国产欧美日韩精品一区二区三区 | 国产亚洲日韩欧美另类第八页 | 久久人人爽人人人人片 | 亚洲啪av永久无码精品放毛片 | 久久午夜无码鲁丝片午夜精品 | 亚洲日本va中文字幕 | 牲交欧美兽交欧美 | 天堂а√在线地址中文在线 | 欧美人妻一区二区三区 | 狂野欧美激情性xxxx | 久久精品人人做人人综合试看 | 偷窥村妇洗澡毛毛多 | 搡女人真爽免费视频大全 | 亚洲人成人无码网www国产 | 国内综合精品午夜久久资源 | 成人aaa片一区国产精品 | 帮老师解开蕾丝奶罩吸乳网站 | 国产在线无码精品电影网 | 少妇一晚三次一区二区三区 | 亚洲小说图区综合在线 | 无码人妻出轨黑人中文字幕 | 免费观看黄网站 | 又粗又大又硬又长又爽 | 亚洲日本va午夜在线电影 | 亚洲自偷自拍另类第1页 | 精品无码成人片一区二区98 | 国产一区二区三区四区五区加勒比 | 国产深夜福利视频在线 | 黑人巨大精品欧美一区二区 | 久久精品国产99久久6动漫 | 欧美激情综合亚洲一二区 | 国产九九九九九九九a片 | 天海翼激烈高潮到腰振不止 | 免费无码一区二区三区蜜桃大 | 色综合视频一区二区三区 | 99久久久国产精品无码免费 | 日韩亚洲欧美精品综合 | 欧美日韩亚洲国产精品 | 国内精品一区二区三区不卡 | 久在线观看福利视频 | 欧美大屁股xxxxhd黑色 | 人人妻人人澡人人爽欧美精品 | 国产电影无码午夜在线播放 | 日本免费一区二区三区最新 | 精品人妻人人做人人爽夜夜爽 | 丁香啪啪综合成人亚洲 | 亚洲男人av香蕉爽爽爽爽 | 色婷婷久久一区二区三区麻豆 | 欧美xxxxx精品 | 色综合久久久无码中文字幕 | 国产亲子乱弄免费视频 | 国产精品国产三级国产专播 | 国产人成高清在线视频99最全资源 | 精品无人国产偷自产在线 | 亚洲熟妇色xxxxx欧美老妇 | 人妻少妇精品无码专区动漫 | 激情内射日本一区二区三区 | 久久综合九色综合欧美狠狠 | 一本精品99久久精品77 | 亚洲精品美女久久久久久久 | 伊人色综合久久天天小片 | 少妇久久久久久人妻无码 | 成人精品一区二区三区中文字幕 | 呦交小u女精品视频 | 四虎影视成人永久免费观看视频 | 麻豆成人精品国产免费 | 欧美精品无码一区二区三区 | 欧美性色19p | 2019午夜福利不卡片在线 | 日本一卡2卡3卡四卡精品网站 | 免费视频欧美无人区码 | 无码精品人妻一区二区三区av | 男人和女人高潮免费网站 | 久久久精品人妻久久影视 | 久久久久久亚洲精品a片成人 | 久久伊人色av天堂九九小黄鸭 |