PYQT5 webcam is not opening on the label - pyqt5

I am trying to set my webcam to a label and open it on pageload. However code does not throw any error also it does not getting bind to the label as well. Can anyone tell me how to fix this?
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'camera.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow,qApp
import sys
import cv2
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.gridLayoutWidget.setGeometry(QtCore.QRect(169, 59, 471, 251))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.label = QtWidgets.QLabel(self.gridLayoutWidget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.capture = cv2.cv2.VideoCapture(0)
timer = QtCore.QTimer()
timer.setInterval(int(1000/30))
timer.timeout.connect(self.get_frame)
timer.start()
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def get_frame(self):
frame = self.capture.read()
image = QtGui.QImage(frame, *frame.shape[1::-1], QtGui.QImage.Format_RGB888).rgbSwapped()
pixmap = QtGui.QPixmap.fromImage(image)
self.label.setPixmap(pixmap)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

The problem is that timer is a local variable that will be destroyed so the get_frame method will not be invoked, the solution is to make it a member of the class so you must change timer to self.timer. Also the read() method returns a tuple, no the frame so you should change it to:
def get_frame(self):
ret, frame = self.capture.read()
if ret:
image = QtGui.QImage(
frame, *frame.shape[1::-1], QtGui.QImage.Format_RGB888
).rgbSwapped()
pixmap = QtGui.QPixmap.fromImage(image)
self.label.setPixmap(pixmap)

Related

Pyqt5 qthread signal and pyqtslot

How to send data to thread is running by pyqt as the code below?
I think it would be using pyqtslot, but I don't know how to use.
I'm trying to use the pyqt qthread for multithreading program.
In the code, there are two different workers instance. I try to use signal and slot for data share. but it seemed that the signal is blocked until one of the qthread is finished.
this is the code.
gui.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(641, 204)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.Button_start_1 = QtWidgets.QPushButton(self.centralwidget)
self.Button_start_1.setGeometry(QtCore.QRect(30, 20, 81, 41))
self.Button_start_1.setObjectName("Button_start_1")
self.Button_start_2 = QtWidgets.QPushButton(self.centralwidget)
self.Button_start_2.setGeometry(QtCore.QRect(30, 70, 81, 41))
self.Button_start_2.setObjectName("Button_start_2")
self.Button_stop_1 = QtWidgets.QPushButton(self.centralwidget)
self.Button_stop_1.setGeometry(QtCore.QRect(150, 20, 75, 41))
self.Button_stop_1.setObjectName("Button_stop_1")
self.Button_stop_2 = QtWidgets.QPushButton(self.centralwidget)
self.Button_stop_2.setGeometry(QtCore.QRect(150, 70, 75, 41))
self.Button_stop_2.setObjectName("Button_stop_2")
self.lcdNumber_1 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_1.setGeometry(QtCore.QRect(250, 20, 151, 41))
self.lcdNumber_1.setObjectName("lcdNumber_1")
self.lcdNumber_2 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_2.setGeometry(QtCore.QRect(250, 70, 151, 41))
self.lcdNumber_2.setObjectName("lcdNumber_2")
self.Button_pause_thread_1 = QtWidgets.QPushButton(self.centralwidget)
self.Button_pause_thread_1.setGeometry(QtCore.QRect(420, 20, 121, 41))
self.Button_pause_thread_1.setObjectName("Button_pause_thread_1")
self.Button_pause_thread_2 = QtWidgets.QPushButton(self.centralwidget)
self.Button_pause_thread_2.setGeometry(QtCore.QRect(420, 70, 121, 41))
self.Button_pause_thread_2.setObjectName("Button_pause_thread_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 641, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.Button_start_1.setText(_translate("MainWindow", "Start thread1"))
self.Button_start_2.setText(_translate("MainWindow", "Start thread2"))
self.Button_stop_1.setText(_translate("MainWindow", "Stop thread 1"))
self.Button_stop_2.setText(_translate("MainWindow", "Stop thread 1"))
self.Button_pause_thread_1.setText(_translate("MainWindow", "Pause thread 1"))
self.Button_pause_thread_2.setText(_translate("MainWindow", "Pause thread 2"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Main.py
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import pyqtSignal
from PyQt5 import QtCore
import time
from gui import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.uic = Ui_MainWindow()
self.uic.setupUi(self)
self.thread = {}
self.uic.Button_start_1.clicked.connect(self.start_worker_1)
self.uic.Button_start_2.clicked.connect(self.start_worker_2)
self.uic.Button_stop_1.clicked.connect(self.stop_worker_1)
self.uic.Button_stop_2.clicked.connect(self.stop_worker_2)
def start_worker_1(self):
self.thread[1] = ThreadClass(index=1)
self.thread[1].start()
self.thread[1].signal.connect(self.my_function)
self.uic.Button_start_1.setEnabled(False)
self.uic.Button_stop_1.setEnabled(True)
def start_worker_2(self):
self.thread[2] = ThreadClass(index=2)
self.thread[2].start()
self.thread[2].signal.connect(self.my_function)
self.uic.Button_start_2.setEnabled(False)
self.uic.Button_stop_2.setEnabled(True)
def stop_worker_1(self):
self.thread[1].stop()
self.uic.Button_stop_1.setEnabled(False)
self.uic.Button_start_1.setEnabled(True)
def stop_worker_2(self):
self.thread[2].stop()
self.uic.Button_stop_2.setEnabled(False)
self.uic.Button_start_2.setEnabled(True)
def my_function(self, counter):
m = counter
i = self.sender().index
if i == 1:
self.uic.lcdNumber_1.display(m)
if i == 2:
self.uic.lcdNumber_2.display(m)
class ThreadClass(QtCore.QThread):
signal = pyqtSignal(int)
def __init__(self, index=0):
super().__init__()
self.index = index
def run(self):
print('Starting thread...', self.index)
counter = 0
while True:
counter += 1
print(counter)
time.sleep(1)
self.signal.emit(counter)
def stop(self):
print('Stopping thread...', self.index)
self.terminate()
def get_value_from_button(self):
print("value of thread ")
if __name__ == "__main__":
app = QApplication(sys.argv)
main_win = MainWindow()
main_win.show()
sys.exit(app.exec())
I need to get data at get_value_from_button(self) function, when I press the button.

The QTableWidget always scrolls to setColumn/RowCount automatically

I am currently trying to add a file (that changes periodically) to a QTable widget. However, the row and column also changes permanently.
To delete old information:
self.tableWidget.setRowCount(0)
self.tableWidget.setColumnCount(0)
Change to new list length:
self.tableWidget.setRowCount(len(someList))
self.tableWidget.setColumnCount(4)
After that the scroll position is at the top. Although I also did the following:
self.tableWidget.setAutoScroll(False)
pos = self.tableWidget.verticalScrollBar().value()
#Change the column row size
#check max>=pos
self.tableWidget.verticalScrollBar().setValue(pos)
Everything is ignored and it scrolls up anyway.
My code example:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTimer
import sys
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(618, 510)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents_2 = QtWidgets.QWidget()
self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 594, 440))
self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_2)
self.gridLayout_2.setObjectName("gridLayout_2")
self.tableWidget = QtWidgets.QTableWidget(self.scrollAreaWidgetContents_2)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(20)
self.gridLayout_2.addWidget(self.tableWidget, 0, 0, 1, 1)
self.scrollArea.setWidget(self.scrollAreaWidgetContents_2)
self.gridLayout.addWidget(self.scrollArea, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 618, 25))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.qTimer = QTimer()
self.qTimer.setInterval(1000)
self.qTimer.timeout.connect(self.getData)
self.qTimer.start()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
def getData(self):
self.tableWidget.setRowCount(0)
self.tableWidget.setColumnCount(0)
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(20)
#Problem: Scrolls to top
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Changing the layout of an item model requires a certain amount of time to the view that is showing it.
In order to ensure that the scroll bar is updated, you can ask Qt to "process" its current event queue:
def getData(self):
pos = self.tableWidget.verticalScrollBar().value()
self.tableWidget.setRowCount(0)
self.tableWidget.setColumnCount(0)
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(20)
QtWidgets.QApplication.processEvents()
self.tableWidget.verticalScrollBar().setValue(pos)
On the other hand, to minimize unnecessary requests on the table and avoid flickering, you should set the row count to the new amount instead of resetting it everytime. In this way you don't need to move the scroll bar everytime, as it will always try to keep its previous position, even if the new row count is less than before.
Note: you should not modify (nor try to mimic) the files generated by pyuic, as those files have to be imported in your main script(s) instead. Read more about using Designer.

