Python 中 PyQt5 庫語法(一)
PyQt5庫(一)
一、 簡介
1、 什麼是 Qt
使用 C++ 語言編寫的跨平台 GUI 庫,支援Windows 、MacOS和Linux。由於 Qt 使用C++語言編寫,所以使用Qt開發的GUI程式的介面風格與當前作業系統完全相同,而且運行效率很高
2、 什麼是PyQt
PyQt實現了一個Python模組集。它有超過300類,將近6000個函數和方法。它是一個多平台的工具包,可以運行在所有主要作業系統上,包括UNIX,Windows和Mac。 PyQt採用雙許可證,開發人員可以選擇GPL和商業許可。在此之前,GPL的版本只能用在Unix上,從PyQt的版本4開始,GPL許可證可用於所有支援的平台 ,同時Qt能實現的功能PyQt都能實現
3、 環境搭建
安裝 PyQt5
pip install pyqt5
官方文檔:【//www.riverbankcomputing.com/static/Docs/PyQt5/sip-classes.html】
二、 基本結構
1、 第一個程式
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
# @file: Demo.py
# @time: 2022/3/28 9:20
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, qApp
import sys
# 創建一個應用程式
# sys.argv 當別人通過命令行執行這個程式的時候,可以設定一種功能(接收命令行傳遞的參數)
app = QApplication(sys.argv)
print(app.arguments()) # 得到命令行的參數
print(qApp.arguments()) # qApp為全局變數
# 創建一個窗口
w = QWidget()
# 窗口尺寸
w.resize(300, 150)
# 移動窗口,窗口左上角的坐標
w.move(300, 300)
# 設置窗口的標題
w.setWindowTitle("第一個基於pyqt5的桌面應用")
# 設置標籤
label = QLabel(w)
label.setText("hello world")
label.move(150, 75)
# 顯示窗口
w.show()
# 進入程式的消息循環,並通過exit函數確保主循環安全結束,相當於無限循環
# 檢測整個程式所接收到的用戶交互資訊
sys.exit(app.exec_())
2、 控制項操作
步驟:
-
創建控制項
-
# 設置標籤 label = QLabel(contain)
參數:
- contain:代表要在哪個控制項(容器)上面展示,可以為空
當我們創建一個控制項之後,如果說,這個控制項沒有父控制項,則把它當作頂層控制項(窗口)
-
-
設置控制項
- 大小,樣式,位置,樣式等
- 頂層控制項有許可權去設置窗口內容,結構等
-
展示控制項
- 當控制項沒有父控制項時,要使用 show 方法去展示控制項
3、 快速生成程式碼
在pycharm中的活動模板配置如下程式碼,快速生成程式碼
from PyQt5.Qt import *
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("$test$") # 設置標題
self.resize($500$, $500$) # 設置窗口大小
self.move($300$, $300$) # 移動窗口
self.setup_ui() # 調用創建控制項的方法
def setup_ui(self): # 添加控制項的操作
pass
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口
w = Window()
# 顯示窗口
w.show()
sys.exit(app.exec_())
4、 面向對象
提高程式碼的可維護性
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
# @file: Demo.py
# @time: 2022/3/28 9:20
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.setWindowTitle("Hello") # 設置標題
self.resize(300, 150) # 設置窗口大小
self.move(300, 300) # 移動窗口
self.setup_label() # 調用創建控制項的方法
def setup_label(self): # 添加控制項的操作
label = QLabel(self)
label.setText("Hello World")
label.move(150, 75)
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口
w = Window()
# 顯示窗口
w.show()
sys.exit(app.exec_())
三、 基類控制項
什麼是控制項?
- 一個程式介面上的各個獨立的標準,一塊矩形區域
- 每類控制項都具備不同的功能
- 同時,有些控制項有相似的功能,可以通過繼承關係學習
1、 QObject
1.1 設置標識
1.1.1 語法
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
# @file: Demo.py
# @time: 2022/3/28 9:20
from PyQt5.Qt import *
obj = QObject(self)
obj.setObjectName("notice") # 設置Qt對象名稱
print(obj.objectName()) # 獲得Qt對象名稱
obj.setProperty("notice_l", "error") # 設置對象的屬性
obj.setProperty("notice_l2", "warning")
print(obj.property("notice_l")) # 獲得一個對象的屬性值
print(obj.dynamicPropertyNames()) # 獲取一個對象中所有通過setProperty設置的屬性名稱
1.1.2 應用場景
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
# @file: Demo.py
# @time: 2022/3/28 9:20
from PyQt5.Qt import *
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QObject") # 設置標題
self.resize(500, 300) # 設置窗口大小
self.move(500, 500) # 移動窗口
self.setup_ui() # 調用創建控制項的方法
def setup_ui(self): # 添加控制項的操作
self.qObject_ui()
def qObject_ui(self): # 所有類的基類
# 案例演示
label = QLabel(self) # 創建標籤
label.setText("Hello") # 設置標籤內容
label.setObjectName("notice") # id 為 notice
label.setProperty("level", "error") # 屬性選擇器
with open("QStyle.qss", "r") as f:
"""
文件內容為:
QLabel#notice[level='error'] {
font-size: 20px;
color: blue;
}
"""
qApp.setStyleSheet(f.read())
# label.setStyleSheet("font-size: 20px; color: blue;")
# qss 樣式表,相當於前端的 css 樣式表,可以將其放入一個 `.qss` 的文件中,方便分離和讀取,同時,所有符合條件的內容都會變成相應的樣式
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口
w = Window()
# 顯示窗口
w.show()
sys.exit(app.exec_())
1.3 父子對象
1.3.1 語法
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
obj1 = QObject()
obj2 = QObject()
obj3 = QObject()
obj2.setParent(obj1) # 設置父子關係
obj3.setObjectName("2") # 設置id
obj3.setParent(obj2)
print(obj1, obj2.parent()) # 獲取父類,返回記憶體地址
print(obj2, obj1.children()) # 獲取所有直系子對象
print(obj1.findChild(QObject)) # 獲取後代,遞歸查找,只返回一個
print(obj1.findChild(QObject, "2")) # 獲取id為2的後代,只返回一個
print(obj1.findChildren(QObject)) # 獲取符合條件的所有後代
1.3.2 應用場景
記憶體管理機制,父控制項刪除,那麼子控制項也會自動刪除
- 按鈕和對話框本身是父子控制項關係
- 當對話框被刪除時,內部的子控制項也會自動刪除——非常合理
- 我們操作的時候,是操作的對話框控制項本身,而不是內部的子控制項
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
obj1 = QObject()
obj2 = QObject()
obj1.setParent(obj2)
# 監聽 obj2 對象被釋放
obj2.destroyed.connect(lambda: print("obj2,被釋放"))
print("刪除父對象")
del obj1
print("刪除完成")
如果一個控制項,沒有任何父控制項,那麼就會被當成頂層控制項——多個頂層窗口相互獨立
如果想要一個控制項被包含在另外一個控制項內部,就需要設置父子關係
- 顯示位置受父控制項約束
- 生命周期也被符對象接管
案例:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
win1 = QWidget()
win1.setStyleSheet("background-color: blue;")
win1.setWindowTitle("blue")
win1.resize(500, 500)
win1.show()
win2 = QWidget(win1)
win2.setStyleSheet("background-color: red;")
win2.setWindowTitle("red")
win2.resize(100, 100)
# win2.setParent(win1) # win1 為父對象,win2 = QWidget(win1) 效果一樣
win2.show()
l1 = QLabel()
b1 = QPushButton()
l1.setParent(win1)
b1.setParent(win1)
l1.setText("label")
b1.setText("button")
l1.move(200, 200)
b1.move(300, 200)
l2 = QLabel()
l2.setParent(win1)
l2.setText("Label")
l2.move(100, 200)
# 遍歷設置樣式
for i in win1.findChildren(QLabel):
i.setStyleSheet("color: green;")
l1.show()
b1.show()
l2.show()
sys.exit(app.exec_())
1.4 訊號操作
1.4.1 訊號與槽機制
訊號和槽是Qt中的核心機制,主要作用在於對象之間進行通訊
- 當達到某個條件時,執行某個操作
訊號(widget):
- 當一個控制項的狀態發生改變時,向外發出資訊
槽(connect):
- 一個執行某些操作的函數/方法
所有繼承自 QWidget 的控制項都支援訊號與槽機制
1.4.2 機制描述
手動操作:
- 訊號和槽相關聯
自動操作:
- 當訊號發出時,連接槽函數會自動執行
1.4.3 訊號處理
訊號:
objectNameChange(objectName)
:對象名稱發生改變時,發射此訊號destroyed(obj)
:對象被銷毀時,發射訊號blockSignals(True)
:臨時阻斷連接receivers(widget)
:查看當前訊號連接了多少個槽
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
def destroy():
print("對象被摧毀")
obj1 = QObject()
obj2 = QObject()
obj1.setParent(obj2)
# obj.destroyed
obj1.destroyed.connect(lambda: destroy())
# obj.objectNameChanged
obj1.objectNameChanged.connect(lambda name: print("對象名稱被改變: " + name))
obj1.setObjectName("xxx")
# obj1.objectNameChanged.disconnect() # 斷開槽與訊號的連接
obj1.blockSignals(True) # 臨時阻斷連接
obj1.setObjectName("1")
print("連接數量:" + str(obj1.receivers(obj1.objectNameChanged))) # 查看有多少個槽連接這個訊號
obj1.blockSignals(False) # 再次開啟連接
obj1.objectNameChanged.connect(lambda name: print("第二個連接:" + name))
print("連接數量:" + str(obj1.receivers(obj1.objectNameChanged))) # 查看有多少個槽連接這個訊號
obj1.setObjectName("2")
del obj2
1.4.4 案例
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("test") # 設置標題
self.resize(300, 300) # 設置窗口大小
self.move(200, 300) # 移動窗口
self.setup_ui() # 調用創建控制項的方法
def ret():
print("標題變化了")
# self.windowTitleChanged.disconnect() # 斷開槽與訊號的關係
self.blockSignals(True) # 臨時斷開連接也行
self.windowTitleChanged.connect(ret)
def setup_ui(self): # 添加控制項的操作
self.btn() # 添加按鈕
def btn(self):
b = QPushButton(self)
b.setText("點擊我")
def ret():
self.setWindowTitle("hello")
b.clicked.connect(ret)
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口
w = Window()
# 顯示窗口
w.show()
sys.exit(app.exec_())
1.5 類型判定
1.5.1 語法
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
obj = QObject(w)
w1 = QWidget(w)
l = QLabel(w)
print(w.isWidgetType()) # 判斷是繼承控制項類型
print(obj.isWidgetType()) # 判斷是否繼承控制項類型
print(l.isWidgetType()) # 判斷是否繼承控制項類型
print(w.inherits("QWidget")) # 判斷是否繼承控制項類型
print(obj.inherits("QLabel")) # 判斷是否繼承標籤類型
print(l.inherits("QLabel")) # 判斷是否繼承標籤類型
sys.exit(app.exec_())
1.5.2 案例
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("test") # 設置標題
self.resize(500, 500) # 設置窗口大小
self.move(300, 300) # 移動窗口
self.setup_ui() # 調用創建控制項的方法
def setup_ui(self): # 添加控制項的操作
l = QLabel(self)
l.setText("first")
l.move(100, 100)
l2 = QLabel(self)
l2.setText("second")
l2.move(200, 100)
btn = QPushButton(self)
btn.setText("點我")
btn.move(300, 100)
for i in self.findChildren(QWidget):
if i.inherits("QLabel"): # 如果為 label 類型,修改樣式
i.setStyleSheet("color: red; font-size: 20px")
else:
i.setStyleSheet("color: blue; font-size: 20px")
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口
w = Window()
# 顯示窗口
w.show()
sys.exit(app.exec_())
1.6 對象刪除
1.6.1 語法
刪除一個對象時,也會解除它與父對象之間的關係
obj.deleteLater()
:其並沒有將對象立即銷毀,而是向主消息循環發送了一個event,下一次主消息循環收到這個event之後才會銷毀對象- 這樣做的好處是可以在這些延遲刪除的時間裡面完成一些操作;壞處是記憶體釋放會不及時
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
obj1 = QObject()
obj2 = QObject()
obj3 = QObject()
obj3.setParent(obj2)
obj2.setParent(obj1)
obj1.destroyed.connect(lambda: print("obj1被釋放"))
obj2.destroyed.connect(lambda: print("obj2被釋放"))
obj3.destroyed.connect(lambda: print("obj3被釋放"))
# obj1.deleteLater()
obj2.deleteLater() # 等下一個循環開始時才會真正釋放
# del obj2 # 直接刪除,但是這是把變數和對象的關聯替換了,使得系統無法訪問對象,不是真的刪除
print(obj1)
w.show()
sys.exit(app.exec_())
1.7 事件處理
訊號與槽機制是對事件機制的高級封裝
事件機制更偏離底層
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
class App(QApplication):
def notify(self, rev, evt):
if rev.inherits("QPushButton") and evt.type() == QEvent.MouseButtonPress: # 過濾器,只查看按鈕事件,並且只查看滑鼠點擊事件
print("底層運行原理:")
print(rev, evt)
return super().notify(rev, evt) # 分發事件
class Btn(QPushButton):
def event(self, evt):
if evt.type() == QEvent.MouseButtonPress: # 事件過濾
print("按鈕點擊了", evt) # 裡面很多事件
return super().event(evt)
def mousePressEvent(self, evt):
print("滑鼠被點擊了。。。。。。。。。。") # 如果只有這行程式碼的話,沒有運行訊號與槽的操作
return super().mousePressEvent(evt)
app = App(sys.argv)
w = QWidget()
btn = Btn(w)
btn.setText("按鈕")
btn.move(100, 100)
btn.pressed.connect(lambda: print("按鈕被按下"))
btn.clicked.connect(lambda: print("按鈕被點擊"))
btn.released.connect(lambda: print("按鈕被鬆開"))
w.show()
sys.exit(app.exec_())
1.8 定時器操作
1.8.1 語法
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
class MyObject(QObject):
def timerEvent(self, evt):
print(evt, "1") # 每個1秒列印
return super().timerEvent(evt)
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("定時器")
w.resize(500, 500)
obj = MyObject()
t_id = obj.startTimer(1000) # 1秒執行一次,通過繼承的方法來啟動計時器
obj.killTimer(t_id) # 關閉定時器
w.show()
sys.exit(app.exec_())
1.8.2 應用場景
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
class MyLabel(QLabel):
def __init__(self, sec, *args, **kwargs): # 使用不定長參數傳參
super().__init__(*args, **kwargs)
self.move(20, 20)
self.setText(sec)
self.setStyleSheet("font-size: 20px; color: red;")
self.t_id = self.startTimer(1000) # 1秒執行一次,通過繼承的方法來啟動計時器
def timerEvent(self, evt):
# 倒計時原理
sec = int(self.text())
sec -= 1
self.setText(str(sec))
if (sec == 0):
self.killTimer(self.t_id) # 關閉定時器
class MyQWidget(QWidget):
def __init__(self, *args, **kwargs):
super(MyQWidget, self).__init__(*args, **kwargs)
self.setWindowTitle("定時器")
self.resize(500, 500)
self.startTimer(1000) # 動畫
def timerEvent(self, evt):
current_w, current_h = self.width(), self.height()
if current_w > 1000 and current_h > 1000:
current_w -= 20
current_h -= 20
elif current_h < 1000 and current_w < 1000:
current_w += 20
current_h += 20
self.resize(current_w, current_h)
app = QApplication(sys.argv)
w = MyQWidget()
MyLabel("10", w) # 同時,10秒倒計時
w.show()
sys.exit(app.exec_())
2、 QWidget
2.1 簡介
介紹
-
其為所有可視控制項的基類
-
是一個最簡單的空白控制項
-
控制項是用戶介面的最小元素
- 接收各種事件(滑鼠、鍵盤等)
- 繪製在桌面上面,展示給用戶看
-
每個控制項都是矩形的,它們按Z軸順序排序
-
控制項由其父控制項和前面的控制項剪切
-
沒有父控制項的控制項稱之為窗口
2.2 繼承
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
print(QWidget.__bases__) # 直系父類
print(QWidget.mro()) # 所有父類,祖宗類
父類幾乎所有的方法,子類都可以使用
2.3 控制項創建
語法:
w = QWidget(parent) # 如果沒有父類,可以不用填寫
2.4 大小位置
2.4.1 獲取
控制項的坐標系統:
- 以左上角為坐標原點,縱軸為垂直方向,橫軸為水平方向
獲取位置:
(x(), y()) / pos()
:- 相對於父控制項的位置,包含窗口框架;頂層控制項則相對於桌面的位置
QPoint(x, y)
(width(), height()) / size()
:- 控制項的寬度和高度,不包含窗口框架
QSize(width, height)
geometry()
:- 用戶區域相對於父控制項的位置和尺寸的組合,不包含窗口框架
QRect(x, y, width, height)
rect()
:- 控制項尺寸的組合,不包含窗口框架
QRect(0, 0, width, height)
frameSize()
:- 框架大小
frameGeometry()
:- 框架位置和尺寸
- 注意:
- 控制項顯示完畢之後,具體位置或者尺寸數據才會正確
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.move(100, 100)
w.resize(200, 200)
w.show()
# 桌面顯示後獲取的數據才準確
print(w.x())
print(w.width())
print(w.geometry())
print(w.rect())
print(w.frameSize())
print(w.frameGeometry())
sys.exit(app.exec_())
2.4.2 設置
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
"""
move(x, y) 操作的是 x, y 也就是 pos,包含窗口框架
resize(width, height) 操作的是寬高:不包含窗口框架
setGeometry(x_noFrame, y_noFrame, width, height) 此處參照為用戶區域,即不包含框架
adjustSize() 根據內容自適應大小
setFixedSize() 設置固定尺寸
"""
app = QApplication(sys.argv)
w = QWidget()
"""
w.move(100, 100)
w.resize(200, 200)
# 下面這行程式碼和上面兩行程式碼的作用類似
w.setGeometry(100, 100, 200, 200)
"""
w.setFixedSize(500, 500) # 不可以修改它的大小
w.show()
sys.exit(app.exec_())
2.5 尺寸最值
2.5.1 獲取
獲取:
(minimumWidth(), minimumHeight()) / minimumSize()
- 最小尺寸
(maximumWidth(), msximumHeight()) / maximumSize()
- 最大尺寸
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
w.show()
print(w.minimumSize()) # 得到最小尺寸
print(w.maximumSize()) # 得到最大尺寸
sys.exit(app.exec_())
2.5.2 設置
設置最大最小尺寸
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
w.setMaximumWidth(1000) # 限定最大寬度
w.setMaximumHeight(1000) # 限定最大高度
w.setMaximumSize(1000, 1000) # 限定最大寬度和高度
w.setMinimumSize(100, 100) # 限定最小寬度和高度
w.setMinimumWidth(100) # 限定最小寬度
w.setMinimumHeight(100) # 限定最小高度
w.show()
sys.exit(app.exec_())
限定最值尺寸後,如果修改後的尺寸超過這個最值,最終大小為最值大小
2.6 內容邊距
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
l = QLabel(w)
l.setText("Hello World")
l.setStyleSheet("background-color: red; font-size: 20px; font-weight: 500;")
l.resize(300, 300)
l.setContentsMargins(110, 0, 0, 0) # 設置內容外邊距
print(l.contentsRect().getRect()) # 得到內容區域
print(l.getContentsMargins()) # 得到內容外邊距
w.show()
sys.exit(app.exec_())
必須是控制項本身有足夠空間
2.7 滑鼠相關
2.7.1 設置滑鼠形狀
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
pixmap = QPixmap(r"D:\35005\Pictures\Screenshots\微信圖片_20220302175157.jpg") # 傳入圖片設置滑鼠圖標
pixmap_new = pixmap.scaled(50, 50) # 輸入縮放的尺寸
cursor = QCursor(pixmap_new) # 實例化滑鼠對象
# w.setCursor(Qt.BusyCursor) # 設置滑鼠形狀,參數裡面輸入滑鼠樣式
w.setCursor(cursor, 0, 0) # 也可以傳入一個滑鼠對象,後面的數字傳入的意思是以左上角為標準
w.unsetCursor() # 取消設置滑鼠的形狀
w.show()
sys.exit(app.exec_())
常見的滑鼠樣式查詢://www.riverbankcomputing.com/static/Docs/PyQt5/api/qtcore/qt.html#CursorShape
如果滑鼠進入了控制項的範圍內,形狀發生變化
2.7.2 重置滑鼠形狀
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
current_cursor = w.cursor() # 獲取滑鼠對象
print(current_cursor.pos()) # 獲得滑鼠相對於電腦螢幕的位置坐標
current_cursor.setPos(10, 10) # 設置滑鼠的位置
w.show()
sys.exit(app.exec_())
2.7.3 滑鼠跟蹤
所謂的滑鼠跟蹤,其實就是設置檢測滑鼠移動事件的條件
滑鼠跟蹤:
- 滑鼠移動時,不處於按下狀態,也會觸發 mouseMoveEvent 事件
滑鼠不跟蹤:
- 滑鼠移動時,必須處於按下狀態,才會觸發 mouseMoveEvent 事件
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
class MyWidget(QWidget):
def mouseMoveEvent(self, me):
print("滑鼠移動了", me.localPos()) # 當不跟蹤時,滑鼠要按下才會觸發
# me.pos()和 me.localPos() 得到滑鼠相對於控制項的位置
app = QApplication(sys.argv)
w = MyWidget()
w.setWindowTitle("滑鼠事件")
w.resize(500, 500)
w.setMouseTracking(True) # 開啟滑鼠跟蹤
print(w.hasMouseTracking()) # 判定是否開啟滑鼠跟蹤
w.show()
sys.exit(app.exec_())
2.7.4 案例
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
# 滑鼠按下移動標籤
class MyWidget(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.resize(500, 500)
self.setWindowTitle("滑鼠事件案例")
self.label = QLabel(self)
self.setup_ui()
def mouseMoveEvent(self, me):
x, y = me.x(), me.y()
self.label.move(x, y)
def setup_ui(self):
self.label.resize(100, 100)
self.label.setText("按住我!")
self.label.setStyleSheet("background-color: green; font-weight: bold;")
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.show()
sys.exit(app.exec_())
2.8 事件
2.8.1 API
顯示和關閉事件:
showEvent(QShowEvent) # 控制項顯示是調用
closeEvent(QCloseEvent) # 控制項關閉時調用
移動事件:
moveEvent(QMoveEvent) # 控制項移動時調用
調整大小事件:
resizeEvent(QResizeEvent) # 控制項大小改變時調用
滑鼠事件:
enterEvent(QEvent) # 滑鼠進入時觸發
leaveEvent(QEvent) # 滑鼠離開時觸發
mousePressEvent(QMouseEvent) # 滑鼠按下時觸發
mouseReleaseEvent(QMouseEvent) # 滑鼠按下時觸發
mouseDoubleClickEvent(QMouseEvent) # 滑鼠雙擊時觸發
mouseMoveEvent(QMouseEvent) # 滑鼠按下後移動時觸發,設置追蹤後,沒按下也能觸發
鍵盤事件:
keyPressEvent(QKeyEvent) # 鍵盤按下時使用
keyReleaseEvent(QKeyEvent) # 鍵盤鬆開時使用
焦點事件:
focusInEvent(QFocusEvent) # 獲得焦點
focuseOutEvent(QFocusEvent) # 失去焦點
拖拽事件:
dragEnterEvent(QDragEnterEvent) # 拖拽進入控制項時使用
dragLeaveEvent(QDragLeaveEvent) # 拖拽離開控制項時使用
dragMoveEvent(QDragMoveEvent) # 拖拽在控制項內移動時使用
dropEvent(QDropEvent) # 拖拽放下時使用
繪製事件:
paintEvent(QPaintEvent) # 顯示控制項,更新控制項時使用
改變事件:
changeEvent(QEvent) # 窗體改變,字體改變時調用
右鍵菜單:
contextMenuEvent(QContextMenuEvent) # 訪問右鍵菜單時使用
輸入法:
inputMethodEvent(QInputMethodEvent) # 輸入法切換調用
當一個控制項被觸發了一個特定的行為時,就會調用特定的方法,來將事件傳遞給開發人員,方便處理
重寫事件方法,就可以監聽相關的資訊
2.8.2 示例
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("test") # 設置標題
self.resize(500, 500) # 設置窗口大小
self.move(100, 100) # 移動窗口
def showEvent(self, ev):
print("窗口被展示了出來", ev)
def closeEvent(self, ev):
print("窗口關閉", ev)
def moveEvent(self, ev):
print("窗口移動", ev.pos())
def resizeEvent(self, ev):
print("控制項大小改變", ev.size())
def enterEvent(self, ev):
print("滑鼠進入了", ev)
def leaveEvent(self, ev):
print("滑鼠離開了", ev)
def mousePressEvent(self, ev):
print("滑鼠按下了", ev.button())
def mouseReleaseEvent(self, ev):
print("滑鼠鬆開", ev)
def mouseDoubleClickEvent(self, ev):
print("滑鼠雙擊了", ev.flags())
def mouseMoveEvent(self, ev):
print("滑鼠在移動", ev)
def keyPressEvent(self, ev):
print("鍵盤按下了:", chr(ev.key()))
def keyReleaseEvent(self, ev):
print("鍵盤鬆開了:", chr(ev.key()))
def focusInEvent(self, ev):
print("獲得焦點")
def focusOutEvent(self, ev):
print("失去焦點")
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口
w = Window()
# 顯示窗口
w.show()
sys.exit(app.exec_())
2.8.3 事件傳遞
如果一個控制項沒有處理該事件,則會自動傳遞給父控制項進行處理
事件對象具有兩種特殊方法:
accept()
:- 自己處理這個事件,並告訴系統不要在向上層傳遞
ignore()
:- 自己忽略這個事件,但是會執行;告訴系統,繼續往後傳遞
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
class Window(QWidget):
def mousePressEvent(self, ev):
print("頂層滑鼠按下")
class MidWindow(QWidget):
def mousePressEvent(self, ev):
ev.ignore() # 轉發給父對象,但是也會接收對象
print(ev.isAccepted())
print("中間滑鼠按下")
class Label(QLabel):
def mousePressEvent(self, ev):
print("標籤控制項滑鼠按下")
ev.accept() # 不用轉發給父對象,接收對象
print(ev.isAccepted())
app = QApplication(sys.argv)
w = Window()
w.setWindowTitle("事件轉發")
w.resize(500, 500)
m_w = MidWindow(w)
m_w.resize(300, 300)
m_w.setAttribute(Qt.WA_StyledBackground, True)
m_w.setStyleSheet("background-color: yellow;")
label = Label(m_w)
label.setText("這是一個標籤")
label.setStyleSheet("background-color: skyblue;")
label.move(110, 110)
# 注意這個底層事件會被頂層事件覆蓋
w.show()
sys.exit(app.exec_())
2.8.4 案例
-
創建一個窗口包含一個標籤
- 滑鼠進入標籤時,展示歡迎光臨
- 滑鼠離開標籤時,展示謝謝惠顧
#!/usr/bin/env python # -*- coding: UTF-8 -*- # @author: kun from PyQt5.Qt import * import sys class Label(QLabel): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.resize(200, 200) self.move(100, 100) self.setStyleSheet("background-color: skyblue;") def enterEvent(self, *args, **kwargs): self.setText("歡迎光臨") def leaveEvent(self, *args, **kwargs): self.setText("謝謝惠顧") app = QApplication(sys.argv) w = QWidget() w.setWindowTitle("滑鼠操作案例1") w.resize(500, 500) label = Label(w) w.show() sys.exit(app.exec_())
-
創建一個窗口,監聽用戶按鍵
- 監聽用戶輸入Tab鍵
- 監聽用戶輸入Ctrl + S 組合鍵
- 監聽用戶輸入Ctrl + Shift + v 組合鍵
#!/usr/bin/env python # -*- coding: UTF-8 -*- # @author: kun from PyQt5.Qt import * import sys class Label(QLabel): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.resize(200, 200) self.move(100, 100) self.setStyleSheet("background-color: skyblue; font-weight: 500;") self.grabKeyboard() # 捕獲鍵盤事件 # self.releaseKeyborad() # 停止捕獲鍵盤事件 def keyPressEvent(self, ev): # 監聽 Tab 鍵 if ev.key() == Qt.Key_Tab: # 監聽普通鍵 self.setText('用戶點擊的是Tab鍵') # 監聽 Ctrl + C 修飾鍵 Ctrl 並且 普通鍵 C Qt.AltModifier:其為 Alt 組合鍵 if ev.modifiers() == Qt.ControlModifier and ev.key() == Qt.Key_C: self.setText("正在複製文本內容") # 監聽 Ctrl + Shift + v 修飾鍵 Ctrl + Shift (使用按位或組合獲取) 並且普通鍵 V if ev.modifiers() == Qt.ControlModifier | Qt.ShiftModifier and ev.key() == Qt.Key_V: self.setText("正在粘貼內容") app = QApplication(sys.argv) w = QWidget() w.setWindowTitle("滑鼠操作案例1") w.resize(500, 500) label = Label(w) w.show() sys.exit(app.exec_())
-
完成窗口,用戶區支援拖拽
- 確定滑鼠移動的距離(向量 x, y)
- 原始窗口坐標點 + 向量
#!/usr/bin/env python # -*- coding: UTF-8 -*- # @author: kun from PyQt5.Qt import * class Window(QWidget): def __init__(self): super().__init__() self.move_flag = False # 判斷是否在移動 self.setWindowTitle("內容拖動") # 設置標題 self.resize(500, 500) # 設置窗口大小 self.move(100, 100) # 移動窗口 self.mouse = () # 移動前的坐標 self.origin = () # 原始的坐標 def mousePressEvent(self, evt): """ print(evt.localPos()) # 得到是相對於窗口左上角的坐標 print(evt.globalPos()) # 得到的是相對於電腦左上角的坐標 """ if evt.button() == Qt.LeftButton: self.move_flag = True # 設定標記 self.mouse = (evt.globalX(), evt.globalY()) self.origin = (self.x(), self.y()) # 左上角坐標 def mouseMoveEvent(self, evt): if self.move_flag: # 相對移動 move_x = evt.globalX() - self.mouse[0] move_y = evt.globalY() - self.mouse[1] self.move(self.origin[0] + move_x, self.origin[1] + move_y) def mouseReleaseEvent(self, evt): # 確定最終位置 self.move_flag = False if __name__ == '__main__': # 可以通過導包來運行窗口 import sys app = QApplication(sys.argv) # 創建窗口 w = Window() # 顯示窗口 w.show() sys.exit(app.exec_())
2.9 父子關係
2.9.1 語法
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("父子關係")
w.resize(500, 500)
l1 = QLabel(w)
l1.setText("標籤1")
l2 = QLabel(w)
l2.setText("標籤2")
l2.move(50, 0)
l3 = QLabel(w)
l3.setText("標籤3")
l3.move(100, 0)
print(w.childAt(50, 0)) # 獲得對應坐標的子控制項
print(l2.parentWidget()) # 獲得父控制項
print(w.childrenRect().getRect()) # 列印子控制項所佔有的矩形區域
w.show()
sys.exit(app.exec_())
2.9.2 案例
創建窗口,若干個Label控制項,實現點擊功能
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
# class MyLabel(QLabel): # 藉助子控制項
# def mousePressEvent(self, evt):
# for i in self.parentWidget().findChildren(MyLabel): # 獲取父控制項
# i.setStyleSheet("")
# self.setStyleSheet("background-color: red;")
class MyWidget(QWidget):
def mousePressEvent(self, evt):
subLabel = self.childAt(evt.x(), evt.y())
if subLabel: # 如果點擊了標籤;避免了報錯
for i in self.findChildren(QLabel): # 獲取所有子控制項,並清空樣式
i.setStyleSheet("")
subLabel.setStyleSheet("background-color: red;") # 給制定內容修改樣式
app = QApplication(sys.argv)
w = MyWidget()
w.setWindowTitle("父子關係")
w.resize(500, 500)
for i in range(11):
l = QLabel(w)
l.setText(f"標籤{i}")
l.move(50 * i, 50 * i)
w.show()
sys.exit(app.exec_())
2.10 層級控制
高層級控制項會被低層級控制項覆蓋
語法:
lower() # 將控制項層級降低到最底層
raise_() # 將控制項提升到最上層
a.stzckUnder(b) # 讓 a 放在 b 下面
注意:以上操作專指同級順序
應用:需要調整控制項Z軸順序
2.11 頂層窗口
2.11.1 基本語法
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
icon = QIcon(r"D:\35005\Pictures\Screenshots\微信圖片_20220302175157.jpg") # 創建圖標對象
w.setWindowIcon(icon) # 設置窗口圖標
print(w.windowIcon()) # 獲取圖標對象
w.setWindowTitle("Hello") # 默認為 python
print(w.windowTitle()) # 獲取窗口的標題
w.setWindowOpacity(0.9) # 設置不透明度,範圍是 0 ~ 1
print(w.windowOpacity()) # 獲取窗口不透明度
w.setWindowState(Qt.WindowActive)
# 設置窗口狀態,有 無狀態(WindowNoSate) 最小化(WindowMinimized)
# 最大化(WindowMaximized) 全螢幕(WindowFullScreen) 活動窗口(WindowActive)
print(w.windowState()) # 獲取窗口狀態
w.show()
sys.exit(app.exec_())
2.11.2 最大化和最小化
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
# w.showMaximized() # 最大化展示
# w.showMinimized() # 最小化展示
# w.showNormal() # 正常展示
# w.showFullScreen() # 全螢幕展示
print(w.isMinimized()) # 查看是否為最小化
print(w.isMaximized()) # 查看是否為最大化
print(w.isFullScreen()) # 查看是否為全螢幕
w.show()
sys.exit(app.exec_())
2.11.3 窗口標誌
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.setWindowFlags(Qt.WindowStaysOnTopHint) # 設置頂層窗口的外觀標誌
w.show()
sys.exit(app.exec_())
屬性 描述 Qt.MSWindowsFixedSizeDialogHint 固定窗口,無法調整大小 Qt.FramelessWindowHint 窗口無邊框 Qt.CustomizeWindowHint 有邊框,無標題欄與按鈕,不能移動和拖動 Qt.WindowTitleHint 添加標題欄與關閉按鈕 Qt.WindowSystemMenuHint 添加系統目錄和關閉按鈕 Qt.WindowMaximizeButtonHint 激活最大化按鈕與關閉按鈕,禁止最小化按鈕 Qt.WindowMinimizeButtonHint 激活最小化按鈕與關閉按鈕,禁止最大化按鈕 Qt.WindowMinMaxButtonsHint 激活最大化與最小化按鈕和關閉按鈕 Qt.WindowCloseButtonHint 添加一個關閉按鈕 Qt.WindowContextHelpButtonHint 添加問號與關閉按鈕,像對話框一樣 Qt.WindowStaysOnTopHint 窗口始終處於頂部位置 Qt.windowStaysOnButtonHint 窗口始終處於底部位置
2.11.4 案例
創建一個窗口,要求:
- 無邊框,無標題欄
- 窗口半透明
- 自定義最大化,最小化,關閉按鈕
- 支援拖拽用戶區移動
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
class Window(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setWindowTitle("案例") # 設置標題
self.move_flag = False # 默認沒有移動
self.resize(500, 500) # 設置窗口大小
self.move(300, 300) # 移動窗口
self.setWindowOpacity(0.9) # 設置窗口透明
self.setup_ui() # 調用創建控制項的方法
self.origin = () # 初始坐標,相對於窗口的
self.mouse = () # 滑鼠按下時,滑鼠相對於窗口的坐標
def setup_ui(self): # 添加控制項的操作
def close_w():
self.deleteLater() # 刪除主窗口
btn_close = QPushButton(self)
btn_close.clicked.connect(close_w)
btn_close.setText("X")
btn_close.move(self.width() - 25, 8)
def max_or_min(btn):
if self.isMaximized():
self.showNormal()
btn.setText("+")
else:
self.showMaximized()
btn.setText("-")
count = 1
self.findChild(QLabel).resize(self.width(), 45)
for i in self.findChildren(QPushButton):
i.move(self.width() - count * 25, 8) # 動態化設置按鍵的位置
count += 1
btn_maxOrMin = QPushButton(self)
btn_maxOrMin.move(self.width() - 50, 8)
btn_maxOrMin.clicked.connect(lambda: max_or_min(btn_maxOrMin))
btn_maxOrMin.setText("+")
qApp.setStyleSheet("""QPushButton{
font-size: 20px;
color: black;
font-weight: 800;
border: 2px solid black;
margin: 5px;
}""") # 設置樣式
# 設置窗口頭部框架
label = QLabel(self)
label.resize(self.width(), 45)
label.setStyleSheet("background-color: skyblue;")
label.lower()
# 設置窗口移動
def mousePressEvent(self, evt):
if evt.button() == Qt.LeftButton:
self.move_flag = True
self.mouse = (evt.globalX(), evt.globalY())
self.origin = (self.x(), self.y())
def mouseMoveEvent(self, evt):
self.move(evt.globalX() - self.mouse[0] + self.origin[0],
evt.globalY() - self.mouse[1] + self.origin[1]) if self.move_flag else None
def mouseReleaseEvent(self, *args, **kwargs):
self.move_flag = False
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口,同時無邊框,無標題欄
w = Window(flags=Qt.FramelessWindowHint)
# 顯示窗口
w.show()
sys.exit(app.exec_())
2.12 交互狀態
2.12.1 是否可見
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
"""
setEnabled(bool) # 設置控制項是否可用
isEnabled() # 獲取控制項是否可用
"""
app = QApplication(sys.argv)
w = QWidget()
btn = QPushButton(w)
btn.setText("點擊")
print(btn.isEnabled()) # 判斷按鈕是否可用
btn.pressed.connect(lambda: btn.setEnabled(False)) # 點擊後按鈕禁用
w.show()
sys.exit(app.exec_())
2.12.2 顯示和隱藏
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
"""
# 顯示和隱藏
setVisible(bool) # 設置控制項是否可見,傳遞的參數值為 True 也不一定可見,如果父控制項沒有展示,那麼子控制項為 True 也不可見
setHidden(bool) # 設置隱藏
show() # 設置顯示
hide() # 設置隱藏
isHidden() # 獲取相對於父控制項是否隱藏
isVisible() # 獲取是否可見
isVisibleTo(widget) # 獲取相對於widget控制項是否可見,即該控制項是否跟著widget控制項一起顯示
"""
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
btn = QPushButton(w)
print(btn.isVisible()) # 判斷控制項是否可見
btn.clicked.connect(lambda: btn.hide()) # 隱藏按鈕
print(w.isHidden()) # 判斷窗口是否隱藏
w.setVisible(True) # 使得窗口可見,先繪製父窗口
# w.setHidden(False) # 效果一樣
sys.exit(app.exec_())
2.12.3 是否可編輯
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
"""
setWindowModified(bool) # 設置是否被編輯
isWindowModified() # 窗口是否被編輯
"""
app = QApplication(sys.argv)
w = QWidget()
w.setWindowTitle("[*]交互狀態")
w.setWindowModified(True) # 可編輯狀態會顯示 [] 裡面的*號,即有 * 號就處於被編輯狀態
print(w.isWindowModified()) # 判斷窗口是否處於可編輯狀態
w.setVisible(True) # 和show作用類似
sys.exit(app.exec_())
2.12.4 是否為活躍窗口
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w1 = QWidget()
w2 = QWidget()
w2.show()
w1.show()
print(w2.isActiveWindow()) # 展示是否處於活躍窗口
print(w1.isActiveWindow())
sys.exit(app.exec_())
2.12.5 控制項關閉
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
"""
setAttribute(Qt.WA_DeleteOnClose, True) # 如果加了這行程式碼,窗口/控制項就會在關閉的同時刪除,效果和deleteLater類似
close() # 效果和setVisible類似
"""
app = QApplication(sys.argv)
w1 = QWidget()
w2 = QWidget()
w2.destroyed.connect(lambda: print("w2銷毀"))
w1.destroyed.connect(lambda: print("w1銷毀"))
w2.show()
w1.show()
w1.setAttribute(Qt.WA_DeleteOnClose, True) # 如果加了這行程式碼,窗口/控制項就會在關閉的同時刪除,效果和deleteLater類似
w1.close() # 效果和setVisible類似
w2.setVisible(False) # 使得窗口不可見,但是窗口並沒有刪除
w2.deleteLater() # 銷毀窗口/控制項
sys.exit(app.exec_())
2.12.6 案例
創建一個窗口,包含一個文本框和一個按鈕和一個標籤:
- 默認狀態下,標籤隱藏,文本框和按鈕顯示,按鈕為不可使用狀態
- 當文本框有內容時,讓按鈕可用,否則不可用
- 當文本框內容為kun時,點擊按鈕顯示標籤,並且展示文本為登錄成功,否則為失敗
涉及知識點:
- 文本框的創建
- QLineEdit類
- 文本框內容監測
- testChanged 訊號
- 文本框內容獲取
- text() 方法
- 按鈕狀態設置
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import hashlib
class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("案例[*]") # 設置標題
self.resize(500, 500) # 設置窗口大小
self.move(100, 100) # 移動窗口
self.setup_ui() # 調用創建控制項的方法
def setup_ui(self): # 添加控制項的操作 5 + 40 + 5 + 40 + 5
qApp.setStyleSheet("*{font-size: 15px; line-height: 15px;}") # 設置樣式
# 創建文本框
text = QLineEdit(self)
text.resize(300, 40)
text.move(100, 5)
def change_():
self.setWindowModified(True)
btn.setEnabled(len(text.text()) > 0) # 當有文本框內容時,按鈕可用
text.textChanged.connect(change_) # 綁定事件
# 創建按鈕
btn = QPushButton(self)
btn.resize(80, 40)
btn.setText("登錄")
btn.move(210, 50)
btn.setEnabled(False) # 按鈕不可用
def click_():
label.setVisible(True) # 顯示標籤
# 使用 hash 加密
salt = hashlib.md5("liu".encode("utf-8"))
salt.update(text.text().encode("utf-8"))
content = salt.hexdigest()
if content == 'a8b2a2561ec21479990c48706a743c9a': # 條件判斷
label.setText("登錄成功")
else:
label.setText("登錄失敗")
text.setText("")
self.setWindowModified(False)
btn.clicked.connect(click_) # 綁定事件
# 創建標籤
label = QLabel(self)
label.resize(100, 40)
label.move(220, 95)
label.setVisible(False) # 標籤隱藏
if __name__ == '__main__':
# 可以通過導包來運行窗口
import sys
app = QApplication(sys.argv)
# 創建窗口
w = Window()
# 顯示窗口
w.show()
sys.exit(app.exec_())
2.13 資訊提示
2.13.1 狀態提示
滑鼠懸停在空間上一會兒後,展示內容在狀態欄上面
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QMainWindow() # 使用組合窗口
w.resize(500, 500)
w.statusBar() # 創建狀態欄,可以顯示狀態提示
l = QLabel(w)
l.setStatusTip("這是資訊提示") # 設置狀態提示
l.setText("你好")
print(l.statusTip()) # 獲取狀態提示
w.show()
sys.exit(app.exec_())
2.13.2 工具提示
滑鼠懸停在控制項上一會兒後,展示在旁邊
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
l = QLabel(w)
l.setToolTip("這是一個工具提示")
l.setText("坤坤")
l.setToolTipDuration(1000) # 工具提示展示時間為 1 秒
print(l.toolTip()) # 獲取工具提示
w.show()
sys.exit(app.exec_())
2.13.3 意思提示
切換到查看這是啥模式,點擊該控制項時顯示
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
w = QWidget(flags=Qt.WindowContextHelpButtonHint) # 這是啥模式
w.resize(500, 500)
l = QLabel(w)
l.setWhatsThis("這是啥,這是一個意思提示") # 設置一個意思提示
l.setText("坤坤")
print(l.whatsThis()) # 獲取意思提示
w.show()
sys.exit(app.exec_())
2.14 焦點控制
2.14.1 單個控制項
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
"""
setFocus() # 指定控制項獲取焦點
setFocusPolicy(mode) # 設置焦點獲取策略
- 參數
Qt.TabFocus 通過 Tab 獲取焦點
Qt.ClickFocus 通過點擊獲取焦點
Qt.StrongFocus 通過以上兩種方式獲取焦點
Qt.NoFocus 不能通過以上兩種方式獲取焦點
clearFocus() # 取消焦點
"""
app = QApplication(sys.argv)
# 創建三個文本框
w = QWidget()
w.resize(500, 500)
t1 = QLineEdit(w)
t2 = QLineEdit(w)
t2.move(50, 50)
t2.setFocus() # 設置焦點
t2.setFocusPolicy(Qt.TabFocus) # 獲取焦點的方式
t2.clearFocus() # 取消焦點
t3 = QLineEdit(w)
t3.move(100, 100)
w.show()
sys.exit(app.exec_())
2.14.2 父控制項
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys
"""
focusWidget() # 獲取子控制項中當前焦距的控制項
focusNextChild() # 聚焦下一個子控制項
focusPreviousChild() # 聚焦上一個子控制項
focusNextPrevChild() # true:下一個 false:上一個
setTabOrder(pre_widget, next_widget) # 靜態方法,用於設置子控制項獲取焦點的先後順序
"""
app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
t1 = QLineEdit(w)
t1.setFocus() # 給 t1 設置焦點
t2 = QLineEdit(w)
t2.move(50, 50)
t3 = QLineEdit(w)
t3.move(100, 100)
w.show()
# QWidget.setTabOrder(t3, t2) # 按 tab 獲取焦點的順序 t3 > t2 > t1
w.focusNextChild() # 聚焦下一個子控制項
w.focusNextPrevChild(True) # 結果是t3有焦點
print(w.focusWidget()) # 獲取子控制項中當前焦距的控制項
sys.exit(app.exec_())
2.15 訊號
windowTitleChanged(QString) # 窗口標題改變訊號
windowIconChanged(QIcon) # 窗口圖標改變訊號
customContentMenuRequested(Qpoint) # 自定義上下文菜單請求訊號
基類控制項學習完成,下面我們開始學習具體的子類控制項