ID_main.py:
# 导入必要的库
from PyQt5.QtWidgets import QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton
from PyQt5.QtGui import QImage, QPixmap, QPainter, QPen, QColor
from PyQt5.QtSvg import QSvgRenderer
from PyQt5.QtCore import QTimer, Qt, QByteArray
import cv2
import sys
import os
class CircleButton(QPushButton):
def __init__(self, radius=35):
super().__init__()
self.radius = radius
self.setFixedSize(radius * 2, radius * 2)
self.setStyleSheet("""
QPushButton {
background-color: transparent;
border: none;
}
QPushButton:pressed {
background-color: rgba(224, 224, 224, 0.5);
}
""")
def paintEvent(self, event):
super().paintEvent(event)
painter = QPainter(self)
# 创建SVG内容
svg_content = f"""
<svg width="{self.radius * 2}" height="{self.radius * 2}" viewBox="0 0 {self.radius * 2} {self.radius * 2}">
<circle cx="{self.radius}" cy="{self.radius}" r="{self.radius}" fill="white"/>
<circle cx="{self.radius}" cy="{self.radius}" r="{self.radius * 3 // 4}" fill="none" stroke="black" stroke-width="1"/>
</svg>
"""
# 渲染SVG
svg_bytes = QByteArray(svg_content.encode('utf-8'))
renderer = QSvgRenderer(svg_bytes)
renderer.render(painter)
class ID_MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("摄像头实例")
self.cap = cv2.VideoCapture(0)
if not self.cap.isOpened():
sys.exit(1)
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.current_frame = None
self.setGeometry(100, 100, self.width, self.height)
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout(self.central_widget)
self.layout.setAlignment(Qt.AlignCenter)
self.camera_label = QLabel(self)
self.camera_label.setFixedSize(self.width, self.height)
self.layout.addWidget(self.camera_label)
# 创建悬浮窗
self.float_window = QLabel(self)
self.float_window.setGeometry(self.width - 210, 10, 200, 150)
self.float_window.setStyleSheet("""
QLabel {
background-color: rgba(255, 255, 255, 0.8);
border-radius: 10px;
padding: 10px;
font-size: 14px;
}
""")
self.float_window.raise_()
# 初始化列表数据
self.update_float_window(["项目1", "项目2", "项目3"])
self.capture_btn = CircleButton(radius=35)
self.capture_btn.setParent(self)
self.capture_btn.move(self.width // 2 - 35, self.height - 90)
self.capture_btn.clicked.connect(self.save_capture)
self.capture_btn.raise_()
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_frame)
self.timer.start(30)
def update_frame(self):
ret, frame = self.cap.read()
if ret:
self.current_frame = frame.copy()
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
h, w, ch = frame_rgb.shape
bytes_per_line = ch * w
q_image = QImage(frame_rgb.data, w, h, bytes_per_line, QImage.Format_RGB888)
pixmap = QPixmap.fromImage(q_image)
self.camera_label.setPixmap(pixmap)
def update_float_window(self, items):
"""更新悬浮窗内容"""
content = "<h4>列表内容</h4>"
for item in items:
content += f"• {item}<br>"
self.float_window.setText(content)
def save_capture(self):
if self.current_frame is not None:
save_dir = os.path.dirname(os.path.abspath(__file__))
filename = os.path.join(save_dir, f"capture_{cv2.getTickCount()}.png")
cv2.imwrite(filename, self.current_frame)
def resizeEvent(self, event):
super().resizeEvent(event)
if hasattr(self, 'capture_btn'):
self.capture_btn.move(self.width // 2 - 35, self.height - 90)
if hasattr(self, 'float_window'):
self.float_window.setGeometry(self.width - 210, 10, 200, 150)
def closeEvent(self, event):
if self.cap.isOpened():
self.cap.release()
event.accept()
main.py:
#添加类
import ID_main
import sys
import cv2
#关联文件
pass
from PyQt5.QtWidgets import QApplication, QMainWindow
from ID_main import ID_MainWindow
def main():
try:
app = QApplication(sys.argv)
window = ID_MainWindow()
window.show()
sys.exit(app.exec_())
except Exception as e:
print(f"错误: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()
库:
1.Python3
2.Python Debugger
3.Qtsvg