【100天精通python】Day38:GUI界面編程_PyQT從入門到實戰(中)

目錄

??專欄導讀?

4 數據庫操作

4.1 連接數據庫

4.2 執行 SQL 查詢和更新:

4.3 使用模型和視圖顯示數據

?5 多線程編程

5.1 多線程編程的概念和優勢

5.2 在 PyQt 中使用多線程

5.3 處理多線程間的同步和通信問題

5.3.1 信號槽機制

5.3.2 線程安全的數據訪問

?QMutex 和 QMutexLocker


??專欄導讀?

專欄訂閱地址:https://blog.csdn.net/qq_35831906/category_12375510.html


4 數據庫操作

??????

????????PyQt6中的數據庫操作主要涉及到Qt的SQL模塊,該模塊提供了用于連接和管理數據庫的功能。下面是一個關于PyQt6數據庫操作的概述:

  1. 數據庫連接: 使用QSqlDatabase類建立與數據庫的連接。可以連接到各種數據庫引擎,例如SQLite、MySQL、PostgreSQL等。連接需要指定數據庫類型、主機、用戶名、密碼等信息。

  2. 數據庫查詢: 使用QSqlQuery類執行SQL查詢語句,例如SELECT、INSERT、UPDATE等。查詢結果可以通過迭代獲取。

  3. 模型-視圖架構: PyQt6提供了QSqlTableModelQSqlQueryModel等模型類,用于將數據庫數據與Qt的視圖類(如QTableView)連接起來。這使得在表格視圖中展示和編輯數據庫中的數據變得更加容易。

  4. 事務管理: 可以使用QSqlDatabase.transaction()QSqlDatabase.commit()來進行數據庫事務的管理,確保數據的一致性和完整性。

  5. 數據綁定: 使用bindValue()方法可以將變量綁定到SQL查詢,這有助于防止SQL注入攻擊。

  6. 錯誤處理: 數據庫操作可能會出現錯誤,通過檢查QSqlQuerylastError()可以獲取詳細的錯誤信息。

4.1 連接數據庫

使用 Qt 的 QSqlDatabase 類可以連接到數據庫。以下是一個簡單的示例:

from PyQt6.QtSql import QSqlDatabasedb = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("my_database.db")
if db.open():print("Connected to database")
else:print("Failed to connect")

4.2 執行 SQL 查詢和更新:

你可以使用 QSqlQuery 類來執行 SQL 查詢和更新操作。以下是一個示例:

from PyQt6.QtSql import QSqlQueryquery = QSqlQuery()
query.exec("SELECT * FROM employees")
while query.next():name = query.value("name")print("Employee name:", name)

4.3 使用模型和視圖顯示數據

