PyQt5是一个流行的Python库,用于创建图形用户界面(GUI)应用程序。它基于Qt库,是一个跨平台的开源框架,可用于创建各种类型的桌面应用程序。
跨平台性:PyQt5可以在多个操作系统上运行,包括Windows、Mac和Linux。这意味着可以在任何支持Python的平台上使用PyQt5来开发应用程序。
丰富的控件:PyQt5提供了大量的用户界面控件,包括按钮、文本框、标签、列表、表格、进度条等等。这些控件可以轻松地创建各种类型的GUI应用程序。
布局管理:PyQt5引入了一种称为布局管理的机制,它可以轻松地控制控件在窗口中的位置和大小。布局管理器可以根据窗口的大小和其他因素自动调整控件的大小和位置,使得应用程序在各种屏幕上都看起来很棒。
事件处理:PyQt5具有完善的事件处理系统,可以响应各种用户输入事件,如点击按钮、选择菜单项、拖放文件等等。通过编写事件处理函数来处理这些事件,以实现应用程序的交互性。
国际化:PyQt5支持国际化和本地化,这意味着你可以轻松地将你的应用程序翻译成不同的语言,以适应不同国家和地区的用户需求。
信号和槽机制:信号和槽机制是PyQt5中最重要的特性之一。当某个事件发生时(如用户点击按钮),一个信号会被发出。然后,这个信号连接到一个槽函数上,槽函数就会被调用。这种机制可以轻松地处理用户交互和执行相应的操作。
样式表:PyQt5支持样式表(Stylesheets),它是一种用于改变应用程序外观的机制。通过使用样式表来定制应用程序的外观,包括颜色、字体、边框等等。
动画效果:PyQt5提供了各种动画效果,如淡入淡出、滑动、旋转等等,可以使用这些效果来增强应用程序的用户体验。
工具和库:PyQt5附带了许多有用的工具和库,如Qt Designer、Qt Creator、QSS(类似于CSS)等等。这些工具和库可以更轻松地创建GUI应用程序。
Pythonic API:尽管PyQt5是基于Qt库的,但它提供了Pythonic的API,可以使用自然易懂的Python语法来编写代码。可以让我们更快速地开发GUI应用程序,而无需深入了解底层C++的细节。
PyQt5库的安装,可以查看这篇文章:完全弄懂如何用pycharm安装pyqt5及其相关配置
def GPU_CPU(self):
"""
选择 GPU or CPU
:return:
"""
selected_button = self.widget.sender()
if selected_button is not None and isinstance(selected_button, QRadioButton):
self.device = selected_button.text()
# 保存旧值
old_parameter = self.save_parameter.copy()
# 更新新值
self.save_parameter["device"] = self.device
# 如果参数值有变化
if old_parameter != self.save_parameter:
# 更新旧值
self.pre_parameter = old_parameter
def SelectData(self):
"""
模型类别选择
:return:
"""
self.data_file_name, _ = QFileDialog.getOpenFileName(self, "选择类别文件", "./", "所有文件(*.txt)")
if self.data_file_name:
self.label_6.setText(os.path.split(self.data_file_name)[-1])
old_parameter = self.save_parameter.copy()
self.save_parameter["label_txt"] = self.data_file_name
if old_parameter != self.save_parameter:
self.pre_parameter = old_parameter
def SelectWeights(self):
"""
模型权重选择
:return:
"""
self.weights_file_name, _ = QFileDialog.getOpenFileName(self, "选择权重文件", "./",
"所有文件(*.pt *.onnx *.ckpt)")
if self.weights_file_name:
self.label_7.setText(os.path.split(self.weights_file_name)[-1])
old_parameter = self.save_parameter.copy()
self.save_parameter["weights"] = self.weights_file_name
if old_parameter != self.save_parameter:
self.pre_parameter = old_parameter
def load_data(img, img_zize):
image_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
transform = transforms.Compose([
transforms.ToPILImage(),
transforms.Resize((img_zize, img_zize), Image.Resampling.NEAREST),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
if len(image_rgb.shape) == 2:
image_rgb = np.stack([image_rgb] * 3, 2)
image_rgb = transform(image_rgb)
image_rgb_batch = torch.unsqueeze(image_rgb, dim=0)
return image_rgb_batch
class WorkerThread(QThread):
"""
识别视频进程
"""
result_ready = pyqtSignal(int, np.ndarray, str, float)
def __init__(self, main_window):
super().__init__()
self.main_window = main_window
def run(self):
cap = cv2.VideoCapture(self.main_window.video_path)
if not cap.isOpened():
raise ValueError("Unable to open video file or cap")
count = 0
while True:
s_time = time.time()
ret, frame = cap.read()
if not ret or self.main_window.stop:
cap.release()
break
infer_class = self.main_window.label_dict[run_Infer(self.main_window.model, frame, self.main_window.img_size)]
# 将数据传递回渲染
self.result_ready.emit(count, frame, infer_class, s_time)
count += 1
time.sleep(0.01)
def show_all(self, count, img, infer_class, s_time):
infer_time = round(time.time() - s_time, 4)
cv2.putText(img, f'fps: {infer_time} class: {infer_class}', (10, 20), 0, 2 / 3, (255, 255, 255), thickness=1, lineType=cv2.LINE_AA)
self.label_9.setText(str(infer_time) + " s")
self.label_11.setText(infer_class)
self.vid_writer.write(img)
self.ShowSource(img)
self._print(f"推理图片源:{self.video_path}_{count},推理结果:{infer_class},推理时间:{infer_time} s")
【ResNet50 可视化界面】在电脑上实现可视化界面