How to scale background image to cover MainWindow in PyQt5 - qt5

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_())

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.

PYQT5 webcam is not opening on the label

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)

I can't get Qt.FramelessWindowHint to work [duplicate]

This question already has answers here:
QtDesigner changes will be lost after redesign User Interface
(2 answers)
Closed 2 years ago.
I have been trying to figure this out for the last two days. I want to make my window frameless, I saw in a couple of resources that I should be using Qt.FramelessWindowHint . However, it doesn't want to work and I can't figure out why.
Can someone please point out what's wrong with my code, as I am very new to PyQt5?
(I have commented out sections that are related to some other files)
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import QTimer, Qt
#from HomeWindow import Ui_Form
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
#def secondscreen(self):
#self.Form = QtWidgets.QWidget()
#self.ui = Ui_Form()
#self.ui.setupUi(self.Form)
#self.Form.showMaximized()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(560, 350)
MainWindow.setStyleSheet("background-color: rgb(255, 255, 255);")
flags = Qt.WindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setWindowFlags(flags)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
self.textBrowser.setGeometry(QtCore.QRect(80, 280, 470, 60))
self.textBrowser.setFrameShape(QtWidgets.QFrame.NoFrame)
self.textBrowser.setFrameShadow(QtWidgets.QFrame.Plain)
self.textBrowser.setObjectName("textBrowser")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(10, 270, 61, 71))
self.label.setText("")
self.label.setPixmap(QtGui.QPixmap("../Media/College Logo.png"))
self.label.setScaledContents(True)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(290, 60, 220, 80))
font = QtGui.QFont()
font.setPointSize(28)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(290, 140, 81, 16))
font = QtGui.QFont()
font.setPointSize(9)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(0, 20, 231, 211))
self.label_4.setText("")
self.label_4.setPixmap(QtGui.QPixmap("../Media/Smample Logo.png"))
self.label_4.setScaledContents(True)
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName("label_4")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(290, 190, 93, 28))
self.pushButton.setObjectName("pushButton")
#self.pushButton.clicked.connect(self.secondscreen)
#self.pushButton.clicked.connect(MainWindow.close)
#QTimer.singleShot (5000, self.secondscreen)
#QTimer.singleShot (5001, MainWindow.close)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.textBrowser.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:7.8pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\';\">(c) 2020 SQU, Inc. Protected by international patents. See Squ.om/patents. App name is a registered trademark of SQU, Inc. Other product or brand names may be trademarks or registred trademarks of their respective holder.</span></p></body></html>"))
self.label_2.setText(_translate("MainWindow", "Mechanica"))
self.label_3.setText(_translate("MainWindow", "Version 1.0"))
self.pushButton.setText(_translate("MainWindow", "Start"))
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_())
You shouldn't try to edit or mimic the behavior of files generated by pyuic, as doing it leads to confusion about the object structure, and that's exactly your case.
Your Ui_MainWindow already inherits from QMainWindow, there's no use to create an instance of QMainWindow. In fact, what you're seeing is that QMainWindow, while you're setting the flag on the Ui_MainWindow instance, which you're never actually showing.
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
# ...
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = Ui_MainWindow()
mainWindow.show()
sys.exit(app.exec_())

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_())

Home button in Matplotlib 2.1.0 navigation toolbar embeded in pyqt5 window, it no longer works correctly