????????Qt 提供了模型-視圖架構來顯示數據庫中的數據。例如,可以使用 QSqlTableModel 來在 QTableView 中顯示數據。以下是一個示例:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QTableView, QVBoxLayout, QWidget, QPushButton, QLineEdit, QDockWidget
from PyQt6.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
from PyQt6.QtCore import Qtclass AddDataDialog(QWidget):def __init__(self, model):super().__init__()self.model = modellayout = QVBoxLayout()self.setLayout(layout)# 添加姓名輸入框self.name_input = QLineEdit(self)layout.addWidget(self.name_input)# 添加職位輸入框self.position_input = QLineEdit(self)layout.addWidget(self.position_input)# 添加 "Add Data" 按鈕,并連接到添加數據函數add_button = QPushButton("Add Data", self)add_button.clicked.connect(self.add_data)layout.addWidget(add_button)def add_data(self):# 獲取姓名和職位輸入框的內容name = self.name_input.text()position = self.position_input.text()# 準備插入數據的SQL查詢query = QSqlQuery()query.prepare("INSERT INTO employees (name, position) VALUES (?, ?)")query.bindValue(0, name)query.bindValue(1, position)if query.exec():print("Data added successfully")self.model.select()  # 刷新表格數據else:print("Error adding data:", query.lastError().text())def create_database_connection():# 創建數據庫連接db = QSqlDatabase.addDatabase("QSQLITE")db.setDatabaseName("employees.db")if not db.open():print("Error: Could not open database.")return Nonereturn dbdef create_table(db):# 創建表格的SQL查詢query = QSqlQuery()query.exec("CREATE TABLE IF NOT EXISTS employees (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, position TEXT)")def setup_model(db):# 設置數據庫表格模型model = QSqlTableModel()model.setTable("employees")model.setEditStrategy(QSqlTableModel.EditStrategy.OnManualSubmit)  # 手動提交更改model.select()return modelif __name__ == "__main__":app = QApplication(sys.argv)db = create_database_connection()if not db:sys.exit(1)create_table(db)model = setup_model(db)view = QTableView()view.setModel(model)add_data_dialog = AddDataDialog(model)window = QMainWindow()window.setWindowTitle("Database Table Example")window.setCentralWidget(view)window.setGeometry(100, 100, 800, 600)add_data_button = QPushButton("Add Data", window)add_data_button.clicked.connect(add_data_dialog.show)# 創建 DockWidget 并添加到主窗口的右側停靠區dock_widget = QDockWidget("Add Data", window)dock_widget.setWidget(add_data_dialog)window.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, dock_widget)window.show()sys.exit(app.exec())

???

?5 多線程編程

5.1 多線程編程的概念和優勢

????????PyQt6中的多線程編程允許你在應用程序中同時執行多個任務,以提高性能、響應速度和資源利用率。在使用多線程時,你需要注意線程之間的同步和通信,以避免數據競爭和其他并發問題。以下是PyQt6多線程編程的概述:

  1. 線程類(QThread): QThread 是 PyQt6 提供的線程基類,用于創建和管理線程。你可以繼承 QThread 并實現 run() 方法來定義線程的執行邏輯。

  2. 線程安全性: 在多線程環境中,多個線程可能同時訪問和修改共享資源。確保對共享資源的訪問是線程安全的是很重要的,可以使用互斥鎖(QMutex)來控制對共享資源的訪問。

  3. 信號和槽機制: 在多線程中,通常不能直接在非主線程中更新用戶界面。可以使用信號和槽機制,通過在主線程中處理信號來更新界面,從而避免線程間的界面更新問題。

  4. 多線程的應用場景: 多線程在以下情況下特別有用:

    • 執行耗時操作,如文件讀寫、網絡請求等,以避免主線程阻塞。
    • 實現實時數據刷新,如傳感器數據、圖表數據等。
    • 并發處理多個任務,提高程序的整體性能。
  5. 線程同步和通信: 多線程編程需要考慮線程之間的同步和通信。合適的同步機制(如互斥鎖、信號量、條件變量等)和通信機制(如隊列、信號槽等)可以確保線程間的正確協作。

  6. 避免死鎖和線程饑餓: 死鎖和線程饑餓是多線程編程中常見的問題。確保正確地設計和組織線程同步和通信,以避免出現這些問題。

總之,多線程編程可以顯著提高應用程序的性能和響應能力,但也需要仔細考慮線程安全性和正確的同步機制。PyQt6提供了一些類和工具來幫助你實現多線程應用程序,但需要小心處理潛在的并發問題。

5.2 在 PyQt 中使用多線程

????????在 PyQt 中,你可以使用 QThread 類來創建和管理線程。以下是一個示例,演示如何在一個線程中執行一個耗時的任務:

from PyQt6.QtCore import QThread, pyqtSignalclass WorkerThread(QThread):result_ready = pyqtSignal(str)def run(self):# 執行耗時任務result = "Task result"self.result_ready.emit(result)thread = WorkerThread()
thread.result_ready.connect(lambda result: print("Result:", result))
thread.start()