window doesnt appear correctly qtpython

I am trying to lunch a simple window when click on a button. this simple window that I had copied come from: MultipleplotAxis.py
My code is:
from PyQt5 import QtCore, QtGui, QtWidgets
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(264, 248)
MainWindow.setMinimumSize(QtCore.QSize(264, 248))
MainWindow.setMaximumSize(QtCore.QSize(264, 248))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 264, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.pushButton.clicked['bool'].connect(self.lanzar_grafica_3_ejes)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
def lanzar_grafica_3_ejes(self):
self.lanzar_a_canasta = lanzar()
self.lanzar_a_canasta.setupUi(self)
class lanzar(object):
###########
# COPY FROM PYQTGRAPH.ORG
###########
def __init__(self):
print('__init__ lanzar class')
def setupUi(self, MainWindow):
import time
pg.mkQApp()
pw = pg.PlotWidget()
pw.show()
time.sleep(5)
pw.setWindowTitle('pyqtgraph example: MultiplePlotAxes')
p1 = pw.plotItem
p1.setLabels(left='axis 1')
## create a new ViewBox, link the right axis to its coordinate system
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)
p1.getAxis('right').setLabel('axis2', color='#0000ff')
## create third ViewBox.
## this time we need to create a new axis as well.
p3 = pg.ViewBox()
ax3 = pg.AxisItem('right')
p1.layout.addItem(ax3, 2, 3)
p1.scene().addItem(p3)
ax3.linkToView(p3)
p3.setXLink(p1)
ax3.setZValue(-10000)
ax3.setLabel('axis 3', color='#ff0000')
## Handle view resizing
def updateViews():
## view has resized; update auxiliary views to match
global p1, p2, p3
p2.setGeometry(p1.vb.sceneBoundingRect())
p3.setGeometry(p1.vb.sceneBoundingRect())
## need to re-update linked axes since this was called
## incorrectly while views had different shapes.
## (probably this should be handled in ViewBox.resizeEvent)
p2.linkedViewChanged(p1.vb, p2.XAxis)
p3.linkedViewChanged(p1.vb, p3.XAxis)
updateViews()
p1.vb.sigResized.connect(updateViews)
p1.plot([10,20,40,80,40,20],[1,2,4,8,16,32])
p2.addItem(pg.PlotCurveItem([10,20,40,80,40,20],[12,13,14,15,16,17], pen='b'))
p3.addItem(pg.PlotCurveItem([10,20,40,80,40,20],[32,16,8,4,2,1], pen='r'))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
When I push the button, the window that I want to appear, it doesnt appears completely, I mean:
This is the window that I want to appear:
, but when I click on the button, only appears the frame with nothing inside. Also I had code a timer because if not, the window disappear immediatetly.
I suppose that I am calling the class in a wrong way.
any help?
Try it:
from PyQt5 import QtCore, QtGui, QtWidgets
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
#import time
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(264, 248)
MainWindow.setMinimumSize(QtCore.QSize(264, 248))
# MainWindow.setMaximumSize(QtCore.QSize(264, 248))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 264, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
# self.pushButton.clicked['bool'].connect(self.lanzar_grafica_3_ejes)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
# def lanzar_grafica_3_ejes(self): ##(MainWindow): #
# self.lanzar_a_canasta = Lanzar()
# self.lanzar_a_canasta.setupUi() #(self)
class Lanzar(QtWidgets.QWidget): #(object):
###########
# COPY FROM PYQTGRAPH.ORG
###########
def __init__(self):
super().__init__()
print('__init__ Lanzar class')
def setupUi(self, MainWindow):
pg.mkQApp()
self.pw = pg.PlotWidget()
# self.pw.show()
# time.sleep(5)
self.pw.setWindowTitle('pyqtgraph example: MultiplePlotAxes')
self.p1 = self.pw.plotItem
self.p1.setLabels(left='axis 1')
## create a new ViewBox, link the right axis to its coordinate system
self.p2 = pg.ViewBox()
self.p1.showAxis('right')
self.p1.scene().addItem(self.p2)
self.p1.getAxis('right').linkToView(self.p2)
self.p2.setXLink(self.p1)
self.p1.getAxis('right').setLabel('axis2', color='#0000ff')
## create third ViewBox.
## this time we need to create a new axis as well.
self.p3 = pg.ViewBox()
ax3 = pg.AxisItem('right')
self.p1.layout.addItem(ax3, 2, 3)
self.p1.scene().addItem(self.p3)
ax3.linkToView(self.p3)
self.p3.setXLink(self.p1)
ax3.setZValue(-10000)
ax3.setLabel('axis 3', color='#ff0000')
## Handle view resizing
def updateViews():
## view has resized; update auxiliary views to match
# global p1, p2, p3
self.p2.setGeometry(self.p1.vb.sceneBoundingRect())
self.p3.setGeometry(self.p1.vb.sceneBoundingRect())
## need to re-update linked axes since this was called
## incorrectly while views had different shapes.
## (probably this should be handled in ViewBox.resizeEvent)
self.p2.linkedViewChanged(self.p1.vb, self.p2.XAxis)
self.p3.linkedViewChanged(self.p1.vb, self.p3.XAxis)
updateViews()
self.p1.vb.sigResized.connect(updateViews)
self.p1.plot([10,20,40,80,40,20],[1,2,4,8,16,32])
self.p2.addItem(pg.PlotCurveItem([10,20,40,80,40,20],[12,13,14,15,16,17], pen='b'))
self.p3.addItem(pg.PlotCurveItem([10,20,40,80,40,20],[32,16,8,4,2,1], pen='r'))
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.lanzar_grafica_3_ejes)
def lanzar_grafica_3_ejes(self):
self.lanzar_a_canasta = Lanzar()
self.lanzar_a_canasta.setupUi(self.lanzar_a_canasta)
self.gridLayout.addWidget(self.lanzar_a_canasta.pw, 1, 0, 1, 5)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Window()
w.show()
w.resize(630, 550)
sys.exit(app.exec_())

