Pyqt5 Qstackedwidget импорт своего класса
Господа, есть вопрос ...
В общем:
- файл
gui.py(описание формы приложения).
- файл
main.py(общий принцип работы приложения).
- файл
video.py(это stackedwidget c currenet(1)).
Так я, для нормальной конструкции всего кода, хочу разделить отдельные виджеты на разных страницах на разные классы и хранить в отдельных файлах. И все эти отдельные классы с описанием функционала импортить в main.py в главный класс.
Вот как прописать класс из video.py чтобы он работал в main.py?
gui.py
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(534, 325)
Form.setStyleSheet("background-color: rgb(1, 203, 170);")
self.stackedWidget = QtWidgets.QStackedWidget(Form)
self.stackedWidget.setGeometry(QtCore.QRect(20, 70, 491, 241))
self.stackedWidget.setObjectName("stackedWidget")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.label = QtWidgets.QLabel(self.page)
self.label.setGeometry(QtCore.QRect(80, 70, 311, 101))
font = QtGui.QFont()
font.setPointSize(25)
self.label.setFont(font)
self.label.setObjectName("label")
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.label_2 = QtWidgets.QLabel(self.page_2)
self.label_2.setGeometry(QtCore.QRect(30, 30, 331, 191))
font = QtGui.QFont()
font.setPointSize(30)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.pushButton_3 = QtWidgets.QPushButton(self.page_2)
self.pushButton_3.setGeometry(QtCore.QRect(380, 110, 75, 23))
self.pushButton_3.setStyleSheet("background-color: rgb(255, 85, 255);")
self.pushButton_3.setObjectName("pushButton_3")
self.stackedWidget.addWidget(self.page_2)
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(70, 20, 75, 23))
self.pushButton.setStyleSheet("background-color: rgb(0, 85, 255);")
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(Form)
self.pushButton_2.setGeometry(QtCore.QRect(400, 20, 75, 23))
self.pushButton_2.setStyleSheet("background-color: rgb(255, 85, 0);")
self.pushButton_2.setObjectName("pushButton_2")
self.retranslateUi(Form)
self.stackedWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "Simple first page"))
self.label_2.setText(_translate("Form", "Video on opencv"))
self.pushButton_3.setText(_translate("Form", "start"))
self.pushButton.setText(_translate("Form", "Main"))
self.pushButton_2.setText(_translate("Form", "Video"))
main.py
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from simple.gui import Ui_Form
class MainClass(QtWidgets.QMainWindow, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton_2.clicked.connect(lambda : self.stackedWidget.setCurrentIndex(1))
self.pushButton.clicked.connect(lambda : self.stackedWidget.setCurrentIndex(0))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
win = MainClass()
win.show()
sys.exit(app.exec_())
video.py
import cv2
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget
from simple.gui import Ui_Form
class VideoStream(QWidget, Ui_Form):
# class constructor
def __init__(self):
# call QWidget constructor
super().__init__()
self.setupUi(self)
# create a timer
self.timer = QTimer()
# set timer timeout callback function
self.timer.timeout.connect(self.viewCam)
# set control_bt callback clicked function
self.pushButton_3.clicked.connect(self.controlTimer)
# view camera
def viewCam(self):
# read image in BGR format
ret, image = self.cap.read()
# convert image to RGB format
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# get image infos
height, width, channel = image.shape
step = channel * width
# create QImage from image
qImg = QImage(image.data, width, height, step, QImage.Format_RGB888)
# show image in img_label
self.label_2.setPixmap(QPixmap.fromImage(qImg))
# start/stop timer
def controlTimer(self):
# if timer is stopped
if not self.timer.isActive():
# create video capture
self.cap = cv2.VideoCapture(0)
# start timer
self.timer.start(20)
# if timer is started
else:
# stop timer
self.timer.stop()
self.cap.release()
Ответы (2 шт):
Если вы редактируете через QtDesigner, то описал ниже, если программно, то VideoStream можно сразу добавить в Ui_Form.
Добавьте в self.page лейаут, например QVBoxLayout, он нужен чтобы растянуть его содержимое на весь родительский виджет:
lass Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
...
self.page = QtWidgets.QWidget()
layout = QVBoxLayout()
self.page.setLayout(layout)
...
Далее в main.py
from video import VideoStream
class MainClass(QtWidgets.QMainWindow, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
# Добавим VideoStream в лейаут на self.page
self.page.layout().addWidget(VideoStream())
Я отметит для вас места где внес изменения.
У меня все модули в одном каталоге. Когда проверите мой пример, разместите свои модули как вам будет угодно.
Чтобы разместить что-то в label_2, создайте layout наследованный от label_2 и размещайте туда что хотите.
main.py
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
#from simple.gui import Ui_Form
from gui import Ui_Form # +
from video import VideoStream # +++
class MainClass(QtWidgets.QMainWindow, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton_2.clicked.connect(lambda : self.stackedWidget.setCurrentIndex(1))
self.pushButton.clicked.connect(lambda : self.stackedWidget.setCurrentIndex(0))
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
layout = QtWidgets.QVBoxLayout(self.label_2)
self.videoStream = VideoStream(self)
layout.addWidget(self.videoStream)
self.pushButton_3.clicked.connect(self.videoStream.controlTimer)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
win = MainClass()
win.show()
sys.exit(app.exec_())
video.py
import cv2
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QImage
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget
#from simple.gui import Ui_Form
class VideoStream(QWidget): # - , Ui_Form):
def __init__(self, parent=None): # + parent
super().__init__(parent) # + parent
self.parent = parent # + parent
# --- self.setupUi(self) # ----
# create a timer
self.timer = QTimer()
# set timer timeout callback function
self.timer.timeout.connect(self.viewCam)
# set control_bt callback clicked function
# self.pushButton_3.clicked.connect(self.controlTimer) # ----
# view camera
def viewCam(self):
# read image in BGR format
ret, image = self.cap.read()
# convert image to RGB format
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# get image infos
height, width, channel = image.shape
step = channel * width
# create QImage from image
qImg = QImage(image.data, width, height, step, QImage.Format_RGB888)
# show image in img_label
self.parent.label_2.setPixmap(QPixmap.fromImage(qImg)) # self.parent.label_2
# start/stop timer
def controlTimer(self):
# if timer is stopped
if not self.timer.isActive():
# create video capture
self.cap = cv2.VideoCapture(0)
# start timer
self.timer.start(20)
# if timer is started
else:
# stop timer
self.timer.stop()
self.cap.release()
gui.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(534, 325)
Form.setStyleSheet("background-color: rgb(1, 203, 170);")
self.stackedWidget = QtWidgets.QStackedWidget(Form)
self.stackedWidget.setGeometry(QtCore.QRect(20, 70, 491, 241))
self.stackedWidget.setObjectName("stackedWidget")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.label = QtWidgets.QLabel(self.page)
self.label.setGeometry(QtCore.QRect(80, 70, 311, 101))
font = QtGui.QFont()
font.setPointSize(25)
self.label.setFont(font)
self.label.setObjectName("label")
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.label_2 = QtWidgets.QLabel(self.page_2)
self.label_2.setGeometry(QtCore.QRect(30, 30, 331, 191))
font = QtGui.QFont()
font.setPointSize(30)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.pushButton_3 = QtWidgets.QPushButton(self.page_2)
self.pushButton_3.setGeometry(QtCore.QRect(380, 110, 75, 23))
self.pushButton_3.setStyleSheet("background-color: rgb(255, 85, 255);")
self.pushButton_3.setObjectName("pushButton_3")
self.stackedWidget.addWidget(self.page_2)
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(70, 20, 75, 23))
self.pushButton.setStyleSheet("background-color: rgb(0, 85, 255);")
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(Form)
self.pushButton_2.setGeometry(QtCore.QRect(400, 20, 75, 23))
self.pushButton_2.setStyleSheet("background-color: rgb(255, 85, 0);")
self.pushButton_2.setObjectName("pushButton_2")
self.retranslateUi(Form)
self.stackedWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "Simple first page"))
self.label_2.setText(_translate("Form", "Video on opencv"))
self.pushButton_3.setText(_translate("Form", "start"))
self.pushButton.setText(_translate("Form", "Main"))
self.pushButton_2.setText(_translate("Form", "Video"))