5.3 處理多線程間的同步和通信問題

????????在多線程編程中,處理線程間的同步和通信問題是至關重要的,以確保數據的一致性和應用程序的穩定性。PyQt 提供了一些機制來幫助解決這些問題,其中最重要的是信號槽機制和線程安全的數據訪問。

5.3.1 信號槽機制

????????信號槽機制是 PyQt 中用于線程間通信的重要工具。它允許一個對象(信號的發出者)發出信號,而另一個對象(槽函數的接收者)將信號連接到槽函數,從而在信號觸發時執行相應的操作。這在多線程環境下特別有用,因為它避免了直接的線程間共享數據。

以下是一個簡單的示例,演示如何在多線程中使用信號槽機制:

import sys
from PyQt6.QtCore import QThread, pyqtSignal
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButtonclass WorkerThread(QThread):result_ready = pyqtSignal(str)def run(self):result = "Task result"self.result_ready.emit(result)class MyWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("Thread Communication Example")self.setGeometry(100, 100, 400, 300)self.button = QPushButton("Start Task", self)self.button.setGeometry(150, 150, 100, 30)self.button.clicked.connect(self.start_thread)def start_thread(self):self.thread = WorkerThread()self.thread.result_ready.connect(self.handle_result)self.thread.start()def handle_result(self, result):print("Result:", result)if __name__ == "__main__":app = QApplication(sys.argv)window = MyWindow()window.show()sys.exit(app.exec())

??

5.3.2 線程安全的數據訪問

????????當多個線程同時訪問共享數據時,很容易出現競爭條件和數據不一致的問題。為了避免這些問題,你需要使用互斥鎖(mutex)來保護共享數據的訪問。PyQt 中的 QMutex 和 QMutexLocker 可以幫助你實現線程安全的數據訪問。

以下是一個簡單的示例,演示如何在多線程中安全地訪問共享數據:

import sys
from PyQt6.QtCore import QThread, QMutex, QMutexLockerclass SharedData:def __init__(self):self.mutex = QMutex()  # 用于保護共享數據的互斥鎖self.data = 0def increment(self):locker = QMutexLocker(self.mutex)  # 加鎖self.data += 1class WorkerThread(QThread):def __init__(self, shared_data):super().__init__()self.shared_data = shared_datadef run(self):for _ in range(10):self.shared_data.increment()if __name__ == "__main__":shared_data = SharedData()  # 創建共享數據對象threads = [WorkerThread(shared_data) for _ in range(4)]  # 創建多個工作線程for thread in threads:thread.start()  # 啟動工作線程for thread in threads:thread.wait()  # 等待所有工作線程完成print("Shared data:", shared_data.data)  # 打印最終共享數據的值

輸出:?

?????????在這個示例中,每個工作線程在循環中執行10次的增量操作,使用互斥鎖確保在任何時候只有一個線程可以訪問和修改SharedData對象的data屬性。這樣可以避免數據競爭和不一致的情況。

????????注意,這個示例使用了Python中的多線程和互斥鎖,與Qt中的線程和互斥鎖略有不同。確保你的環境中同時存在Qt庫和Python的線程支持(例如PyQt6.QtCorethreading庫),以便代碼可以正確運行。

5.4?避免死鎖和線程饑餓

????????避免死鎖和線程饑餓是多線程編程中的關鍵問題。死鎖指的是多個線程彼此等待對方釋放鎖,導致程序無法繼續執行。線程饑餓是指某個線程長時間無法獲得所需的資源或鎖,導致其他線程占用資源,使得該線程無法繼續執行。以下是在PyQt6中避免死鎖和線程饑餓的詳解和示例:

避免死鎖:

  1. 有序獲取鎖: 當多個線程需要獲取多個鎖時,確保它們按照相同的順序獲取鎖,這可以減少死鎖的風險。

  2. 超時機制: 在獲取鎖時使用超時機制,如果無法在一定時間內獲取鎖,就放棄并釋放已有的鎖。

