python3+pyqt5+opencv3簡單使用(轉載)
關於python3下搭建pyqt5(pycharm)參考這條鏈接。
對於pyqt的使用個人比較建議ui設計與邏輯功能分開開發。
下面介紹下簡單的使用(通過左側的目錄可直接跳轉到相應模塊):
ui界面的建立
通過pycharm的Tools->External Tools->QtDesigner打開界面設計窗口(本文以創建一個Main Window為例)。
通過拖拽可以簡單的設計界面,設計好后保存UI文件(本文創建的文件名為GUI),對UI文件點擊鼠標反鍵選擇External Tools->PyUIC,會生成一個對應UI界面的GUI.py文件。
接下來為了讓UI設計文件與邏輯功能文件分開,在新建一個py文件,導入剛生成的GUI.py中的 Ui_MainWindow。
-
import sys
-
import cv2
-
from PyQt5 import QtCore, QtGui, QtWidgets
-
from PyQt5.QtCore import *
-
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QDockWidget, QListWidget
-
from PyQt5.QtGui import *
-
-
from GUI import Ui_MainWindow # 導入創建的GUI類
-
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
if __name__ == '__main__':
-
app = QtWidgets.QApplication(sys.argv)
-
window = mywindow()
-
window.show()
-
sys.exit(app.exec_())
OK!一個超級簡單的UI設計以及UI的調用全部完成。
接下來再寫點基礎UI開發中常用到的功能:
PyQt窗口界面位置以及透明度調節
下面介紹幾個函數用來調節窗口界面的位置以及界面邊框和背景的隱藏。
在邏輯功能文件的初始化中進行設置:
-
import sys
-
import cv2
-
from PyQt5 import QtCore, QtGui, QtWidgets
-
from PyQt5.QtCore import *
-
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QDockWidget, QListWidget
-
from PyQt5.QtGui import *
-
-
from main_window import Ui_MainWindow # 導入創建的GUI類
-
-
class mywindow(QtWidgets.QMainWindow, Ui_MainWindow):
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
# setting main window geometry
-
desktop_geometry = QtWidgets.QApplication.desktop() # 獲取屏幕大小
-
main_window_width = desktop_geometry.width() # 屏幕的寬
-
main_window_height = desktop_geometry.height() # 屏幕的高
-
rect = self.geometry() # 獲取窗口界面大小
-
window_width = rect.width() # 窗口界面的寬
-
window_height = rect.height() # 窗口界面的高
-
x = (main_window_width - window_width) // 2 # 計算窗口左上角點橫坐標
-
y = (main_window_height - window_height) // 2 # 計算窗口左上角點縱坐標
-
self.setGeometry(x, y, window_width, window_height) # 設置窗口界面在屏幕上的位置
-
-
# 無邊框以及背景透明一般不會在主窗口中用到,一般使用在子窗口中,例如在子窗口中顯示gif提示載入信息等等
-
self.setWindowFlags(Qt.FramelessWindowHint) # 無邊框
-
self.setAttribute(Qt.WA_TranslucentBackground) # 背景透明
-
Pyqt中的常用小控件
QPushbutton的簡單使用
首先打開QtDesigner通過鼠標添加一個pushbutton,雙擊進行更改pushbutton的text。
接下來對pushbutton反鍵選擇Change objectName進行修改,這個名稱是在邏輯功能設計時調用的名稱。重要!
修改完之后進行保存,記得每次修改后都要對UI文件反鍵進行External Tools->PyUIC操作對GUI.py文件進行更新。
接着進入邏輯功能文件,添加pushbutton對應的響應函數與槽連接。
設計pushbutton點擊對應的響應函數:
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
def pushbutton_fuction(self): # pushbutton對應的響應函數
-
# do some things
添加槽連接:
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
self.one_pushButton.clicked.connect(self.pushbutton_fuction) # one_pushButton是對應的objectName
-
# 將點擊事件與槽函數進行連接
-
def pushbutton_fuction(self):
-
# do some things
QLabel與opencv讀取並顯示圖片
首先添加一個QLabel,修改text內容以及Change objectName.
接下來我們要實現通過點擊一個pushbutton在QLabel中顯示一張圖片。
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
self.one_pushButton.clicked.connect(self.pushbutton_fuction)
-
-
def pushbutton_fuction(self):
-
Im = cv2.imread('***.jpg') # 通過Opencv讀入一張圖片
-
image_height, image_width, image_depth = Im.shape # 獲取圖像的高,寬以及深度。
-
QIm = cv2.cvtColor(Im, cv2.COLOR_BGR2RGB) # opencv讀圖片是BGR,qt顯示要RGB,所以需要轉換一下
-
QIm = QImage(QIm.data, image_width, image_height, # 創建QImage格式的圖像,並讀入圖像信息
-
image_width * image_depth,
-
QImage.Format_RGB888)
-
self.image_label.setPixmap(QPixmap.fromImage(QIm)) # 將QImage顯示在之前創建的QLabel控件中
如果想讓圖片適應QLabel的大小,在 __init__中添加一行代碼:
self.image_label.setScaledContents(True)
如果想自定義QLabel的大小以及位置,可以用:
self.image_label.setGeometry(x, y, width, height)
QLineEdit的讀取與寫入
QLineEdit控件常用的就是讀取與寫入兩個功能:
-
self.my_lineEdit.text() # 讀取QLineEdit中的內容
-
self.my_lineEdit.setText('show some text') # 將字符串寫入QLineEdit中
-
self.my_lineEdit.clear() # 清除QLineEdit中的信息
QCheckBox的使用
QCheckBox主要是檢查其勾選狀態,或者連接改變狀態觸發事件,常用函數如下:
-
self.my_checkbox.stateChanged.connect(self.related_function) # 將checkbox狀態變化事件連接相應函數
-
-
self.my_checkbox.isChecked() # 檢查checkbox是否被勾選
-
-
self.my_checkbox.setCheckState(QtCore.Qt.Unchecked) # 將checkbox狀態設置為未勾選狀態
-
# QtCore.Qt.Checked 為勾選狀態
QCombo box的使用
首先通過QtDesigner將Comb box控件托至界面中,雙擊Combo box控件在彈出的界面中點擊左下角的加號添加選項:
獲取Combo box選擇信息的常用方法主要有兩種,一種是獲取選項的index一種是直接獲取選項的文本。
-
self.image_type_comboBox.currentIndex() # 獲取當前選項的Index(int)
-
self.image_type_comboBox.currentText() # 獲取當前選項的文本(Qstring)
QMovie的使用
QMovie可將gif動態圖在label中進行顯示。用起來也非常簡單。
-
Movie = QMovie( 'time.gif') # 載入Gif圖,注意QMovie在PyQt5.QtCore內
-
self.movie_label.setMovie(Movie) # 將gif顯示在gif中
-
Movie.start() # 啟動gif
-
Movie.stop() # 停止gif
pyqt界面的布局與資源文件的載入
在界面開發過程中若不對界面進行布局則導致界面縮放過程中各控件不會跟着調整使得界面非常的難看,該部分由於圖片較多,故單獨寫在一個博文里,詳情見鏈接。
pyqt中的常用小功能
通過QFileDialog選擇文件或者文件夾
-
directory = QFileDialog.getExistingDirectory(self,
-
"選取文件夾",
-
"D:/") # 打開路徑為D盤,若不指定路徑,默認打開當前py文件所在文件夾
-
fileName, filetype = QFileDialog.getOpenFileName(self,
-
"選取文件",
-
"C:/",
-
"Image Files (*.jpg);;Text Files (*.txt)") # 設置文件擴展名過濾,
-
# 注意用雙分號間隔
QMessageBox簡單用法
information框:
QMessageBox.information(self, 'Information', '提示消息')
question框:
-
reply = QMessageBox.question(self,
-
"question",
-
"選擇是或否",
-
QMessageBox.Yes | QMessageBox.No)
DateTime獲取當前時間命名文件
通常保存圖片或者文件時,會經常糾結如何命名文件,別想了直接用時間命名吧!
-
time = datetime.datetime.now().strftime( '%Y-%m-%d-%H-%M-%S') # import datetime
-
save_file_name = time + '.jpg'
-
cv2.imwrite(save_file_name, save_image)
PyQt菜單欄的創建
首先打開Qt Designer,在界面的最上端雙擊“Type Here”輸入“File(&F)”后按回車鍵,創建一級菜單,如圖所示,(&F)表示通過“Alt + F”快捷鍵直接打開。同理創建二級菜單等。
創建好菜單后在右側menuFile_F一級菜單下可以看到相應menu名稱,例如圖中創建的Open file二級菜單對應的名稱為actionOpen_file_O
接下來在邏輯功能文件中的__init__函數下進行槽連接即可。
self.actionOpen_file_O.triggered.connect(self.open_file_function)
PyQt底部狀態欄
狀態欄的使用主要是顯示一些信息,便於使用。主要使用兩個函數:
-
self.statusBar().showMessage() # 顯示字符串
-
self.statusBar().clearMessage() # 清除字符串
PyQt創建子界面
首先新建一個UI文件(Widget)sub_window.py以及相應的邏輯功能文件sub_main.py。
創建相應的邏輯文件sub_main.py(要將創建的子UI界面導入):
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QDockWidget, QListWidget
from PyQt5.QtGui import *
from sub_window import Ui_Form # 導入子UI界面
class secondwindow(QtWidgets.QWidget, Ui_Form): # 創建子UI類
def __init__(self):
super(secondwindow, self).__init__()
self.setupUi(self)
接着在主邏輯文件中導入子類,並進行實例化:
-
import sys
-
import cv2
-
from PyQt5 import QtCore, QtGui, QtWidgets
-
from PyQt5.QtCore import *
-
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QDockWidget, QListWidget
-
from PyQt5.QtGui import *
-
-
from GUI import Ui_MainWindow
-
from sub_main import secondwindow # 導入子UI類
-
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
self.second_window = secondwindow() # 實例化子界面
-
self.one_pushButton.clicked.connect(pushbutton_fuction) # 槽函數連接
-
-
def pushbutton_fuction(self):
-
self.second_window.show() # 通過點擊按鈕彈出子界面
-
-
if __name__ == '__main__':
-
app = QtWidgets.QApplication(sys.argv)
-
window = mywindow()
-
window.show()
-
sys.exit(app.exec_())
注意:本示例創建的子窗口繼承自QWidget,是非模態化的窗口(可以同時在子窗口和主窗口上進行操作)。若要創建一個模態化的窗口(只有在關閉子窗口后才能對主窗口進行操作),需要繼承自QDialog,實例化並打開窗口代碼如下:
-
self.second_window = secondwindow() # 實例化子界面,注意secondwindow繼承自QDialog
-
self.second_window.exec_() # 打開子窗口,注意和非模態化不同
創建pyqt信號並進行連接
在主邏輯文件中創建pyqt信號傳遞到子窗口中:
-
import sys
-
import cv2
-
from PyQt5 import QtCore, QtGui, QtWidgets
-
from PyQt5.QtCore import *
-
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QDockWidget, QListWidget
-
from PyQt5.QtGui import *
-
-
from GUI import Ui_MainWindow
-
from sub_main import secondwindow
-
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
emit_image_signal = pyqtSignal(QImage) # 創建pyqt信號,指定傳遞的變量類型為QImage
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
self.second_window = secondwindow() # 實例化子界面
-
-
self.one_pushButton.clicked.connect(pushbutton_fuction)
-
self.emit_image_signal.connect(self.second_window.show_label) # 將pyqt信號連接到
-
# 子窗口的show_label()函數
-
-
def pushbutton_fuction(self):
-
Im = cv2.imread('***.jpg') # 通過Opencv讀入一張圖片
-
image_height, image_width, image_depth = Im.shape # 獲取圖像的高,寬以及深度。
-
QIm = cv2.cvtColor(Im, cv2.COLOR_BGR2RGB) # opencv讀圖片是BGR,qt顯示要RGB,所以需要轉換一下
-
QIm = QImage(QIm.data, image_width, image_height, # 創建QImage格式的圖像,並讀入圖像信息
-
image_width * image_depth,
-
QImage.Format_RGB888)
-
self.second_window.show() # 彈出子窗口
-
self.emit_image_signal.emit(QIm) # 釋放pyqt信號
-
-
if __name__ == '__main__':
-
app = QtWidgets.QApplication(sys.argv)
-
window = mywindow()
-
window.show()
-
sys.exit(app.exec_())
在子邏輯文件中接收pyqt信號並繪制圖像:
-
class secondwindow(QtWidgets.QWidget, Ui_Form): # 創建子UI類
-
-
def __init__(self):
-
super(secondwindow, self).__init__()
-
self.setupUi(self)
-
-
def show_label(self, QIm)
-
self.image_label.setPixmap(QPixmap.fromImage(QIm)) # 將傳遞進來的圖片顯示在創建好的QLabel控件中
pyqt鼠標事件
使用鼠標事件首先要開啟鼠標跟蹤,接着重寫鼠標事件:
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
self.setMouseTracking(True) # 開啟鼠標跟蹤
-
self.centralwidget.setMouseTracking(True)
-
self.image_label.setMouseTracking(True) # 在image_label中開啟鼠標跟蹤
-
-
def mouseMoveEvent(self, a0: QtGui.QMouseEvent): # 鼠標移動事件
-
# a0.x() -> x坐標 ; a0.y() -> y坐標
-
-
def mousePressEvent(self, a0: QtGui.QMouseEvent): # 鼠標點擊事件
-
if a0.button() == Qt.LeftButton: # 按下鼠標左鍵
-
# do something
-
if a0.button() == Qt.RightButton: # 按下鼠標右鍵
-
# do something
-
if a0.button() == Qt.MidButton: # 按下鼠標中間
-
# do something
-
-
def mouseReleaseEvent(self, a0: QtGui.QMouseEvent): # 鼠標釋放事件
-
# do something
pyqt多線程的簡單使用
pyqt多線程的使用,主要是先創建一個線程類,接着在主線程中進行實例化並開啟線程。
首先創建一個線程類,新建一個py文件:
-
import cv2
-
from PyQt5 import QtCore, QtGui, QtWidgets
-
from PyQt5.QtCore import *
-
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QDockWidget, QListWidget
-
from PyQt5.QtGui import *
-
-
class mythread(QThread):
-
-
def __init__(self, parent=None):
-
super(mythread, self).__init__()
-
-
def __del__(self):
-
self.wait()
-
-
def run(self):
-
# do something
接着在主函數中導入自定義線程類,實例化並開啟:
-
import sys
-
import cv2
-
from PyQt5 import QtCore, QtGui, QtWidgets
-
from PyQt5.QtCore import *
-
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QDockWidget, QListWidget
-
from PyQt5.QtGui import *
-
-
from GUI import Ui_MainWindow
-
from costom_thread import mythread # 導入自定義線程類
-
-
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
-
-
def __init__(self):
-
super(mywindow, self).__init__()
-
self.setupUi(self)
-
-
self.one_pushButton.clicked.connect(pushbutton_fuction) # 槽函數連接
-
self.sub_thread = mythread() # 實例化新線程
-
-
def pushbutton_fuction(self):
-
self.sub_thread.start() # 開啟新線程
-
-
if __name__ == '__main__':
-
app = QtWidgets.QApplication(sys.argv)
-
window = mywindow()
-
window.show()
-
sys.exit(app.exec_())
原文鏈接:https://blog.csdn.net/qq_37541097/article/details/79143898