I embedded a matplotlib in a window maked in qtdesigner, pyqt5. I have 3 files
The window:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MplMainWindow(object):
def setupUi(self, MplMainWindow):
MplMainWindow.setObjectName("MplMainWindow")
MplMainWindow.resize(628, 416)
self.centralwidget = QtWidgets.QWidget(MplMainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.mpl = MplWidgetTest(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.mpl.sizePolicy().hasHeightForWidth())
self.mpl.setSizePolicy(sizePolicy)
self.mpl.setObjectName("mpl")
self.gridLayout_2.addWidget(self.mpl, 0, 0, 1, 1)
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox.setMaximumSize(QtCore.QSize(95, 16777215))
self.groupBox.setObjectName("groupBox")
self.gridLayout = QtWidgets.QGridLayout(self.groupBox)
self.gridLayout.setObjectName("gridLayout")
self.buttonDrawDate = QtWidgets.QPushButton(self.groupBox)
self.buttonDrawDate.setMaximumSize(QtCore.QSize(75, 16777215))
self.buttonDrawDate.setObjectName("buttonDrawDate")
self.gridLayout.addWidget(self.buttonDrawDate, 0, 0, 1, 1)
self.buttonErase = QtWidgets.QPushButton(self.groupBox)
self.buttonErase.setMaximumSize(QtCore.QSize(75, 16777215))
self.buttonErase.setObjectName("buttonErase")
self.gridLayout.addWidget(self.buttonErase, 1, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem, 2, 0, 1, 1)
self.gridLayout_2.addWidget(self.groupBox, 0, 1, 1, 1)
MplMainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MplMainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 628, 21))
self.menubar.setObjectName("menubar")
MplMainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MplMainWindow)
self.statusbar.setObjectName("statusbar")
MplMainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MplMainWindow)
QtCore.QMetaObject.connectSlotsByName(MplMainWindow)
def retranslateUi(self, MplMainWindow):
_translate = QtCore.QCoreApplication.translate
MplMainWindow.setWindowTitle(_translate("MplMainWindow", "MainWindow"))
self.groupBox.setTitle(_translate("MplMainWindow", "GroupBox"))
self.buttonDrawDate.setText(_translate("MplMainWindow", "Draw"))
self.buttonErase.setText(_translate("MplMainWindow", "Erase"))
from mplwidgettest import MplWidgetTest
The Matplot widget class:
from PyQt5.QtWidgets import QSizePolicy, QWidget, QVBoxLayout
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT as NavigationToolbar)
class MplCanvas(FigureCanvas):
"""Class to represent the FigureCanvas widget"""
def __init__(self):
# setup Matplotlib Figure and Axis
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
# initialization of the canvas
FigureCanvas.__init__(self, self.fig)
# we define the widget as expandable
FigureCanvas.setSizePolicy(self,
QSizePolicy.Expanding,
QSizePolicy.Expanding)
# notify the system of updated policy
FigureCanvas.updateGeometry(self)
class MplWidgetTest(QWidget):
"""Widget defined in Qt Designer"""
def __init__(self, parent = None):
# initialization of Qt MainWindow widget
QWidget.__init__(self, parent)
# set the canvas to the Matplotlib widget
self.canvas = MplCanvas()
# create a NavigatioToolbar
self.ntb=NavigationToolbar(self.canvas,self)
# create a vertical box layout
self.vbl = QVBoxLayout()
# add mpl widget to vertical box
self.vbl.addWidget(self.canvas)
# add NavigationToolBar to vertical box
self.vbl.addWidget(self.ntb)
# set the layout to th vertical box
self.setLayout(self.vbl)
And the main file that call others:
import sys
from IHMDrawDates import Ui_MplMainWindow
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget
import numpy as np
import datetime
class DesignerMainWindow(QMainWindow, Ui_MplMainWindow):
def __init__(self, parent = None):
super(DesignerMainWindow, self).__init__(parent)
self.setupUi(self)
# connect the signals with the slots
self.buttonDrawDate.clicked.connect(self.drawDate)
self.buttonErase.clicked.connect(self.eraseDate)
def drawDate(self):
# base = datetime.datetime(2018, 1, 1)
# x = np.array([base + datetime.timedelta(hours=i) for i in range(24)])
# y = np.random.rand(len(x))
x = np.arange(0,100,0.1)
y = np.sin(x)
self.mpl.canvas.ax.plot(x,y)
self.mpl.canvas.ax.relim()
self.mpl.canvas.ax.autoscale(True)
self.mpl.canvas.draw()
def eraseDate(self):
self.mpl.canvas.ax.clear()
self.mpl.canvas.draw()
if __name__ == '__main__':
app=0
app = QApplication(sys.argv)
dmw = DesignerMainWindow()
# show it
dmw.show()
sys.exit(app.exec_())
After update to matplotlib 2.1.0, the home button does not work correctly. It always return to the inicial clean axes. Example:
1.-Before click in drawing button:
2.-Click in draw button:
3.-Click in zoom:
4.-Click in home:
before the update, pressing the button HOME it returned to the image number 2, now with matplotlib 2.1.0 it returned to image 4. Any idea.
When I add:
def drawDate(self):
x = np.arange(0,100,0.1)
y = np.sin(x)
self.mpl.canvas.ax.plot(x,y)
self.mpl.canvas.ax.relim()
self.mpl.canvas.ax.autoscale(True)
self.mpl.ntb.update()
self.mpl.canvas.draw()
def eraseDate(self):
self.mpl.canvas.ax.clear()
self.mpl.ntb.update()
self.mpl.canvas.draw()
Then occurs:
I guess the answer to this question is given in this post, just for Tkinter, instead of PyQt:
NagivationToolbar fails when updating in Tkinter canvas
The home button restores the initial state of the plot, which is usually the desired functionality of a home button.
Here you apparently want it to restore the state of the plot, after the button has clicked. This would be done by calling the toolbar's update() method.
In this case you'd add
self.mpl.ntb.update()
inside the drawDate method.
The method could then look like
def drawDate(self):
x = np.arange(0,100,0.1)
y = np.sin(x)
self.mpl.canvas.ax.plot(x,y)
self.mpl.canvas.ax.relim()
self.mpl.canvas.ax.autoscale(True)
self.mpl.ntb.update() # <-- add this
#self.mpl.ntb.push_current() # and possibly this(?)
self.mpl.canvas.draw()
def eraseDate(self):
self.mpl.canvas.ax.clear()
self.mpl.ntb.update() # <-- add this
#self.mpl.ntb.push_current() # and possibly this(?)
self.mpl.canvas.draw()