避免線程饑餓:

  1. 公平性: 使用公平的鎖和資源分配策略,確保所有線程都有平等的機會獲得資源,避免某個線程長時間無法獲得所需資源。

  2. 優先級: 在某些情況下,可以通過為線程設置不同的優先級,確保高優先級線程不會長時間無法獲得資源。

以下是一個簡單的示例,展示如何在PyQt6中使用QMutex來避免死鎖和線程饑餓:

import sys
from PyQt6.QtCore import QThread, QMutex, QMutexLocker# 共享資源類,用于展示互斥鎖的使用來避免死鎖和線程饑餓
class SharedResource:def __init__(self):self.mutex1 = QMutex()  # 第一個互斥鎖self.mutex2 = QMutex()  # 第二個互斥鎖def process1(self):with QMutexLocker(self.mutex1):  # 獲取第一個鎖print("Process 1: Mutex 1 locked")QThread.msleep(100)  # 模擬處理時間with QMutexLocker(self.mutex2):  # 獲取第二個鎖print("Process 1: Mutex 2 locked")def process2(self):with QMutexLocker(self.mutex2):  # 獲取第二個鎖print("Process 2: Mutex 2 locked")QThread.msleep(100)  # 模擬處理時間with QMutexLocker(self.mutex1):  # 獲取第一個鎖print("Process 2: Mutex 1 locked")class WorkerThread(QThread):def __init__(self, shared_resource, process_func):super().__init__()self.shared_resource = shared_resourceself.process_func = process_funcdef run(self):self.process_func()if __name__ == "__main__":shared_resource = SharedResource()thread1 = WorkerThread(shared_resource, shared_resource.process1)thread2 = WorkerThread(shared_resource, shared_resource.process2)thread1.start()  # 啟動線程1thread2.start()  # 啟動線程2thread1.wait()  # 等待線程1完成thread2.wait()  # 等待線程2完成print("Main thread exited")  # 主線程退出

?????????在這個示例中,兩個線程分別嘗試獲取兩個不同的鎖(mutex1和mutex2)。通過始終以相同的順序獲取鎖,可以避免死鎖。同時,通過在獲取鎖時使用QMutexLocker,可以確保線程在離開作用域時釋放鎖。

????????需要注意的是,死鎖和線程饑餓是復雜的問題,可能在更復雜的場景中出現。避免死鎖和線程饑餓需要仔細的設計和測試,以確保線程在協同工作時能夠正確地進行同步和協調。

?QMutexQMutexLocker

QMutexQMutexLocker 是 PyQt 中用于線程同步的兩個重要類。它們幫助確保多個線程在訪問共享資源時的正確同步,以避免競爭條件和數據不一致。下面是關于它們的詳解和示例:

QMutex(互斥鎖): 互斥鎖是一種線程同步機制,用于控制多個線程對共享資源的訪問。在多線程環境中,一個線程可以獲得互斥鎖的所有權,從而可以安全地訪問共享資源。其他線程在獲取互斥鎖之前必須等待,以確保同一時間只有一個線程可以訪問共享資源。

示例代碼:

from PyQt6.QtCore import QMutexmutex = QMutex()def thread_function():mutex.lock()# 訪問共享資源mutex.unlock()# 創建多個線程,每個線程執行 thread_function

QMutexLocker(互斥鎖鎖定器): QMutexLockerQMutex 的一個輔助類,它在創建時自動鎖定 QMutex,并在銷毀時釋放鎖。這樣可以確保在一個作用域內,線程在獲取鎖后能夠正確地釋放鎖,從而避免忘記釋放鎖而導致的死鎖。

示例代碼:

from PyQt6.QtCore import QMutex, QMutexLockermutex = QMutex()def thread_function():with QMutexLocker(mutex):  # 進入作用域時自動鎖定,離開作用域時自動釋放# 訪問共享資源# 創建多個線程,每個線程執行 thread_function

