久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > 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】的环境搭建和使用(全网最全)其一的全部內容,希望文章能夠幫你解決所遇到的問題。

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

亚洲gv猛男gv无码男同 | 国产手机在线αⅴ片无码观看 | 久久精品成人欧美大片 | 久久精品国产精品国产精品污 | 亚洲爆乳无码专区 | 又大又硬又爽免费视频 | 精品亚洲成av人在线观看 | 亚洲午夜福利在线观看 | 久久天天躁狠狠躁夜夜免费观看 | 成人性做爰aaa片免费看不忠 | 红桃av一区二区三区在线无码av | 中文字幕无码av激情不卡 | 国产疯狂伦交大片 | 国产69精品久久久久app下载 | 99国产欧美久久久精品 | 曰韩少妇内射免费播放 | 成年美女黄网站色大免费视频 | 小sao货水好多真紧h无码视频 | 色综合久久88色综合天天 | 国产艳妇av在线观看果冻传媒 | 九九在线中文字幕无码 | 无套内谢的新婚少妇国语播放 | av香港经典三级级 在线 | 丰满少妇高潮惨叫视频 | 日欧一片内射va在线影院 | 麻豆国产人妻欲求不满谁演的 | 久久97精品久久久久久久不卡 | 亚洲国产精品无码一区二区三区 | 高中生自慰www网站 | 少女韩国电视剧在线观看完整 | 亚洲男人av天堂午夜在 | 亚洲成a人片在线观看日本 | 国产成人无码午夜视频在线观看 | 丰满少妇熟乱xxxxx视频 | 久久久精品456亚洲影院 | www成人国产高清内射 | 天干天干啦夜天干天2017 | 中文无码伦av中文字幕 | 国产精品成人av在线观看 | 一本久久伊人热热精品中文字幕 | 精品无人国产偷自产在线 | 免费人成网站视频在线观看 | 丰满人妻一区二区三区免费视频 | 色狠狠av一区二区三区 | 最新国产麻豆aⅴ精品无码 | 亚洲自偷自拍另类第1页 | 国产精品无码永久免费888 | 亚洲熟妇色xxxxx欧美老妇 | 女人色极品影院 | 国产精品无码mv在线观看 | 色窝窝无码一区二区三区色欲 | 伊人久久大香线焦av综合影院 | 国产成人精品必看 | 在线欧美精品一区二区三区 | 性开放的女人aaa片 | 天天燥日日燥 | 性做久久久久久久久 | 亚洲精品成a人在线观看 | 黑人巨大精品欧美一区二区 | 99re在线播放 | 亚洲啪av永久无码精品放毛片 | 粉嫩少妇内射浓精videos | 精品无人国产偷自产在线 | 国产色xx群视频射精 | 欧美激情综合亚洲一二区 | 国产欧美熟妇另类久久久 | 国产香蕉97碰碰久久人人 | 西西人体www44rt大胆高清 | 精品国产精品久久一区免费式 | 任你躁在线精品免费 | 欧美国产日韩亚洲中文 | 欧美35页视频在线观看 | 又大又硬又黄的免费视频 | 狠狠cao日日穞夜夜穞av | 久久国产精品偷任你爽任你 | 国产激情一区二区三区 | 国产精品丝袜黑色高跟鞋 | 国产sm调教视频在线观看 | 少妇久久久久久人妻无码 | 色老头在线一区二区三区 | 东京热一精品无码av | 久久午夜夜伦鲁鲁片无码免费 | 午夜肉伦伦影院 | а√天堂www在线天堂小说 | 亚洲国产精品成人久久蜜臀 | 日韩av激情在线观看 | 国产极品美女高潮无套在线观看 | 欧美大屁股xxxxhd黑色 | 国产成人精品无码播放 | 久久久精品人妻久久影视 | 在线精品国产一区二区三区 | 亚洲精品国产精品乱码不卡 | 国产精品永久免费视频 | 最新国产乱人伦偷精品免费网站 | 亚洲码国产精品高潮在线 | 妺妺窝人体色www在线小说 | 美女黄网站人色视频免费国产 | 夜夜躁日日躁狠狠久久av | 国产香蕉97碰碰久久人人 | 亚洲精品一区二区三区婷婷月 | 中文字幕日韩精品一区二区三区 | 内射欧美老妇wbb | 伊人久久大香线焦av综合影院 | 久久aⅴ免费观看 | 国产精品高潮呻吟av久久4虎 | 国产精品美女久久久久av爽李琼 | 老熟女重囗味hdxx69 | 中文字幕 亚洲精品 第1页 | 久久久久成人片免费观看蜜芽 | 国产麻豆精品精东影业av网站 | 精品无码国产一区二区三区av | 日韩视频 中文字幕 视频一区 | 欧美人与禽zoz0性伦交 | 亚洲精品欧美二区三区中文字幕 | 熟妇人妻无码xxx视频 | 国产亚洲精品久久久久久久久动漫 | 无遮挡国产高潮视频免费观看 | 18无码粉嫩小泬无套在线观看 | 国产特级毛片aaaaaa高潮流水 | 中文字幕日韩精品一区二区三区 | 人妻人人添人妻人人爱 | 1000部夫妻午夜免费 | a在线亚洲男人的天堂 | 精品夜夜澡人妻无码av蜜桃 | 成人一在线视频日韩国产 | 欧美激情内射喷水高潮 | 女人和拘做爰正片视频 | 国产又爽又黄又刺激的视频 | 久久精品女人天堂av免费观看 | 亚洲国产精品毛片av不卡在线 | 色爱情人网站 | 久久国产劲爆∧v内射 | 久久精品99久久香蕉国产色戒 | 欧美国产亚洲日韩在线二区 | 大胆欧美熟妇xx | 亚洲成色www久久网站 | 伊人久久大香线蕉av一区二区 | 国产一精品一av一免费 | 无码精品国产va在线观看dvd | 免费国产黄网站在线观看 | 亚洲精品综合五月久久小说 | 亚洲一区二区三区含羞草 | 最新国产乱人伦偷精品免费网站 | 性做久久久久久久免费看 | 亚洲区小说区激情区图片区 | 老熟妇仑乱视频一区二区 | 国产va免费精品观看 | 一个人看的视频www在线 | 色情久久久av熟女人妻网站 | 无码人妻av免费一区二区三区 | 女人高潮内射99精品 | 国产色xx群视频射精 | 国产精品-区区久久久狼 | 免费乱码人妻系列无码专区 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲成在人网站无码天堂 | 久久午夜无码鲁丝片 | 人妻夜夜爽天天爽三区 | 久久国产精品萌白酱免费 | 欧美国产日韩久久mv | 精品亚洲韩国一区二区三区 | 日本丰满护士爆乳xxxx | 青青青手机频在线观看 | 国产精品久久久久7777 | 国产真实乱对白精彩久久 | 中文精品久久久久人妻不卡 | 国产香蕉尹人视频在线 | 在教室伦流澡到高潮hnp视频 | 全球成人中文在线 | 青青草原综合久久大伊人精品 | 亚洲区欧美区综合区自拍区 | 国产激情无码一区二区app | 亚洲国产精品毛片av不卡在线 | 无码人妻出轨黑人中文字幕 | 国产xxx69麻豆国语对白 | 精品 日韩 国产 欧美 视频 | 国产精品免费大片 | 久久97精品久久久久久久不卡 | 欧洲欧美人成视频在线 | 九九热爱视频精品 | 国产精品久久久久无码av色戒 | 欧美怡红院免费全部视频 | 日本精品人妻无码77777 天堂一区人妻无码 | 久久精品国产一区二区三区 | 亚洲精品成a人在线观看 | 久久久久亚洲精品男人的天堂 | 精品成人av一区二区三区 | 亚洲第一网站男人都懂 | 少妇邻居内射在线 | 少妇的肉体aa片免费 | 欧美丰满少妇xxxx性 | 国产精品-区区久久久狼 | 亚洲日韩精品欧美一区二区 | 噜噜噜亚洲色成人网站 | 免费网站看v片在线18禁无码 | 狠狠色噜噜狠狠狠狠7777米奇 | 中文字幕无码乱人伦 | 国产综合色产在线精品 | 久久久婷婷五月亚洲97号色 | 国产 精品 自在自线 | 高清无码午夜福利视频 | 亚洲精品www久久久 | 国产片av国语在线观看 | 无码一区二区三区在线观看 | 国内精品久久毛片一区二区 | 免费播放一区二区三区 | 熟女少妇人妻中文字幕 | 亚洲欧美国产精品久久 | 国产精品办公室沙发 | 亚洲经典千人经典日产 | 久久久久久九九精品久 | 免费网站看v片在线18禁无码 | 亚洲毛片av日韩av无码 | 国产97色在线 | 免 | √天堂中文官网8在线 | 成人影院yy111111在线观看 | 丁香啪啪综合成人亚洲 | 成人精品视频一区二区 | 日韩精品a片一区二区三区妖精 | 亚洲精品午夜国产va久久成人 | 久久人人爽人人爽人人片ⅴ | 亚洲aⅴ无码成人网站国产app | 欧美兽交xxxx×视频 | 精品国偷自产在线 | 精品久久久久久人妻无码中文字幕 | 精品偷自拍另类在线观看 | 精品夜夜澡人妻无码av蜜桃 | 欧美性猛交内射兽交老熟妇 | 欧美日韩一区二区免费视频 | 日韩精品a片一区二区三区妖精 | 久久国产精品二国产精品 | 人妻互换免费中文字幕 | 国产亚洲精品久久久久久久 | 久久久国产一区二区三区 | 亚洲一区二区三区国产精华液 | 国产精品久久久久久久影院 | 夜夜影院未满十八勿进 | 国产亚洲人成在线播放 | 丰满少妇人妻久久久久久 | 任你躁国产自任一区二区三区 | 国产成人无码区免费内射一片色欲 | 东京热无码av男人的天堂 | 亚洲精品鲁一鲁一区二区三区 | 中文精品久久久久人妻不卡 | 欧美zoozzooz性欧美 | 亚洲欧美日韩综合久久久 | 一本久道久久综合狠狠爱 | 自拍偷自拍亚洲精品10p | 国内老熟妇对白xxxxhd | 久久精品成人欧美大片 | 天天拍夜夜添久久精品 | 18黄暴禁片在线观看 | 十八禁视频网站在线观看 | 97夜夜澡人人双人人人喊 | 亚洲成熟女人毛毛耸耸多 | 男女下面进入的视频免费午夜 | 无码播放一区二区三区 | 亚洲综合无码久久精品综合 | 亚洲成a人片在线观看无码 | 久激情内射婷内射蜜桃人妖 | 国产精品欧美成人 | 久久久久久a亚洲欧洲av冫 | 日本一本二本三区免费 | 精品国产一区二区三区四区 | 国产农村妇女高潮大叫 | 夜夜躁日日躁狠狠久久av | 少女韩国电视剧在线观看完整 | 国产精品无码一区二区桃花视频 | 精品偷自拍另类在线观看 | 亚洲乱码日产精品bd | 国产一区二区三区日韩精品 | 欧美性黑人极品hd | 国产激情精品一区二区三区 | 成人片黄网站色大片免费观看 | 国产精品第一区揄拍无码 | 国产无av码在线观看 | 欧美人与禽zoz0性伦交 | 欧美日韩人成综合在线播放 | 一区二区三区乱码在线 | 欧洲 | 亚洲精品中文字幕久久久久 | 无码人妻精品一区二区三区不卡 | 中文字幕乱码人妻二区三区 | 十八禁视频网站在线观看 | 国产精品久久久久久无码 | 久久久www成人免费毛片 | 国产精品亚洲五月天高清 | 亚洲爆乳大丰满无码专区 | 久久久久久a亚洲欧洲av冫 | 九九久久精品国产免费看小说 | 成 人 网 站国产免费观看 | 99麻豆久久久国产精品免费 | 亚洲午夜福利在线观看 | 无码国模国产在线观看 | 欧美第一黄网免费网站 | 日韩欧美中文字幕在线三区 | 欧美亚洲日韩国产人成在线播放 | 55夜色66夜色国产精品视频 | 乱人伦人妻中文字幕无码 | 熟妇激情内射com | 大色综合色综合网站 | 国产精品第一国产精品 | 亚洲国产精华液网站w | 国产成人精品必看 | 日韩精品无码一区二区中文字幕 | 又粗又大又硬又长又爽 | 少妇厨房愉情理9仑片视频 | 国产电影无码午夜在线播放 | 四十如虎的丰满熟妇啪啪 | 荫蒂添的好舒服视频囗交 | 男人的天堂2018无码 | 啦啦啦www在线观看免费视频 | 麻豆国产97在线 | 欧洲 | 亚洲欧洲中文日韩av乱码 | 无码人妻精品一区二区三区下载 | 少妇太爽了在线观看 | 国产无套粉嫩白浆在线 | 亚洲欧美日韩成人高清在线一区 | 久久久久久九九精品久 | 日本欧美一区二区三区乱码 | 鲁大师影院在线观看 | 日本精品少妇一区二区三区 | 一本色道久久综合狠狠躁 | 日韩无码专区 | 无码乱肉视频免费大全合集 | 97夜夜澡人人爽人人喊中国片 | 人妻aⅴ无码一区二区三区 | 国产片av国语在线观看 | 日本大香伊一区二区三区 | 亚洲天堂2017无码中文 | 国产精品多人p群无码 | 日韩精品久久久肉伦网站 | 动漫av网站免费观看 | 日产精品99久久久久久 | 久久天天躁狠狠躁夜夜免费观看 | 国产午夜福利100集发布 | 国产人成高清在线视频99最全资源 | 最近中文2019字幕第二页 | 亚洲 另类 在线 欧美 制服 | 亚洲成av人在线观看网址 | 久久国产精品二国产精品 | 日韩精品一区二区av在线 | 国产精品第一国产精品 | 夜精品a片一区二区三区无码白浆 | 东京一本一道一二三区 | 欧美日韩久久久精品a片 | 欧美熟妇另类久久久久久不卡 | 99精品国产综合久久久久五月天 | 夜精品a片一区二区三区无码白浆 | 天天做天天爱天天爽综合网 | 欧美性黑人极品hd | 爽爽影院免费观看 | 国产内射老熟女aaaa | 亚洲精品综合五月久久小说 | 亚洲成在人网站无码天堂 | 大地资源网第二页免费观看 | 国产精品免费大片 | 樱花草在线播放免费中文 | 中文字幕人成乱码熟女app | 宝宝好涨水快流出来免费视频 | 成人免费视频一区二区 | 无码av中文字幕免费放 | 熟妇人妻激情偷爽文 | 高清不卡一区二区三区 | 欧美熟妇另类久久久久久不卡 | 国产熟妇高潮叫床视频播放 | 成熟女人特级毛片www免费 | 日本www一道久久久免费榴莲 | 欧美变态另类xxxx | 成在人线av无码免观看麻豆 | 婷婷五月综合激情中文字幕 | 撕开奶罩揉吮奶头视频 | 亚洲人成无码网www | 亚洲阿v天堂在线 | 精品久久久无码中文字幕 | 青青青爽视频在线观看 | а√资源新版在线天堂 | 亚洲国产日韩a在线播放 | 国产无遮挡又黄又爽又色 | 极品嫩模高潮叫床 | 亚洲欧洲日本综合aⅴ在线 | 久久久无码中文字幕久... | 日韩欧美群交p片內射中文 | 精品一区二区三区波多野结衣 | 久久精品中文字幕大胸 | 无码免费一区二区三区 | 丰满岳乱妇在线观看中字无码 | 丝袜人妻一区二区三区 | 国产精品亚洲一区二区三区喷水 | 偷窥日本少妇撒尿chinese | 久久99精品久久久久久动态图 | 精品国产一区二区三区四区 | аⅴ资源天堂资源库在线 | 丰满诱人的人妻3 | 一本色道久久综合亚洲精品不卡 | 亚洲熟熟妇xxxx | 日韩av无码一区二区三区 | 少妇无码av无码专区在线观看 | 久久亚洲日韩精品一区二区三区 | 性欧美videos高清精品 | 一个人看的www免费视频在线观看 | 国产精品igao视频网 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 国产精品久久久午夜夜伦鲁鲁 | 精品无码成人片一区二区98 | 国产精品免费大片 | 国产精品久久久久7777 | 国产激情无码一区二区 | 国产激情无码一区二区 | 亚洲国产精品无码一区二区三区 | 黄网在线观看免费网站 | 日本护士毛茸茸高潮 | 99视频精品全部免费免费观看 | 成人免费视频一区二区 | av无码不卡在线观看免费 | 一个人免费观看的www视频 | 无套内谢的新婚少妇国语播放 | 国产无遮挡又黄又爽又色 | 国产成人精品一区二区在线小狼 | 国产精品久久福利网站 | 国产手机在线αⅴ片无码观看 | 国产一精品一av一免费 | 午夜精品一区二区三区的区别 | 久久精品人妻少妇一区二区三区 | 国精品人妻无码一区二区三区蜜柚 | 国产一区二区三区四区五区加勒比 | 日本欧美一区二区三区乱码 | 欧美日韩精品 | 亚洲精品一区二区三区四区五区 | 午夜精品久久久久久久 | 欧美精品国产综合久久 | 377p欧洲日本亚洲大胆 | 日本大乳高潮视频在线观看 | 黑人玩弄人妻中文在线 | 无码成人精品区在线观看 | 成人aaa片一区国产精品 | 无码纯肉视频在线观看 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 熟女少妇人妻中文字幕 | 日本熟妇人妻xxxxx人hd | 又大又硬又黄的免费视频 | 黑人巨大精品欧美一区二区 | ass日本丰满熟妇pics | 亚洲欧美日韩综合久久久 | 久久久久成人精品免费播放动漫 | 日韩少妇白浆无码系列 | 欧美成人免费全部网站 | 55夜色66夜色国产精品视频 | 亚洲综合伊人久久大杳蕉 | 欧美日韩一区二区综合 | 色婷婷综合激情综在线播放 | а天堂中文在线官网 | 一本精品99久久精品77 | 亚洲熟妇色xxxxx欧美老妇y | 暴力强奷在线播放无码 | 国产国语老龄妇女a片 | 中文无码精品a∨在线观看不卡 | 国内揄拍国内精品人妻 | 久久久久久久久蜜桃 | 亚洲无人区一区二区三区 | 国产在线一区二区三区四区五区 | a在线观看免费网站大全 | 亚洲 激情 小说 另类 欧美 | 国产亚洲精品久久久久久久 | 久久精品国产日本波多野结衣 | 久在线观看福利视频 | 亚洲午夜久久久影院 | 久久天天躁狠狠躁夜夜免费观看 | √天堂中文官网8在线 | 亚洲人成影院在线无码按摩店 | 欧美丰满熟妇xxxx性ppx人交 | 国模大胆一区二区三区 | 18精品久久久无码午夜福利 | 老熟妇仑乱视频一区二区 | 成人免费视频视频在线观看 免费 | 少妇久久久久久人妻无码 | 午夜精品久久久久久久 | 蜜桃无码一区二区三区 | 亚洲人成影院在线观看 | 国产一区二区三区四区五区加勒比 | 国产偷国产偷精品高清尤物 | 久青草影院在线观看国产 | 成 人 免费观看网站 | 色婷婷av一区二区三区之红樱桃 | 黑人玩弄人妻中文在线 | 中文字幕av伊人av无码av | 性欧美牲交在线视频 | 人人妻人人澡人人爽人人精品浪潮 | 欧美国产日产一区二区 | 一本久久a久久精品亚洲 | 丰满少妇女裸体bbw | 婷婷丁香五月天综合东京热 | 天天躁日日躁狠狠躁免费麻豆 | 亚洲欧美日韩成人高清在线一区 | 欧美黑人性暴力猛交喷水 | 日韩亚洲欧美精品综合 | 亚洲国产欧美日韩精品一区二区三区 | 夜夜高潮次次欢爽av女 | 国内精品人妻无码久久久影院 | 日本精品高清一区二区 | 国内精品一区二区三区不卡 | 中文无码成人免费视频在线观看 | 亚洲熟熟妇xxxx | 亚洲大尺度无码无码专区 | 老子影院午夜伦不卡 | 免费无码一区二区三区蜜桃大 | 色婷婷香蕉在线一区二区 | 国内精品久久毛片一区二区 | 成人性做爰aaa片免费看不忠 | 久久国产自偷自偷免费一区调 | 久久五月精品中文字幕 | 性色欲情网站iwww九文堂 | 亚洲一区二区观看播放 | 久久精品女人天堂av免费观看 | 免费无码的av片在线观看 | 人妻互换免费中文字幕 | 成人亚洲精品久久久久 | 色婷婷欧美在线播放内射 | 性色av无码免费一区二区三区 | 一区二区三区乱码在线 | 欧洲 | 性做久久久久久久久 | 国产成人av免费观看 | 亚洲中文字幕成人无码 | 国产综合久久久久鬼色 | 久久久国产一区二区三区 | 2020久久超碰国产精品最新 | 小sao货水好多真紧h无码视频 | 天天摸天天碰天天添 | 国产无遮挡吃胸膜奶免费看 | 欧美日本免费一区二区三区 | 亚洲日韩乱码中文无码蜜桃臀网站 | 日韩视频 中文字幕 视频一区 | 无码av岛国片在线播放 | 亚洲精品国产第一综合99久久 | 夜精品a片一区二区三区无码白浆 | 日产精品99久久久久久 | 中文字幕中文有码在线 | 狠狠综合久久久久综合网 | 少妇人妻偷人精品无码视频 | 日韩欧美群交p片內射中文 | 国产亚洲人成在线播放 | 强伦人妻一区二区三区视频18 | 两性色午夜免费视频 | 四虎4hu永久免费 | 性欧美牲交在线视频 | 亚洲熟悉妇女xxx妇女av | 狠狠色噜噜狠狠狠狠7777米奇 | 97精品人妻一区二区三区香蕉 | 久久 国产 尿 小便 嘘嘘 | 日韩精品无码一本二本三本色 | 亚洲无人区一区二区三区 | 无码国产乱人伦偷精品视频 | 中文精品久久久久人妻不卡 | 成人试看120秒体验区 | 荫蒂添的好舒服视频囗交 | 成年美女黄网站色大免费全看 | 久久久久人妻一区精品色欧美 | 日韩av无码中文无码电影 | 久久久久人妻一区精品色欧美 | 欧美肥老太牲交大战 | 久久人人97超碰a片精品 | 亚洲日韩av片在线观看 | 日韩精品成人一区二区三区 | 亚洲成av人在线观看网址 | 波多野结衣一区二区三区av免费 | 日日摸天天摸爽爽狠狠97 | 风流少妇按摩来高潮 | 97精品国产97久久久久久免费 | 99精品无人区乱码1区2区3区 | 亚洲国产一区二区三区在线观看 | 狠狠色欧美亚洲狠狠色www | 成人亚洲精品久久久久 | 99久久亚洲精品无码毛片 | 丰满少妇弄高潮了www | 乌克兰少妇性做爰 | 九月婷婷人人澡人人添人人爽 | 成年女人永久免费看片 | 无码精品国产va在线观看dvd | 精品国产麻豆免费人成网站 | 强辱丰满人妻hd中文字幕 | 狠狠色噜噜狠狠狠7777奇米 | 日日摸天天摸爽爽狠狠97 | 狠狠cao日日穞夜夜穞av | 岛国片人妻三上悠亚 | 99re在线播放 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 日本熟妇乱子伦xxxx | 亚洲区小说区激情区图片区 | 国产又粗又硬又大爽黄老大爷视 | 1000部夫妻午夜免费 | 人妻中文无码久热丝袜 | 亚洲乱码中文字幕在线 | 装睡被陌生人摸出水好爽 | 又湿又紧又大又爽a视频国产 | 奇米影视7777久久精品 | 亚洲国产精品一区二区美利坚 | 少妇人妻av毛片在线看 | 精品久久久无码人妻字幂 | 亚洲综合另类小说色区 | 99久久精品日本一区二区免费 | 成人试看120秒体验区 | 国产农村妇女高潮大叫 | 国产猛烈高潮尖叫视频免费 | 久久久中文久久久无码 | 国产两女互慰高潮视频在线观看 | 精品无码成人片一区二区98 | 人人妻人人澡人人爽人人精品浪潮 | 国产情侣作爱视频免费观看 | 老头边吃奶边弄进去呻吟 | 伊人久久大香线蕉av一区二区 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 青青青爽视频在线观看 | 亚洲国产日韩a在线播放 | 亚洲精品国偷拍自产在线观看蜜桃 | 欧美性猛交xxxx富婆 | 亚洲色偷偷男人的天堂 | 日日摸天天摸爽爽狠狠97 | 300部国产真实乱 | 国产av一区二区精品久久凹凸 | 小泽玛莉亚一区二区视频在线 | 男女性色大片免费网站 | 精品无码国产自产拍在线观看蜜 | 少妇人妻av毛片在线看 | 粉嫩少妇内射浓精videos | 午夜成人1000部免费视频 | 亚洲区小说区激情区图片区 | 国产成人无码午夜视频在线观看 | 亚洲国产成人av在线观看 | 丰满人妻一区二区三区免费视频 | 熟妇人妻无码xxx视频 | 亚洲热妇无码av在线播放 | 久久精品人妻少妇一区二区三区 | 波多野结衣av在线观看 | 乱中年女人伦av三区 | 两性色午夜视频免费播放 | 久久久久久亚洲精品a片成人 | 麻豆成人精品国产免费 | 欧美老妇交乱视频在线观看 | 四十如虎的丰满熟妇啪啪 | 日本乱偷人妻中文字幕 | 亚洲精品国偷拍自产在线麻豆 | 国产精品多人p群无码 | 国产激情无码一区二区app | 亚洲天堂2017无码中文 | 东北女人啪啪对白 | 亚洲成av人在线观看网址 | 色综合久久中文娱乐网 | 久久久婷婷五月亚洲97号色 | 欧美老人巨大xxxx做受 | 欧美老妇交乱视频在线观看 | 日韩人妻系列无码专区 | 曰韩少妇内射免费播放 | 中文字幕无码免费久久99 | 国模大胆一区二区三区 | 久久久中文久久久无码 | 澳门永久av免费网站 | 国产精品手机免费 | 未满成年国产在线观看 | 99久久久无码国产精品免费 | 欧美国产亚洲日韩在线二区 | 国产成人无码专区 | 中文字幕乱妇无码av在线 | 少妇被黑人到高潮喷出白浆 | 又黄又爽又色的视频 | 国产午夜亚洲精品不卡 | 亚洲精品久久久久久一区二区 | 99久久人妻精品免费二区 | 波多野结衣av一区二区全免费观看 | 无码任你躁久久久久久久 | 亚洲综合另类小说色区 | 天天拍夜夜添久久精品大 | 色婷婷av一区二区三区之红樱桃 | 最近中文2019字幕第二页 | 一本大道伊人av久久综合 | 水蜜桃色314在线观看 | 色综合久久网 | 日本丰满熟妇videos | 色欲人妻aaaaaaa无码 | 女人被男人爽到呻吟的视频 | 亚洲日韩乱码中文无码蜜桃臀网站 | 任你躁国产自任一区二区三区 | 亚欧洲精品在线视频免费观看 | 国产麻豆精品精东影业av网站 | 成熟妇人a片免费看网站 | 狠狠亚洲超碰狼人久久 | 国产无遮挡又黄又爽免费视频 | 国产香蕉尹人视频在线 | 四虎影视成人永久免费观看视频 | 国产精品无码一区二区桃花视频 | 麻豆国产丝袜白领秘书在线观看 | 欧美日韩综合一区二区三区 | 国产国产精品人在线视 | 18禁黄网站男男禁片免费观看 | 亲嘴扒胸摸屁股激烈网站 | 麻豆国产丝袜白领秘书在线观看 | 国产免费久久久久久无码 | 精品国产av色一区二区深夜久久 | 久久无码专区国产精品s | 亚洲精品美女久久久久久久 | 3d动漫精品啪啪一区二区中 | 永久黄网站色视频免费直播 | 欧美性色19p | 无码人妻精品一区二区三区不卡 | 天天爽夜夜爽夜夜爽 | 俺去俺来也www色官网 | 无码人中文字幕 | 97色伦图片97综合影院 | 熟妇人妻激情偷爽文 | 国产亚洲精品久久久久久久久动漫 | 久久久久久av无码免费看大片 | 久久久久99精品国产片 | a国产一区二区免费入口 | 亚洲毛片av日韩av无码 | 久久久久久国产精品无码下载 | 欧美人与禽zoz0性伦交 | 婷婷色婷婷开心五月四房播播 | 狠狠色噜噜狠狠狠狠7777米奇 | 男人的天堂2018无码 | 国产人妻大战黑人第1集 | 久久精品国产99精品亚洲 | 鲁鲁鲁爽爽爽在线视频观看 | 精品aⅴ一区二区三区 | 国产国产精品人在线视 | 亚洲欧洲日本无在线码 | 丰满少妇弄高潮了www | 久久综合九色综合欧美狠狠 | 麻豆精产国品 | 国产国产精品人在线视 | 成人精品天堂一区二区三区 | 久久zyz资源站无码中文动漫 | 日日摸天天摸爽爽狠狠97 | 久久精品丝袜高跟鞋 | 久久国产精品_国产精品 | 中文字幕av伊人av无码av | 任你躁国产自任一区二区三区 | 兔费看少妇性l交大片免费 | 成人影院yy111111在线观看 | 成 人影片 免费观看 | 亚洲精品一区三区三区在线观看 | 乌克兰少妇性做爰 | 天堂久久天堂av色综合 | 欧美日韩在线亚洲综合国产人 | 国产亚洲人成a在线v网站 | 日日天日日夜日日摸 | 国产精品鲁鲁鲁 | 亚洲伊人久久精品影院 | 无码任你躁久久久久久久 | 国产亚洲精品久久久久久大师 | 精品少妇爆乳无码av无码专区 | 少妇无套内谢久久久久 | 亚洲国产欧美日韩精品一区二区三区 | 亚洲精品国产第一综合99久久 | 无码人妻丰满熟妇区毛片18 | 爱做久久久久久 | 亚洲自偷精品视频自拍 | 日本护士xxxxhd少妇 | 亚洲一区二区三区香蕉 | 亚洲一区二区三区 | 扒开双腿吃奶呻吟做受视频 | 久久www免费人成人片 | 日本大香伊一区二区三区 | 亚洲精品国产精品乱码视色 | 国产97人人超碰caoprom | 婷婷综合久久中文字幕蜜桃三电影 | 午夜精品久久久内射近拍高清 | 国产熟妇高潮叫床视频播放 | 国产成人无码av片在线观看不卡 | 色五月丁香五月综合五月 | 色 综合 欧美 亚洲 国产 | 夜夜躁日日躁狠狠久久av | 久久久中文久久久无码 | 狠狠色欧美亚洲狠狠色www | 夜夜高潮次次欢爽av女 | 波多野结衣乳巨码无在线观看 | 97夜夜澡人人爽人人喊中国片 | 天天做天天爱天天爽综合网 | 无码人妻精品一区二区三区下载 | 国产内射爽爽大片视频社区在线 | 亚洲一区二区观看播放 | 色偷偷人人澡人人爽人人模 | 亚洲欧洲日本无在线码 | 国内老熟妇对白xxxxhd | 欧洲欧美人成视频在线 | 国产麻豆精品一区二区三区v视界 | 久久伊人色av天堂九九小黄鸭 | 5858s亚洲色大成网站www | 好爽又高潮了毛片免费下载 | 人妻天天爽夜夜爽一区二区 | 狠狠噜狠狠狠狠丁香五月 | 人人澡人人透人人爽 | 国产综合在线观看 | 国产午夜无码视频在线观看 | 性欧美牲交xxxxx视频 | 无码人妻精品一区二区三区下载 | 婷婷丁香六月激情综合啪 | 扒开双腿吃奶呻吟做受视频 | 国产精品久久精品三级 | 亚洲一区二区三区播放 | 国产成人无码av一区二区 | 国产在线一区二区三区四区五区 | 亚洲成熟女人毛毛耸耸多 | 国产精品久久久久久亚洲毛片 | 精品人妻中文字幕有码在线 | 又湿又紧又大又爽a视频国产 | 日本va欧美va欧美va精品 | 国产乱码精品一品二品 | 国内精品人妻无码久久久影院 | 亚洲日本va中文字幕 | 成人精品视频一区二区三区尤物 | 丰满少妇女裸体bbw | 女人被男人躁得好爽免费视频 | 日日橹狠狠爱欧美视频 | 国产免费无码一区二区视频 | 国产美女精品一区二区三区 | 亚洲国产精华液网站w | 久久久久人妻一区精品色欧美 | 黑人巨大精品欧美黑寡妇 | 国产特级毛片aaaaaaa高清 | 国产黑色丝袜在线播放 | 久久久www成人免费毛片 | 黑人玩弄人妻中文在线 | √天堂中文官网8在线 | 国产一区二区三区精品视频 | 97色伦图片97综合影院 | 日韩成人一区二区三区在线观看 | 国产午夜无码视频在线观看 | 欧美自拍另类欧美综合图片区 | 给我免费的视频在线观看 | 欧美熟妇另类久久久久久多毛 | 欧美日韩一区二区免费视频 | 人妻无码久久精品人妻 | 欧美人与物videos另类 | 国内综合精品午夜久久资源 | 蜜桃av抽搐高潮一区二区 | 欧美 丝袜 自拍 制服 另类 | 天堂无码人妻精品一区二区三区 | 国产麻豆精品一区二区三区v视界 | 国产精品亚洲lv粉色 | 欧美熟妇另类久久久久久不卡 | 亚洲日本在线电影 | 亚洲天堂2017无码中文 | 国产亚洲视频中文字幕97精品 | 亚洲精品一区三区三区在线观看 | 国产精品人妻一区二区三区四 | 午夜嘿嘿嘿影院 | 国产精品高潮呻吟av久久4虎 | 亚洲精品国产精品乱码不卡 | 国产精品亚洲专区无码不卡 | 日本大乳高潮视频在线观看 | 麻豆md0077饥渴少妇 | 亚洲一区二区三区国产精华液 | 天天综合网天天综合色 | 国产熟妇高潮叫床视频播放 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 在线看片无码永久免费视频 | 国产高清av在线播放 | 亚洲国产一区二区三区在线观看 | 亚洲第一网站男人都懂 | 久久人人97超碰a片精品 | 强辱丰满人妻hd中文字幕 | 国产熟妇另类久久久久 | 国产精品亚洲专区无码不卡 | 色诱久久久久综合网ywww | 亚洲国产精品一区二区美利坚 | 日韩少妇白浆无码系列 | 亚洲精品国偷拍自产在线观看蜜桃 | 成人影院yy111111在线观看 | 亚洲国产一区二区三区在线观看 | 久久久久亚洲精品男人的天堂 | 无码精品国产va在线观看dvd | 国产办公室秘书无码精品99 | 国产美女精品一区二区三区 | 一本大道久久东京热无码av | 国产精品国产自线拍免费软件 | 55夜色66夜色国产精品视频 | 色综合久久久久综合一本到桃花网 | 中文字幕日韩精品一区二区三区 | 曰韩无码二三区中文字幕 | 熟女少妇人妻中文字幕 | 久久99精品国产.久久久久 | 少妇高潮喷潮久久久影院 | 风流少妇按摩来高潮 | 国内揄拍国内精品人妻 | 久久国产精品偷任你爽任你 | 成人动漫在线观看 | 国产精品久久久午夜夜伦鲁鲁 | 在线а√天堂中文官网 | 亚洲综合无码久久精品综合 | 亚洲精品国偷拍自产在线麻豆 | 日本又色又爽又黄的a片18禁 | 国产办公室秘书无码精品99 | av香港经典三级级 在线 | 青青青爽视频在线观看 | 漂亮人妻洗澡被公强 日日躁 | 国产人妻精品午夜福利免费 | 高潮毛片无遮挡高清免费 | 国产成人无码a区在线观看视频app | 久久精品国产一区二区三区肥胖 | 欧洲精品码一区二区三区免费看 | 亚洲精品午夜无码电影网 | 麻豆国产丝袜白领秘书在线观看 | 少妇愉情理伦片bd | 国产一区二区三区精品视频 | 欧美人与禽猛交狂配 | 精品无码一区二区三区爱欲 | 午夜精品一区二区三区的区别 | 久久国语露脸国产精品电影 | 小sao货水好多真紧h无码视频 | 国产精品无码一区二区三区不卡 | 性色欲情网站iwww九文堂 | 色老头在线一区二区三区 | 天天躁夜夜躁狠狠是什么心态 | 国产香蕉97碰碰久久人人 | 国产真实乱对白精彩久久 | 国产精品嫩草久久久久 | 中文字幕日产无线码一区 | 乱人伦人妻中文字幕无码 | 牲欲强的熟妇农村老妇女视频 | 中文久久乱码一区二区 | 一本久久a久久精品vr综合 | 好屌草这里只有精品 | 日韩视频 中文字幕 视频一区 | 性啪啪chinese东北女人 | 国产亚洲人成在线播放 | 亚洲综合无码一区二区三区 | 亚洲国产精品毛片av不卡在线 | 好屌草这里只有精品 | a片免费视频在线观看 | 欧美喷潮久久久xxxxx | 国产精品嫩草久久久久 | 色婷婷综合中文久久一本 | 国产亚洲欧美在线专区 | 国产av人人夜夜澡人人爽麻豆 | 日本一区二区更新不卡 | 亚洲成熟女人毛毛耸耸多 | 国产成人综合色在线观看网站 | 妺妺窝人体色www在线小说 | 国产午夜福利亚洲第一 | a在线观看免费网站大全 | 国产超碰人人爽人人做人人添 | 大胆欧美熟妇xx | 日日麻批免费40分钟无码 | 成人aaa片一区国产精品 | 啦啦啦www在线观看免费视频 | 中文字幕无码日韩专区 | 精品欧洲av无码一区二区三区 | 免费男性肉肉影院 | 波多野结衣高清一区二区三区 | 日本成熟视频免费视频 | 亚洲另类伦春色综合小说 | 亚洲欧美日韩国产精品一区二区 | 无码精品国产va在线观看dvd | 亚洲精品国产第一综合99久久 | 午夜福利试看120秒体验区 | 亚洲а∨天堂久久精品2021 | 澳门永久av免费网站 | 国产精品办公室沙发 | 亚洲欧美日韩国产精品一区二区 | 国产特级毛片aaaaaa高潮流水 | 大乳丰满人妻中文字幕日本 | 国产精品亚洲а∨无码播放麻豆 | 精品久久综合1区2区3区激情 | 久久www免费人成人片 | 亚洲男人av香蕉爽爽爽爽 | 夜精品a片一区二区三区无码白浆 | 人妻有码中文字幕在线 | 国产成人精品久久亚洲高清不卡 | 又粗又大又硬又长又爽 | 人妻天天爽夜夜爽一区二区 | 日韩精品无码免费一区二区三区 | 老子影院午夜伦不卡 | 熟女少妇人妻中文字幕 | 国产精品高潮呻吟av久久4虎 | 国产精品99久久精品爆乳 | 99er热精品视频 | 日本一本二本三区免费 | 青春草在线视频免费观看 | 一本久久a久久精品vr综合 | 精品成在人线av无码免费看 | 99视频精品全部免费免费观看 | 人人澡人人透人人爽 | 97无码免费人妻超级碰碰夜夜 | 久久久久久久久蜜桃 | 国产综合在线观看 | 国产电影无码午夜在线播放 | 又大又紧又粉嫩18p少妇 | 亚洲欧美综合区丁香五月小说 | 国产熟女一区二区三区四区五区 | 亚洲欧美日韩成人高清在线一区 | 免费观看又污又黄的网站 | 扒开双腿疯狂进出爽爽爽视频 | 少妇高潮一区二区三区99 | 久久国产劲爆∧v内射 | 欧美人与禽zoz0性伦交 | 精品一区二区不卡无码av | 人人妻人人澡人人爽人人精品浪潮 | 亚洲小说春色综合另类 | 任你躁在线精品免费 | 午夜精品一区二区三区在线观看 | 99久久精品日本一区二区免费 | 成人性做爰aaa片免费看不忠 | 亚洲日韩av片在线观看 | 国产猛烈高潮尖叫视频免费 | 日本一卡2卡3卡四卡精品网站 | 狠狠色噜噜狠狠狠狠7777米奇 | 少妇无码一区二区二三区 | 国产精品内射视频免费 | 亚洲综合在线一区二区三区 | 蜜臀av无码人妻精品 | 久久国内精品自在自线 | 欧美人与动性行为视频 | 亚洲国产精品毛片av不卡在线 | 久久99久久99精品中文字幕 | 精品无码一区二区三区的天堂 | 少妇愉情理伦片bd | 国产亚av手机在线观看 | 天堂а√在线地址中文在线 | 高潮毛片无遮挡高清免费 | 国产成人无码a区在线观看视频app | 亚洲综合另类小说色区 | 日日噜噜噜噜夜夜爽亚洲精品 | 欧美人与禽zoz0性伦交 | 99视频精品全部免费免费观看 | 国产亚洲精品久久久久久国模美 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 亚洲欧美国产精品久久 | 国产97人人超碰caoprom | 国产精品人人爽人人做我的可爱 | 天干天干啦夜天干天2017 | 小sao货水好多真紧h无码视频 | 领导边摸边吃奶边做爽在线观看 | 老熟女乱子伦 | 又大又硬又爽免费视频 | 激情内射亚州一区二区三区爱妻 | 成人无码精品1区2区3区免费看 | 久久久久成人片免费观看蜜芽 | 图片小说视频一区二区 | 乱人伦人妻中文字幕无码 | 日韩亚洲欧美精品综合 | 精品久久久中文字幕人妻 | 无人区乱码一区二区三区 | 欧美野外疯狂做受xxxx高潮 | 377p欧洲日本亚洲大胆 | 亚洲成a人片在线观看无码3d | 国产av久久久久精东av | 国产网红无码精品视频 | 国产亚洲欧美日韩亚洲中文色 | 无套内射视频囯产 | 国产乱人伦av在线无码 | 国产成人无码av在线影院 | 国产 精品 自在自线 | 国产偷抇久久精品a片69 | 色综合久久久无码中文字幕 | 97久久精品无码一区二区 | 性欧美大战久久久久久久 | 美女极度色诱视频国产 | 日韩人妻无码中文字幕视频 | 国内揄拍国内精品少妇国语 | 免费人成在线观看网站 | 亚洲日韩一区二区 | 精品亚洲韩国一区二区三区 | 99久久精品国产一区二区蜜芽 | 乱人伦中文视频在线观看 | 无码av免费一区二区三区试看 | 亚洲国产欧美日韩精品一区二区三区 | 欧美人与物videos另类 | 亚洲国产高清在线观看视频 | 狠狠色噜噜狠狠狠狠7777米奇 | 成人一区二区免费视频 | 欧美 日韩 亚洲 在线 | 亚洲精品综合五月久久小说 | 日韩精品a片一区二区三区妖精 | 久久国产精品萌白酱免费 | 久久综合网欧美色妞网 | 亚洲精品成人av在线 | a国产一区二区免费入口 | 色综合久久久无码中文字幕 | 人妻夜夜爽天天爽三区 | 久久国产精品二国产精品 | 一本久久伊人热热精品中文字幕 | 国产乱人无码伦av在线a | 国产亚洲精品久久久ai换 | 国产精品内射视频免费 | 亚洲日韩精品欧美一区二区 | 国产亚洲日韩欧美另类第八页 | 野狼第一精品社区 | 久久久精品国产sm最大网站 | 少妇性俱乐部纵欲狂欢电影 | 亚洲中文字幕久久无码 | 国产精品第一区揄拍无码 | 天天摸天天透天天添 | 一本一道久久综合久久 | 131美女爱做视频 | 国产性生大片免费观看性 | 久久久亚洲欧洲日产国码αv | 丝袜美腿亚洲一区二区 | 成人性做爰aaa片免费看不忠 | 2019午夜福利不卡片在线 | 漂亮人妻洗澡被公强 日日躁 | 乱码午夜-极国产极内射 | 免费国产黄网站在线观看 | 国语自产偷拍精品视频偷 | 国产成人av免费观看 | 国产激情无码一区二区 | 97无码免费人妻超级碰碰夜夜 | 波多野结衣乳巨码无在线观看 | 午夜福利一区二区三区在线观看 | 麻豆国产人妻欲求不满谁演的 | 天堂а√在线中文在线 | 亚洲国产一区二区三区在线观看 | 国产性生大片免费观看性 | 精品欧洲av无码一区二区三区 | 国产亚洲美女精品久久久2020 | 99精品无人区乱码1区2区3区 | a国产一区二区免费入口 | 在线成人www免费观看视频 | 亚洲伊人久久精品影院 | 国产精品人妻一区二区三区四 | 亚洲高清偷拍一区二区三区 | 久久精品国产精品国产精品污 | 九九综合va免费看 | 久久精品国产大片免费观看 | 天天躁日日躁狠狠躁免费麻豆 | 性生交大片免费看l | 国产午夜无码视频在线观看 | 久久久久久久久蜜桃 | 亚洲gv猛男gv无码男同 | 日韩精品无码一区二区中文字幕 | 精品国精品国产自在久国产87 | 国产香蕉97碰碰久久人人 | 成人免费视频视频在线观看 免费 | 国模大胆一区二区三区 | 国产明星裸体无码xxxx视频 | 欧美 丝袜 自拍 制服 另类 | 高潮毛片无遮挡高清免费 | 国产成人一区二区三区别 | 欧美一区二区三区视频在线观看 | 欧美野外疯狂做受xxxx高潮 | 国产精品久久久一区二区三区 | 最近免费中文字幕中文高清百度 | 欧美性猛交内射兽交老熟妇 | 水蜜桃av无码 | 国产激情无码一区二区 | 天堂亚洲2017在线观看 | 欧美大屁股xxxxhd黑色 | 中文精品无码中文字幕无码专区 | 奇米影视7777久久精品人人爽 | 双乳奶水饱满少妇呻吟 | 亚洲成熟女人毛毛耸耸多 | 久久久中文字幕日本无吗 | 亚洲色欲久久久综合网东京热 | 97无码免费人妻超级碰碰夜夜 | 无码毛片视频一区二区本码 | 精品国产乱码久久久久乱码 | 国产无av码在线观看 | 又粗又大又硬又长又爽 | 装睡被陌生人摸出水好爽 | 夜夜高潮次次欢爽av女 | 国产乱码精品一品二品 | 国产在线一区二区三区四区五区 | 亚洲一区二区观看播放 | 国产成人无码av一区二区 | 国产精品人人妻人人爽 | av无码久久久久不卡免费网站 | 无码人妻丰满熟妇区五十路百度 | 捆绑白丝粉色jk震动捧喷白浆 | 熟妇激情内射com | 伊在人天堂亚洲香蕉精品区 | 蜜桃视频插满18在线观看 | 中文字幕av无码一区二区三区电影 | 奇米影视7777久久精品 | 欧美肥老太牲交大战 | 搡女人真爽免费视频大全 | 国产精品怡红院永久免费 | 老司机亚洲精品影院 | 中文字幕日产无线码一区 | 国产精品亚洲一区二区三区喷水 | 少妇无套内谢久久久久 | 国产人妻人伦精品 | 午夜男女很黄的视频 | 亚洲aⅴ无码成人网站国产app | 内射巨臀欧美在线视频 | 大乳丰满人妻中文字幕日本 | 久久亚洲中文字幕精品一区 | 国产激情艳情在线看视频 | 精品亚洲韩国一区二区三区 | 性欧美疯狂xxxxbbbb | 55夜色66夜色国产精品视频 | 内射后入在线观看一区 | 国产农村乱对白刺激视频 | 一二三四社区在线中文视频 | 大胆欧美熟妇xx | 精品人妻中文字幕有码在线 | 高潮毛片无遮挡高清免费 | 欧美精品无码一区二区三区 | 无码中文字幕色专区 | 国产精品无套呻吟在线 | 国产精品爱久久久久久久 | 狂野欧美激情性xxxx | 久久精品99久久香蕉国产色戒 | 久久精品中文字幕大胸 | 国产精品久久久久久无码 | 亚洲精品久久久久avwww潮水 | 老太婆性杂交欧美肥老太 | 国产成人综合美国十次 | www成人国产高清内射 | 国产精品igao视频网 | 国产无遮挡又黄又爽免费视频 | 欧美日韩人成综合在线播放 | 老太婆性杂交欧美肥老太 | 久久久精品欧美一区二区免费 | 午夜福利一区二区三区在线观看 | 永久免费观看美女裸体的网站 | 国产高潮视频在线观看 | 97夜夜澡人人爽人人喊中国片 | 欧美高清在线精品一区 | 欧洲熟妇色 欧美 | 精品人妻中文字幕有码在线 | 老熟妇仑乱视频一区二区 | 日本一卡二卡不卡视频查询 | 窝窝午夜理论片影院 | 亚洲熟妇色xxxxx欧美老妇 | 日韩精品乱码av一区二区 | 四虎影视成人永久免费观看视频 | 久久综合网欧美色妞网 | 亚洲精品鲁一鲁一区二区三区 | 亚洲一区二区三区香蕉 | 综合网日日天干夜夜久久 | 性啪啪chinese东北女人 | 99久久精品无码一区二区毛片 | 嫩b人妻精品一区二区三区 | 人人妻人人澡人人爽欧美一区九九 | 巨爆乳无码视频在线观看 | 十八禁视频网站在线观看 | 全球成人中文在线 | 中文字幕无码免费久久9一区9 | 国产精品亚洲а∨无码播放麻豆 | 国产午夜亚洲精品不卡 | 国产精品鲁鲁鲁 | 亚洲理论电影在线观看 | 性欧美大战久久久久久久 | 亚洲最大成人网站 | 樱花草在线社区www | 欧美亚洲日韩国产人成在线播放 | 国精品人妻无码一区二区三区蜜柚 | 爱做久久久久久 | 俺去俺来也在线www色官网 | 无码午夜成人1000部免费视频 | 日本在线高清不卡免费播放 | 亚洲人成人无码网www国产 | 国产九九九九九九九a片 | 精品久久久久久亚洲精品 | 日本大香伊一区二区三区 | 性做久久久久久久久 | 99久久精品午夜一区二区 | 18无码粉嫩小泬无套在线观看 | 在线成人www免费观看视频 | 高清国产亚洲精品自在久久 | 亚洲 a v无 码免 费 成 人 a v | 男女爱爱好爽视频免费看 | 亚洲国产精品无码一区二区三区 | 国内少妇偷人精品视频免费 | 桃花色综合影院 | 18禁黄网站男男禁片免费观看 | 久久久久免费精品国产 | 午夜无码区在线观看 | 牲欲强的熟妇农村老妇女 | 欧美高清在线精品一区 | 在线精品亚洲一区二区 | 久久精品国产一区二区三区 | 奇米影视7777久久精品 | 性做久久久久久久免费看 | 精品日本一区二区三区在线观看 | 国产午夜福利亚洲第一 | 久久精品成人欧美大片 | 女人被男人躁得好爽免费视频 | 中文字幕久久久久人妻 | 国产绳艺sm调教室论坛 | 久久久久久国产精品无码下载 | 国产成人无码av在线影院 | 亚洲理论电影在线观看 | 亚洲无人区午夜福利码高清完整版 | 夜先锋av资源网站 | 欧美三级不卡在线观看 | 久久99精品国产麻豆蜜芽 | 人妻熟女一区 | 国产一区二区三区四区五区加勒比 | 18无码粉嫩小泬无套在线观看 | 亚洲s码欧洲m码国产av | 欧美精品一区二区精品久久 | 中文字幕av日韩精品一区二区 | 亚洲gv猛男gv无码男同 | 老熟女重囗味hdxx69 | 久久婷婷五月综合色国产香蕉 | 国产精品办公室沙发 | 人妻少妇被猛烈进入中文字幕 | 少妇被黑人到高潮喷出白浆 | 久久午夜无码鲁丝片秋霞 | 人人爽人人澡人人人妻 | 99精品视频在线观看免费 | 亚洲国产精品美女久久久久 | 亚洲国产av美女网站 | 日日碰狠狠躁久久躁蜜桃 | 国产精品二区一区二区aⅴ污介绍 | 成年美女黄网站色大免费视频 | 初尝人妻少妇中文字幕 | 国产精品无码永久免费888 | av无码久久久久不卡免费网站 | 一本久道久久综合婷婷五月 | 久久国产劲爆∧v内射 | 日产国产精品亚洲系列 | 亚洲中文字幕在线无码一区二区 | 极品尤物被啪到呻吟喷水 | 牲交欧美兽交欧美 | 欧美野外疯狂做受xxxx高潮 | 国产精品亚洲五月天高清 | 亚洲成av人片在线观看无码不卡 | 久久五月精品中文字幕 | v一区无码内射国产 | 99久久久无码国产aaa精品 | 波多野结衣高清一区二区三区 | 日本va欧美va欧美va精品 | 好男人www社区 | 亚洲色无码一区二区三区 | 熟女少妇人妻中文字幕 | 国内综合精品午夜久久资源 | 久久久久久久女国产乱让韩 | 全球成人中文在线 | 乌克兰少妇性做爰 | 成人免费视频在线观看 | 国产偷抇久久精品a片69 | 亚洲色欲色欲天天天www | 亚洲一区二区三区 | 欧美35页视频在线观看 | 亚洲一区二区观看播放 | 熟妇人妻中文av无码 | 久久精品人妻少妇一区二区三区 | 亚洲欧美国产精品久久 | 国产热a欧美热a在线视频 | 国产精品亚洲五月天高清 | 无码国产乱人伦偷精品视频 | 强伦人妻一区二区三区视频18 | 久热国产vs视频在线观看 | 男人的天堂av网站 | 久久午夜夜伦鲁鲁片无码免费 | 亚洲自偷自拍另类第1页 | 亚洲狠狠色丁香婷婷综合 | 国产麻豆精品一区二区三区v视界 | 色爱情人网站 | 久久天天躁狠狠躁夜夜免费观看 | 5858s亚洲色大成网站www | 精品国产福利一区二区 | 久久精品丝袜高跟鞋 | 成 人 网 站国产免费观看 | 黑人巨大精品欧美一区二区 | 国内精品九九久久久精品 | 亚洲色成人中文字幕网站 | 樱花草在线播放免费中文 | 色欲久久久天天天综合网精品 | 色一情一乱一伦一区二区三欧美 | 欧美freesex黑人又粗又大 | 亚洲一区av无码专区在线观看 | 欧洲熟妇精品视频 | 熟妇女人妻丰满少妇中文字幕 | 国产亚洲精品久久久久久大师 | 18禁止看的免费污网站 | 久久这里只有精品视频9 | 人人妻人人澡人人爽欧美一区 | 日韩av无码中文无码电影 | 久久人人爽人人爽人人片ⅴ | 亚洲精品综合五月久久小说 | 中文字幕无码视频专区 | 97精品人妻一区二区三区香蕉 | 丰满护士巨好爽好大乳 | 在线成人www免费观看视频 | 日韩av无码中文无码电影 | 午夜成人1000部免费视频 | 亚洲一区二区三区播放 | 婷婷六月久久综合丁香 | 久精品国产欧美亚洲色aⅴ大片 | 成人欧美一区二区三区黑人 | 久青草影院在线观看国产 | 欧美精品在线观看 | 少妇性荡欲午夜性开放视频剧场 | 中文字幕乱码中文乱码51精品 | 狠狠躁日日躁夜夜躁2020 | 夜夜夜高潮夜夜爽夜夜爰爰 | 亚洲最大成人网站 | 一本久久a久久精品vr综合 | 国产明星裸体无码xxxx视频 | 国产精品国产三级国产专播 | 久久99热只有频精品8 | 欧美激情内射喷水高潮 | 亚洲s码欧洲m码国产av | 麻豆国产丝袜白领秘书在线观看 | 两性色午夜视频免费播放 | 无套内谢的新婚少妇国语播放 | 日韩无套无码精品 | 日欧一片内射va在线影院 | 自拍偷自拍亚洲精品被多人伦好爽 | 婷婷五月综合缴情在线视频 | 强伦人妻一区二区三区视频18 | 永久免费精品精品永久-夜色 | 亚洲欧美综合区丁香五月小说 | 亚洲精品一区二区三区婷婷月 | 好男人社区资源 | 国产精品久久久久影院嫩草 | 日本护士xxxxhd少妇 | 亚洲高清偷拍一区二区三区 | 精品国产福利一区二区 | 国产精品久久久午夜夜伦鲁鲁 | 又粗又大又硬又长又爽 | 国产麻豆精品一区二区三区v视界 | 亚拍精品一区二区三区探花 | 西西人体www44rt大胆高清 | 最新国产乱人伦偷精品免费网站 | 日韩av无码一区二区三区不卡 | 97精品人妻一区二区三区香蕉 | 丝袜人妻一区二区三区 | 精品 日韩 国产 欧美 视频 | 亚洲日韩乱码中文无码蜜桃臀网站 | 人人澡人人透人人爽 | 日日摸天天摸爽爽狠狠97 | 麻豆av传媒蜜桃天美传媒 | 麻豆国产丝袜白领秘书在线观看 | 激情爆乳一区二区三区 | 大地资源中文第3页 | 中文字幕无码热在线视频 | 久久久国产一区二区三区 | 久久精品国产大片免费观看 | 国产精品美女久久久网av | 狠狠综合久久久久综合网 | 欧美日韩一区二区综合 | 少妇性l交大片欧洲热妇乱xxx | 国产偷国产偷精品高清尤物 | 久久精品99久久香蕉国产色戒 | 国产亚洲视频中文字幕97精品 | 亚洲中文字幕无码一久久区 | 一本色道久久综合亚洲精品不卡 | 捆绑白丝粉色jk震动捧喷白浆 | а天堂中文在线官网 | 午夜福利一区二区三区在线观看 | 国产精品人人爽人人做我的可爱 | 国产精品无码mv在线观看 | 欧美xxxx黑人又粗又长 | 久久久精品欧美一区二区免费 | 久久人人爽人人爽人人片ⅴ | 1000部夫妻午夜免费 | 少妇性荡欲午夜性开放视频剧场 | 无码一区二区三区在线观看 | 亚洲精品国产精品乱码不卡 | 成人片黄网站色大片免费观看 | 亚洲成a人片在线观看无码3d | 亚洲一区二区三区含羞草 | 国产偷国产偷精品高清尤物 | 亚洲一区二区三区无码久久 | 三上悠亚人妻中文字幕在线 | 一本大道久久东京热无码av | 久久熟妇人妻午夜寂寞影院 | 精品人妻人人做人人爽夜夜爽 | 色窝窝无码一区二区三区色欲 | 荫蒂添的好舒服视频囗交 | 波多野结衣乳巨码无在线观看 | 亚洲综合伊人久久大杳蕉 | 99久久久国产精品无码免费 | 国产凸凹视频一区二区 | 中文亚洲成a人片在线观看 | 国产小呦泬泬99精品 | 日日鲁鲁鲁夜夜爽爽狠狠 | 永久免费观看国产裸体美女 | 国产在线精品一区二区三区直播 | 久久精品中文字幕大胸 | 丰满少妇弄高潮了www | 国产午夜视频在线观看 | 日本又色又爽又黄的a片18禁 | 亚洲国产精品久久久天堂 | 玩弄少妇高潮ⅹxxxyw | 亚洲成色www久久网站 | 国产精品无码一区二区三区不卡 | 无码人妻丰满熟妇区毛片18 | 两性色午夜免费视频 | 又黄又爽又色的视频 | 奇米影视7777久久精品人人爽 | 欧美人与牲动交xxxx | 成熟人妻av无码专区 | 日本爽爽爽爽爽爽在线观看免 | 午夜福利试看120秒体验区 | 在线精品国产一区二区三区 | 欧美日本日韩 | 中文字幕无码日韩欧毛 | 亚洲国产欧美国产综合一区 | 精品人妻av区 | 精品国产av色一区二区深夜久久 | 性生交大片免费看女人按摩摩 | 精品乱子伦一区二区三区 | 丝袜人妻一区二区三区 | 久久综合狠狠综合久久综合88 | 性啪啪chinese东北女人 | 日韩人妻少妇一区二区三区 | 国内精品久久毛片一区二区 | 国产精品无码成人午夜电影 | 久久综合给合久久狠狠狠97色 | 狠狠综合久久久久综合网 | 漂亮人妻洗澡被公强 日日躁 | 久久久久亚洲精品男人的天堂 | 精品国产成人一区二区三区 | 中文字幕av日韩精品一区二区 | 亚洲国产一区二区三区在线观看 | 在线视频网站www色 | 2020久久香蕉国产线看观看 | 亚洲阿v天堂在线 | 亚洲另类伦春色综合小说 | 在线看片无码永久免费视频 | 性生交片免费无码看人 | 成在人线av无码免观看麻豆 | 中文字幕日产无线码一区 | 国产亚洲精品精品国产亚洲综合 | 久久久精品成人免费观看 | 国产精品无码成人午夜电影 | 特级做a爰片毛片免费69 | 国产猛烈高潮尖叫视频免费 | www国产亚洲精品久久久日本 | 欧美人与禽zoz0性伦交 | 成 人 免费观看网站 | 久久久久久亚洲精品a片成人 | 色婷婷欧美在线播放内射 | 亚洲欧美精品aaaaaa片 | 欧美丰满熟妇xxxx性ppx人交 | 久久久国产精品无码免费专区 | 亚洲欧洲日本综合aⅴ在线 | 99视频精品全部免费免费观看 | 任你躁在线精品免费 | 四十如虎的丰满熟妇啪啪 | 中文字幕无线码免费人妻 | 国产精品久久国产精品99 | 国产亚洲精品久久久闺蜜 | 国产精品久久久久久久9999 | 人妻插b视频一区二区三区 | 一二三四社区在线中文视频 | 麻豆果冻传媒2021精品传媒一区下载 | 十八禁真人啪啪免费网站 | 久久精品国产大片免费观看 | 免费人成网站视频在线观看 | 狂野欧美性猛交免费视频 | 国产欧美精品一区二区三区 | 中文字幕无码av波多野吉衣 | 波多野结衣av在线观看 | 亚洲精品成a人在线观看 | 久久人妻内射无码一区三区 | 成熟人妻av无码专区 | 成人无码视频免费播放 | 国产精品无码成人午夜电影 | 国产亚洲精品久久久久久大师 | 麻花豆传媒剧国产免费mv在线 | 成人无码影片精品久久久 | 天堂无码人妻精品一区二区三区 | 国产成人综合在线女婷五月99播放 | 日韩欧美成人免费观看 | 伊人久久大香线焦av综合影院 | 久久久久久亚洲精品a片成人 | 亚洲人成影院在线观看 | 自拍偷自拍亚洲精品被多人伦好爽 | 国产亚洲日韩欧美另类第八页 | 亚洲精品国产第一综合99久久 | 亚洲欧美日韩成人高清在线一区 | 中文字幕人妻无码一区二区三区 | 1000部夫妻午夜免费 | 国产真人无遮挡作爱免费视频 | 午夜精品一区二区三区在线观看 | 少妇被粗大的猛进出69影院 | 人人爽人人爽人人片av亚洲 | 久久无码中文字幕免费影院蜜桃 | 兔费看少妇性l交大片免费 | 久久精品国产大片免费观看 | 色婷婷久久一区二区三区麻豆 | 成年女人永久免费看片 | 内射欧美老妇wbb | 天天拍夜夜添久久精品 | 狠狠躁日日躁夜夜躁2020 | yw尤物av无码国产在线观看 | 国产精品国产自线拍免费软件 | 女人和拘做爰正片视频 | 国产口爆吞精在线视频 | 欧美国产亚洲日韩在线二区 | 国产女主播喷水视频在线观看 | 久久伊人色av天堂九九小黄鸭 | 久久久精品成人免费观看 | yw尤物av无码国产在线观看 | 狂野欧美性猛交免费视频 | 亚洲小说春色综合另类 | 波多野结衣高清一区二区三区 | 久久精品女人的天堂av | 极品尤物被啪到呻吟喷水 | 波多野结衣高清一区二区三区 | 精品无码成人片一区二区98 | 一本色道婷婷久久欧美 | 日韩精品无码免费一区二区三区 | 妺妺窝人体色www在线小说 | 色一情一乱一伦一视频免费看 | 欧美国产日韩亚洲中文 | 亚洲精品成人福利网站 | 全黄性性激高免费视频 | 少妇无码av无码专区在线观看 | 99久久人妻精品免费一区 | 亚洲va欧美va天堂v国产综合 | 国产精品自产拍在线观看 | 免费国产黄网站在线观看 | 在线播放免费人成毛片乱码 | 国产成人无码av片在线观看不卡 | 亚洲国产精品毛片av不卡在线 | 2020最新国产自产精品 | 一个人看的www免费视频在线观看 | 久久午夜无码鲁丝片午夜精品 | 在线a亚洲视频播放在线观看 | 国产精品久久久久久久9999 | 亚洲欧美日韩国产精品一区二区 | 亚洲无人区午夜福利码高清完整版 | 久久伊人色av天堂九九小黄鸭 | 国产精品久久久一区二区三区 | 动漫av一区二区在线观看 | 国产农村乱对白刺激视频 | 欧美zoozzooz性欧美 | 无码国内精品人妻少妇 | 成年美女黄网站色大免费全看 | 亚拍精品一区二区三区探花 | 欧美肥老太牲交大战 | 久久久久成人精品免费播放动漫 | 久久久久99精品国产片 | 久久天天躁狠狠躁夜夜免费观看 | 亚欧洲精品在线视频免费观看 | 国产人妻精品一区二区三区 | 久久综合给久久狠狠97色 | 婷婷色婷婷开心五月四房播播 | 免费无码午夜福利片69 | 97人妻精品一区二区三区 | а√天堂www在线天堂小说 | 兔费看少妇性l交大片免费 | 精品国产青草久久久久福利 | 日本饥渴人妻欲求不满 | 女人被男人躁得好爽免费视频 | 鲁一鲁av2019在线 | 久久午夜无码鲁丝片午夜精品 | 国产亚av手机在线观看 | 97se亚洲精品一区 | 国产在线一区二区三区四区五区 | 国产97人人超碰caoprom | 亚洲成熟女人毛毛耸耸多 | 动漫av网站免费观看 | 自拍偷自拍亚洲精品被多人伦好爽 | 久久午夜无码鲁丝片午夜精品 | 人人妻人人澡人人爽人人精品浪潮 | 中文字幕乱码人妻二区三区 | 亚洲一区二区三区无码久久 | 久久aⅴ免费观看 | 极品尤物被啪到呻吟喷水 | 精品国精品国产自在久国产87 | 国产av无码专区亚洲awww | 国产亚洲人成在线播放 | 欧美三级不卡在线观看 | 久久久久久久女国产乱让韩 | 精品一二三区久久aaa片 | 久久精品国产99精品亚洲 | 精品厕所偷拍各类美女tp嘘嘘 | 欧美阿v高清资源不卡在线播放 | 精品人人妻人人澡人人爽人人 | 98国产精品综合一区二区三区 | 天下第一社区视频www日本 | 老子影院午夜伦不卡 | 免费网站看v片在线18禁无码 | 欧美国产亚洲日韩在线二区 | 国产亚av手机在线观看 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲 高清 成人 动漫 | 亚洲综合无码久久精品综合 | 男女超爽视频免费播放 | 亚洲色欲色欲欲www在线 | 国产精品资源一区二区 |