How can I open and close a new window from main window in PyQt?

I searched in Google usually many posts are talking about how to open a new window and not indicating how to close the window. I found several posts in this website but most of them are using dialog window which is not considered in my software.
I make a UI, which contains a spin box and a button, to demonstrate my problem. I can type in a number equal or less than 5 in spin box. When I click the button, a number of new windows will show up and how many windows will show up is depending on the number in the spin box. If I change to the number in spin box then click the button, the original windows will be closed and new windows will be shown.
Fox example, first I type in "2" in spin box then click the button. Then 2 new windows will show up. If I change the number in spin box to 3 then click the button, the original 2 windows will be closed and 3 new windows will show up.
Here is my main program code:
from PyQt5.QtWidgets import QApplication, QMainWindow
from uitest_review import Ui_MainWindow # import the UI module
# set up a class for main window
class window(QMainWindow):
def __init__(self, parent=None):
super(window, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Open.clicked.connect(self.openwindow)
def openwindow(self):
windownum = self.ui.windownum.value()
print("open window num:", windownum)
opennewwindow = newwindow(self)
opennewwindow.show()
class newwindow(QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
if __name__ == "__main__":
app = QApplication([])
gui = window()
gui.show()
app.exec_()
Here is my UI code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(816, 577)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 796, 537))
self.scrollAreaWidgetContents.setObjectName(\
"scrollAreaWidgetContents")
self.verticalLayout = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
spacerItem = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
self.verticalLayout.addItem(spacerItem)
self.windownum = QtWidgets.QSpinBox(self.scrollAreaWidgetContents)
self.windownum.setMaximum(5)
self.windownum.setObjectName("windownum")
self.verticalLayout.addWidget(self.windownum)
self.groupBox = QtWidgets.QGroupBox(self.scrollAreaWidgetContents)
self.groupBox.setTitle("")
self.groupBox.setObjectName("groupBox")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
self.horizontalLayout.setObjectName("horizontalLayout")
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem1)
self.Open = QtWidgets.QPushButton(self.groupBox)
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.Open.setFont(font)
self.Open.setObjectName("Open")
self.horizontalLayout.addWidget(self.Open)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem2)
self.verticalLayout.addWidget(self.groupBox)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.gridLayout.addWidget(self.scrollArea, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.Open.setText(_translate("MainWindow", "Open"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I create a new class (newwindow) in my main program and I can call this class to show a new window. But I cannot figure out how to detect how many windows is opened and how to close them. Does anyone can help me? Thank you so much.
I figured out by myself.
class window(QMainWindow):
def __init__(self, parent=None):
super(window, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.Open.clicked.connect(self.openwindow)
self.openedwin = []
def openwindow(self):
windownum = self.ui.windownum.value()
if windownum != 0:
if self.openedwin != []:
for window in self.openedwin:
window.close()
for repeat in range(windownum):
opennewwindow = newwindow(self)
# print("opennewwindow:", opennewwindow)
self.openedwin.append(opennewwindow)
opennewwindow.show()
# print("self.openedwin:", self.openedwin)
class newwindow(QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
if __name__ == "__main__":
app = QApplication([])
gui = window()
gui.show()
app.exec_()
I add a list self.openedwin = [] to save all window objects. I can use "window object".close() command to close the window before opening new one.

How to scale background image to cover MainWindow in PyQt5

I trying to learn PyQt5 so it might a noobie question, but I search a lot and I couldn't find a solution.
I wrinting a sample code showing a countdow to a defined datetime and now it looks like in the image below:
I need to resize the image to cover the app, atm I have a window 300x200 and background image 2400x1800.
I also need the background to resize on MainWindow resize. At first glance css property background-size is not supported, border-image would strech the image.
OS: Windows 7-10 (not a choise)
Python: 3.4.3
PyQt: 5.5
Current code (not working)
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtCore import QObject, pyqtSignal, QTimer
import design
import sys
from datetime import datetime, timedelta
# UI base class is inherited from design.Ui_MainWindow
class Counter(QtWidgets.QMainWindow, design.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
# applying background image
self.background = QtGui.QPixmap("./assets/img/trecime.jpg")
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Background,QtGui.QBrush(self.background).scale(self.size()))
self.MainWindow.setPalette(palette)
# custom colors for QLCDWidgets
lcdPalette = self.dayCount.palette()
lcdPalette.setColor(lcdPalette.WindowText, QtGui.QColor(255,0,0, 200))
lcdPalette.setColor(lcdPalette.Background, QtGui.QColor(0, 0, 0, 0))
lcdPalette.setColor(lcdPalette.Light, QtGui.QColor(200, 0, 0, 120))
lcdPalette.setColor(lcdPalette.Dark, QtGui.QColor(100, 0, 0, 150))
self.dayCount.setPalette(lcdPalette)
lcdPalette.setColor(lcdPalette.WindowText, QtGui.QColor(255,255,255, 200))
lcdPalette.setColor(lcdPalette.Light, QtGui.QColor(200, 0, 0, 0))
lcdPalette.setColor(lcdPalette.Dark, QtGui.QColor(200, 0, 0, 0))
self.timeCount.setPalette(lcdPalette)
# init Qtimer
self.timer = QTimer()
self.timer.timeout.connect(self.update_timer)
self.timer.start(200)
# config final date
self.finalDatetime = datetime(2016, 11, 30, 14, 00)
def resizeEvent(self, resizeEvent):
print('resized')
def update_timer(self):
currentDatetime = datetime.today()
delta = self.finalDatetime - currentDatetime
(days, hours, minutes) = days_hours_minutes(delta)
self.dayCount.display(days)
# blinking colon
separator = ":" if delta.microseconds < 799999 else ' '
self.timeCount.display('%02d%s%02d' % (hours, separator, minutes))
def days_hours_minutes(td):
return td.days, td.seconds//3600, (td.seconds//60)%60
def main():
app = QtWidgets.QApplication(sys.argv)
counter = Counter()
counter.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
pyqt style sheet can be used for this resizing
try
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self,MainWindow):
super().__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
MainWindow.setObjectName("MainWindow")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralWidget)
self.horizontalLayout_2.setContentsMargins(11, 11, 11, 11)
self.horizontalLayout_2.setSpacing(6)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSpacing(6)
self.horizontalLayout.setObjectName("horizontalLayout")
self.start_button = QtWidgets.QPushButton(self.centralWidget)
self.start_button.setObjectName("start_button")
self.horizontalLayout.addWidget(self.start_button)
self.stop_button = QtWidgets.QPushButton(self.centralWidget)
self.stop_button.setObjectName("stop_button")
self.horizontalLayout.addWidget(self.stop_button)
self.horizontalLayout_2.addLayout(self.horizontalLayout)
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
self.menuBar.setObjectName("menuBar")
MainWindow.setMenuBar(self.menuBar)
self.mainToolBar = QtWidgets.QToolBar(MainWindow)
self.mainToolBar.setObjectName("mainToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.start_button.setText(_translate("MainWindow", "Start"))
self.stop_button.setText(_translate("MainWindow", "Stop"))
stylesheet = """
MainWindow {
border-image: url("The_Project_logo.png");
background-repeat: no-repeat;
background-position: center;
}
"""
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
app.setStyleSheet(stylesheet) # <---
window = MainWindow()
window.resize(640, 640)
window.show()
sys.exit(app.exec_())