????????在使用 QMutexLocker 時,當線程離開作用域(例如使用 with 語句),會自動釋放鎖,無論是否發生異常。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40483.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40483.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40483.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

日常BUG——通過命令行創建vue項目報錯

😜作 者:是江迪呀??本文關鍵詞:日常BUG、BUG、問題分析??每日 一言 :存在錯誤說明你在進步! 一、問題描述 在使用vue命令行創建一個vue項目時,出現一下的錯誤: vue create my…

UDP數據報結構分析(面試重點)

在傳輸層中有UDP和TCP兩個重要的協議,下面將針對UDP數據報的結構進行分析 UDP結構圖示 UDP報頭結構的分析 UDP報頭有4個屬性,分別是源端口,目的端口,UDP報文長度,校驗和,它們都占16位2個字節,所…

.devos勒索病毒解密方法|勒索病毒解決|勒索病毒恢復|數據庫修復

導言: 隨著科技的迅猛發展,網絡安全問題也日益凸顯。近期,一種名為 .devos 的勒索病毒在網絡安全領域引起了廣泛的關注和警惕。本文91數據恢復將 探討如何解密被其加密的數據文件,并提供預防措施以避免受到類似威脅的侵害。 如不幸…

【java面向對象中static關鍵字】

提綱 static修飾成員變量static修飾成員變量的應用場景static修飾成員方法static修飾成員方法的應用場景static的注意事項static的應用知識:代碼塊static的應用知識:單例設計模式 static靜態的意思,可以修飾成員變量,成員方法&a…

FPGA_學習_14_第一個自寫模塊的感悟和ila在線調試教程與技巧(尋找APD的擊穿偏壓)

前一篇博客我們提到了,如果要使用算法找到Vbr,通過尋找APD采集信號的噪聲方差的劇變點去尋找Vbr是一個不錯的方式。此功能的第一步是在FPGA中實現方差的計算,這個我們已經在上一篇博客中實現了。 繼上一篇博客之后,感覺過了很久了…

【Image captioning】ruotianluo/self-critical.pytorch之1—數據集的加載與使用

【Image captioning】ruotianluo/self-critical.pytorch之1—數據集的加載與使用 作者:安靜到無聲 個人主頁 數據加載程序示意圖 使用方法 示例代碼 #%%from __future__ import absolute_import from __future__ import division from __future__ import print_…

Flink-網絡流控及反壓剖析

參考: Apache Flink學習網

開源,微信小程序 美食便簽地圖(FoodNoteMap)的設計與開發

目錄 0 前言 1 美食便簽地圖簡介 2 美食便簽地圖小程序端開發 2.1技術選型 2.2前端UI設計 2.3主頁界面 2.4個人信息界面 2.5 添加美食界面 2.6美食便簽界面 2.8 美食好友界面 2.9 美食圈子界面 2.10 子頁面-店鋪詳情界面 2.11 后臺數據緩存 2.12 訂閱消息通知 2.1…

Redis為什么能如此之快

推薦閱讀 AI文本 OCR識別最佳實踐 AI Gamma一鍵生成PPT工具直達鏈接 玩轉cloud Studio 在線編碼神器 玩轉 GPU AI繪畫、AI講話、翻譯,GPU點亮AI想象空間 資源分享 「java、python面試題」來自UC網盤app分享,打開手機app,額外獲得1T空間 https://dr…

“深入探索JVM內部機制:解密Java虛擬機原理“

標題:深入探索JVM內部機制:解密Java虛擬機原理 摘要:本文將深入探索Java虛擬機(JVM)的內部機制,揭示其工作原理和關鍵組成部分,包括類加載、內存管理、垃圾回收、即時編譯和運行時數據區域等。…

探索區塊鏈世界:去中心化應用(DApp)的嶄新前景

