PYQt5编写界面遇到问题以及分析以及解决办法
科技制作比赛研究了一下界面制作问题,最终效果如下,在此进行记录
目录
1.美观问题
2.如何加透明框
3.图片素材添加办法
4.如何播放视频(有参考)
5.编译后的代码如何调用,主函数与启动加载时图片标志
6.主窗口操作与如何加弹窗(如操作错误警报)
7.如何绘制实时变化的波动曲线(有参考)
8.按钮外接自定义函数
9.时间与线程
10.硬件互联
QPushButton{
border:1px solid #F3F3F5;
border-radius:10px;
border-color:rgba(0, 160, 240,155);
color:rgba(220, 220, 220,155);
font-size:12px;
height:20px;
padding-left:10px;
padding-right:10px;
text-align:left;
}
QPushButton:hover{
color:black;
border:1px solid #F3F3F5;
border-radius:10px;
background-color:rgba(255,255,255,180);
}
MainWindow.setWindowOpacity(0.9)
MainWindow.setWindowFlag(QtCore.Qt.FramelessWindowHint)
border-image: url(:/liubian/pic/装饰01.png);
background-color: rgba(0, 0, 0, 0);
其编译后代码效果如下:self.graphicsView_6 = QtWidgets.QGraphicsView(self.centralwidget)
self.graphicsView_6.setGeometry(QtCore.QRect(790, 520, 181, 161))
self.graphicsView_6.setStyleSheet("border-image: url(:/qiu/pic/装饰球.png);\n"
"background-color: rgba(0, 0, 0,0);")
self.graphicsView_6.setObjectName("graphicsView_6")
注意本方法需要通过安装的第三个工具将图片格式也转换一下,并在代码结尾注意是否能够成功的import此图片
另,label的写法完全不同,其代码见视频播放
def Display(self):
while self.videoflag==1:
if self.cap.isOpened():
print(10)
success, frame = self.cap.read()
self.main_ui.picture=frame
# RGB转BGR
print(11)
if success:
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
self.main_ui.label_15.setPixmap(QPixmap.fromImage(img))
self.main_ui.label_15.setScaledContents(True)
#time.sleep(0.1)
cv2.waitKey(10)
else:
print("read failed, no frame data")
success, frame = self.playCapture.read()
#if not success and self.video_type is parentWindow.VIDEO_TYPE_OFFLINE:
# print("play finished") # 判断本地文件播放完毕
# self.reset()
#self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
# return
else:
print("open file or capturing device error, init again")
self.reset()
print(16)
如果需要对实时视频流进行测试,本地直接调用电脑摄像机,网络流可以连凤凰卫视等直播,地址为"rtmp://live.hkstv.hk.lxdns.com/live/hks1";"rtmp://58.200.131.2:1935/livetv/hunantv"等,都不行就查一下哇
class parentWindow(QMainWindow,QWidget):
video_url = ""
def __init__(self,video_url="", video_type=VIDEO_TYPE_OFFLINE, auto_play=False):
QMainWindow.__init__(self)
self.main_ui = Ui_MainWindow()
self.main_ui.setupUi(self)
那个Ui_MainWindow就是编译生成的那个类,另写主函数如下:
if __name__=='__main__':
app=QApplication(sys.argv)
#启动界面
splash=QSplashScreen(QPixmap("pic/bk01.jpg"))
splash.showMessage("加载... 0%", Qt.AlignHCenter | Qt.AlignBottom, Qt.black)
splash.show()
qApp.processEvents()
window = parentWindow("http://一个网址")
child=childWindow()
video=videoWindow()
#window.main_ui.pushButton_11.clicked.connect(video.show())
# 显示
window.show()
splash.finish(window)
sys.exit(app.exec_())
其中splash是启动界面,在界面加载难产的时候让他不那么尴尬,效果如下:
6. 上面的主函数中能看到初始化中存在一个孩子类,其为警告弹窗,面向在界面中操作不当时出现,需要先在designer中另绘制一个窗口,效果与编译后代码如下
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(408, 336)
Dialog.setWindowOpacity(1.0)
Dialog.setStyleSheet("background-color:rgba(0,0,0,0)")
self.graphicsView = QtWidgets.QGraphicsView(Dialog)
self.graphicsView.setGeometry(QtCore.QRect(0, 20, 401, 331))
self.graphicsView.setStyleSheet("border-image: url(:/warn/pic/warn01.png);\n"
"background-color:rgba(0,0,0,0)")
self.graphicsView.setObjectName("graphicsView")
self.graphicsView_2 = QtWidgets.QGraphicsView(Dialog)
self.graphicsView_2.setGeometry(QtCore.QRect(330, 10, 51, 41))
self.graphicsView_2.setStyleSheet("border-image: url(:/warn/pic/close.png);\n"
"background-color:rgba(0,0,0,0)")
self.graphicsView_2.setObjectName("graphicsView_2")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(340, 20, 31, 21))
self.pushButton.setStyleSheet("background-color:rgba(0,0,0,0)")
self.pushButton.setText("")
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
self.pushButton.clicked.connect(Dialog.close)
QtCore.QMetaObject.connectSlotsByName(Dialog)
Dialog.setWindowOpacity(0.8)
Dialog.setWindowFlag(QtCore.Qt.FramelessWindowHint)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
import warn_rc
尤其注意,类似于主界面的代码,我们也需要另写一个类来将其调用,代码如下:
class childWindow(QDialog):
def __init__(self):
QDialog.__init__(self)
self.child=Ui_Dialog()
self.child.setupUi(self)
def plotData(self):
if self.dataflag==1:
self.tmp_x,self.tmp_y,self.tmp_z=self.cmdd
self.main_ui.lineEdit_3.setText(str(self.tmp_x))
self.main_ui.lineEdit_2.setText(str(self.tmp_y))
self.main_ui.lineEdit.setText(str(self.tmp_z))
if len(self.data_x)<self.N:
self.data_x.append(self.tmp_x)
else:
self.data_x[:-1]=self.data_x[1:]
self.data_x[-1]=self.tmp_x
self.curve_x.setData(self.data_x)
if len(self.data_y)<self.N:
self.data_y.append(self.tmp_y)
else:
self.data_y[:-1]=self.data_y[1:]
self.data_y[-1]=self.tmp_y
self.curve_y.setData(self.data_y)
if len(self.data_z)<self.N:
self.data_z.append(self.tmp_z)
else:
self.data_z[:-1]=self.data_z[1:]
self.data_z[-1]=self.tmp_z
self.curve_z.setData(self.data_z)
self.idx+=1
self.pushButton_9.clicked.connect(self.doit)
self.pushButton_4.clicked.connect(self.starguide_1)
之后同样在此类里定义函数
def doit(self): # OK
if self.flagbutton[1] == 1:
#child=childWindow()
#self.flagbutton=[0,1,0,0]
......
另一种是加在我们写出的大类parentwindow里,代码如下:
self.main_ui.pushButton_15.clicked.connect(self.dataconnect_2)
self.main_ui.pushButton_11.clicked.connect(self.bofang)
此时函数定义也要写在parentwindow里
self.thread=WorkThread()
self.xyztimer=QTimer()#计时器
self.xyztimer.start(5)
因为此计时器申请两个及以上时出现了未知错误,本任务中借用了另一篇博客中的视频播放中的计时器。
线程代码使用thread库,如下:
def bofang(self):
self.cap=cv2.VideoCapture(self.video_url)
self.videoflag=self.videoflag*(-1)
thu=threading.Thread(target=self.Display)
thu.start()
Display是我们要接出线程运行的函数
over.