隨著科技的不斷發展,區塊鏈技術逐漸引領著數字時代的潮流。在這個充滿創新和變革的領域中,去中心化應用(DApp)成為了備受矚目的焦點。DApp 不僅改變了傳統應用程序的范式,還在金融、社交、游戲等多個領域展現出了廣闊的…

GRPC 鏈接 NODE 和 GOLANG

GRPC 鏈接 NODE 和 GOLANG GRPC 了解 什么是GRPC gRPC 采用了 Protocol Buffers 作為數據序列化和反序列化的協議,可以更快速地傳輸數據,并支持多種編程語言的跨平臺使用gRPC 提供“統一水平層”來對此類問題進行抽象化。 開發人員在本機平臺中編寫專…

打造專屬照片分享平臺:快速上手Piwigo網頁搭建

文章目錄 通過cpolar分享本地電腦上有趣的照片:部署piwigo網頁前言1.Piwigo2. 使用phpstudy網頁運行3. 創建網站4. 開始安裝Piwogo 總結 🍀小結🍀 🎉博客主頁:小智_x0___0x_ 🎉歡迎關注:&#x…

深度學習1:通過模型評價指標優化訓練

P(Positive)表示預測為正樣本,N(negative)表示預測為負樣本,T(True)表示預測正確,F(False)表示預測錯誤。 TP:正樣本預測正確的數量(正確檢測) FP:負樣本預測正確數量(誤檢測) TN…

【AI實戰】BERT 文本分類模型自動化部署之 dockerfile

【AI實戰】BERT 文本分類模型自動化部署之 dockerfile BERTBERT 文本分類模型基于中文預訓練bert的文本分類模型針對多分類模型的loss函數樣本不均衡時多標簽分類時 dockerfile編寫 dockerfilebuild鏡像運行docker測試服務 參考 本文主要介紹: 基于BERT的文本分類模…

卷積神經網絡CNN

卷積神經網絡CNN 1 應用領域1 檢測任務2 分類和檢索3 超分辨率重構4 醫學任務5 無人駕駛6 人臉識別 2 卷積的作用3 卷積特征值計算方法4 得到特征圖表示5 步長和卷積核大小對結果的影響1 步長2 卷積核 6 邊緣填充方法7 特征圖尺寸計算與參數共享8 池化層的作用9 整體網絡架構10…

【GitLab私有倉庫】如何在Linux上用Gitlab搭建自己的私有庫并配置cpolar內網穿透?

文章目錄 前言1. 下載Gitlab2. 安裝Gitlab3. 啟動Gitlab4. 安裝cpolar5. 創建隧道配置訪問地址6. 固定GitLab訪問地址6.1 保留二級子域名6.2 配置二級子域名 7. 測試訪問二級子域名 前言 GitLab 是一個用于倉庫管理系統的開源項目,使用Git作為代碼管理工具&#xf…

ngModel和formControlName處理表單控件

ngModel 和 formControlName 不能同時在同一個表單控件上使用; 二者都用于在 Angular 中處理表單控件的值,但是它們的底層實現方式不同。 ngModel 是 Angular 提供的雙向數據綁定指令,它可以將表單控件的值與組件類中的屬性進行雙向綁定。當…

軟考筆記——10.項目管理

進度管理 進度管理就是采用科學的方法,確定進度目標,編制進度計劃和資源供應計劃,進行進度控制,在與質量、成本目標協調的基礎上,實現工期目標。 具體來說,包括以下過程: (1) 活動定義&#…

HLS實現FIR低通濾波器+System Generator仿真

硬件:ZYNQ7010 軟件:MATLAB 2019b、Vivado 2017.4、HLS 2017.4、System Generator 2017.4 1、MATLAB設計低通濾波器 FPGA系統時鐘 50MHz,也是采樣頻率。用 MATLAB 生成 1MHz 和 10MHz 的正弦波疊加的信號,并量化為 14bit 整數。把…