I am having a problem with resizing the frame based on the clicking of a single button. I have a blank window with a single push button called pushButton in my ui file. I would like that whenever this button is pressed, the dimensions of the MainWindow are changed, however the resizing only happens one time. The original dimensions are 640 by 480.
What I am doing incorrectly in the run_resize function? Thanks!
The code is as follows.
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.uic import loadUiType
qtCreatorFile = 'my_gui.ui'
Ui_MainWindow, QtBaseClass = loadUiType(qtCreatorFile)
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.setFixedSize(self.size())
self.frame = QFrame()
self.pushButton.clicked.connect(self.run_resize)
def run_resize(self):
if self.frame.height() == 480:
self.setMinimumSize(640, 150)
self.resize(640, 150)
else:
self.setMinimumSize(640, 480)
self.resize(640, 480)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = main_window()
w.show()
sys.exit(app.exec_())
You have to check the condition on the QMainWindow, here is a working example :
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.uic import loadUiType
qtCreatorFile = 'my_gui.ui'
Ui_MainWindow, QtBaseClass = loadUiType(qtCreatorFile)
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.setFixedSize(self.size())
self.pushButton.clicked.connect(self.run_resize)
def run_resize(self):
if self.height() == 480:
self.setMinimumSize(640, 150)
self.resize(640, 150)
else:
self.setMinimumSize(640, 480)
self.resize(640, 480)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Related
I'm trying to get a background image to my mainwindow but i can't get it to work properly.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QLabel
from PyQt5.QtGui import QIcon
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSvg import *
from PyQt5.QtWidgets import *
from abc import abstractmethod
class App(QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.title = 'Title'
self.left = 500
self.top = 500
self.width = 440
self.height = 280
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# ...
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
#view = TableScene(ex)
ex.show()
sys.exit(app.exec_())
I've tried different kinds of methods but none of them works as it should.
I found the following code as a solution from another topic but it just gives me a black background and the rest of the widgets get laggy.
oImage = QImage("table.png")
sImage = oImage.scaled(QSize(440, 280))
palette = QPalette()
palette.setBrush(QPalette.Window, QBrush(sImage))
self.setPalette(palette)
I don't know if the whole window gets laggy or what really happens but the picture below is a screenshot of a part of the window using the code above, and as you can see it gets all black and the slider shows all the previous position it has been on, sort of laggy anyways.
I've also tried the setStyleSheet but I don't know if it's my syntax that's wrong or if it's a faulty way of doing it. Does anyone know a way of doing it correctly?
EDIT
This is my current window:
This is the picture I'm trying to implement as a background to my current window, the picture called "table.png" :
This is a visualization of what I'm trying to do, and this is made in paint since I don't know how to do it correctly:
And this is what I get if i use the code from the other topic:
One of the possible reasons why a black background appears is that QImage is null. And a QImage is null because the image is invalid or because the image path is incorrect. In this case I think it is the second case since the OP uses a relative path that is prone to errors. The solution is to build the absolute path using the script information such as its location:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class App(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.initUI()
def initUI(self):
self.setWindowTitle("Title")
self.setGeometry(500, 500, 440, 280)
oImage = QtGui.QImage(os.path.join(CURRENT_DIR, "table.png"))
sImage = oImage.scaled(QtCore.QSize(440, 280))
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush(sImage))
self.setPalette(palette)
pushbutton = QtWidgets.QPushButton("test", self)
pushbutton.move(100, 100)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
Note: The image provided by the OP has extension .jpg but the one indicated by code is .png, maybe "imgur" has changed the extension.
Note: If the window is resized manually, the following behavior will be observed:
So for this there are 2 possible solutions depending on the developer's criteria:
Set a fixed size: self.setFixedSize(440, 280)
Adapt the image to the size of the window:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class App(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.initUI()
def initUI(self):
self.setWindowTitle("Title")
self.setGeometry(500, 500, 440, 280)
pushbutton = QtWidgets.QPushButton("test", self)
pushbutton.move(100, 100)
self.oImage = QtGui.QImage(os.path.join(CURRENT_DIR, "table.png"))
# or QPixmap
# self.oPixmap = QtGui.QPixmap(os.path.join(CURRENT_DIR, "table.png"))
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.drawImage(self.rect(), self.oImage)
# or QPixmap
# painter.drawPixmap(self.rect(), self.oPixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
or
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class App(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent=parent)
self.initUI()
def initUI(self):
self.setWindowTitle("Title")
self.setGeometry(500, 500, 440, 280)
pushbutton = QtWidgets.QPushButton("test", self)
pushbutton.move(100, 100)
self.setStyleSheet(
"""
QMainWindow{
border-image: url(%s) 0 0 0 0 stretch stretch
}
"""
% os.path.join(CURRENT_DIR, "table.png")
)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
I would like to place a QPixmap on another QPixmap. Both have the same size, so I would just like to make an overlay. The overlay image has a transparent elipse in the middle. I figure they should be QPixmap format, however I dont know how to place them on top of each other and keep them in place when resizing the window. This is my code displaying how my background images are placed. I have attached a image explaining what i want.
import sys
from PyQt5 import QtGui ,QtWidgets, uic
from PyQt5.QtCore import Qt
class Ergolab(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(Ergolab, self).__init__(*args, **kwargs)
# Load the UI Page
self.ui = uic.loadUi("mainwindow.ui",self)
self.pixmap1 = QtGui.QPixmap('C:/Users/Frede/Desktop/img1.jpg')
self.shoflexLLabel.setPixmap(self.pixmap1.scaled(self.shoflexLLabel.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
self.shoflexLLabel.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.shoflexLLabel.setMinimumSize(150, 150)
self.shoflexLLabel.resize(800, 600)
self.pixmap2 = QtGui.QPixmap('C:/Users/Frede/Desktop/img2.jpg')
self.shoflexRLabel.setPixmap(self.pixmap2.scaled(self.shoflexRLabel.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
self.shoflexRLabel.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.shoflexRLabel.setMinimumSize(150, 150)
self.shoflexRLabel.resize(800, 600)
def resizeEvent(self, event):
scaledSize = self.shoflexLLabel.size()
if not self.shoflexLLabel.pixmap() or scaledSize != self.shoflexLLabel.pixmap().size():
self.updateLabel()
def updateLabel(self):
self.shoflexLLabel.setPixmap(self.pixmap1.scaled(
self.shoflexLLabel.size(), Qt.KeepAspectRatio,
Qt.SmoothTransformation))
self.shoflexRLabel.setPixmap(self.pixmap2.scaled(
self.shoflexRLabel.size(), Qt.KeepAspectRatio,
Qt.SmoothTransformation))
def main():
app = QtWidgets.QApplication(sys.argv)
main = Ergolab()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
This is the result I would like:
You must use QPainter by setting the circle as a clip path:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
label = QtWidgets.QLabel()
self.setCentralWidget(label)
base_pixmap = QtGui.QPixmap("background.png")
overlay_pixmap = QtGui.QPixmap("overlay.png")
radius = 300
r = QtCore.QRectF()
r.setSize(radius * QtCore.QSizeF(1, 1))
r.moveCenter(base_pixmap.rect().center())
path = QtGui.QPainterPath()
path.addEllipse(r)
painter = QtGui.QPainter(base_pixmap)
painter.setRenderHints(
QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform
)
painter.setClipPath(path, QtCore.Qt.IntersectClip)
painter.drawPixmap(QtCore.QPoint(), overlay_pixmap)
painter.end()
label.setPixmap(base_pixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
This question already has an answer here:
How to open a window with a click of a button from another window using PyQt?
(1 answer)
Closed 3 years ago.
I want to create a new window when a button is clicked. I will later have windows be created dynamically depending on inputted data. But I want to start simple first.
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget
class MyWindow(QtWidgets.QMainWindow, QPushButton):
def __init__(self):
super(MyWindow, self).__init__()
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.setWindowTitle("ASSET")
self.Button = QPushButton('Action',self)
self.Button.clicked.connect(self.Action)
self.layout = QGridLayout(centralWidget)
self.layout.addWidget(self.Button)
def Action(self):
pass
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
You can create another QMainWindow() and when the button is clicked, activate the show() method
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QLabel
class NewWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(NewWindow, self).__init__(parent)
self.label = QLabel('New Window!')
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.layout = QGridLayout(centralWidget)
self.layout.addWidget(self.label)
class MyWindow(QtWidgets.QMainWindow, QPushButton):
def __init__(self):
super(MyWindow, self).__init__()
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.setWindowTitle("ASSET")
self.Button = QPushButton('Action',self)
self.Button.clicked.connect(self.Action)
self.layout = QGridLayout(centralWidget)
self.layout.addWidget(self.Button)
self.new_window = NewWindow(self)
def Action(self):
self.new_window.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
I want to set the background for text, which means that I want to set the color of the rectangle contains the text. I have tested QPainter.setBackground, but it do not work. This is my code:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MyLabel(QLabel):
def __init__(self):
super(MyLabel, self).__init__()
self.setMinimumHeight(200)
self.setMinimumWidth(200)
def paintEvent(self, QPaintEvent):
super(MyLabel, self).paintEvent(QPaintEvent)
pos = QPoint(50, 50)
painter = QPainter(self)
brush = QBrush()
brush.setColor(QColor(255,0,0))
painter.setBackgroundMode(Qt.OpaqueMode)
painter.setBackground(brush)
painter.drawText(pos, 'hello,world')
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
layout = QHBoxLayout(self)
self.label = MyLabel()
layout.addWidget(self.label)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
What I want is:
Thanks for any help.
It is not necessary to implement a personalized QLabel, it is enough to set the background color through Qt Style Sheet, also do not use a layout if you want to establish a certain position
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.label = QtWidgets.QLabel("hello,world", self)
self.label.adjustSize()
self.label.setStyleSheet(
"background-color: {};".format(QtGui.QColor(255, 0, 0).name())
)
self.label.move(QtCore.QPoint(50, 50))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
Trying to animate a line growing from nothing to a (0,0) to (200, 200) line with PyQt5 and using QPropertyAnimation. I already read a lot of documentation about Qt and tried several samples, but I just cannot get this to work. This is the code I have now:
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtGui import QPainter, QPixmap, QPainterPath
from PyQt5.QtCore import QObject, QPointF, QPropertyAnimation, pyqtProperty
from PyQt5.QtCore import QLineF
import sys
class Sample(QWidget):
l1 = QLineF(QPointF(), QPointF())
def __init__(self):
super().__init__()
self.initView()
self.initAnimation()
def initView(self):
self.show()
def initAnimation(self):
self.anim = QPropertyAnimation(self.l1, b'geometry')
self.anim.setDuration(7000)
self.anim.setStartValue(QPointF(0, 0))
self.anim.setEndValue(QPointF(200, 200))
self.anim.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Sample()
sys.exit(app.exec_())
Not posting all previous attemps, each one fails with a different error. I got a fade out animation on a widget to work, and a picture following a path, but I can seem to make a simple line drawing work. I was hoping to achieve something like this:
Codepen example
Qt documentation is huge and it seems there are several ways to achieve this, painter and timer, animation, variant animation, but I am not very familiar with C++ and the translation to Python is not always easy. Also samples are not that easy to find.
Am I missing something obvious?
Thanks!
For the record, this is what I achieved so far but as soon as I un-comment the QPropertyAnimation creation, app does not launch. Anyway I was still far from the result in the accepted answer.
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class MyLine(QGraphicsLineItem, QObject):
def __init__(self):
super().__init__()
def _set_start(self, point):
self.setLine(point.x(), point.y(), self.line().p2().x(), self.line().p2().y())
def _set_end(self, point):
self.setLine(self.line().p1().x(), self.line().p1().y(), point.x(), point.y())
start = pyqtProperty(QPointF, fset=_set_start)
end = pyqtProperty(QPointF, fset=_set_end)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout(self)
self.button = QPushButton("Start", self)
self.button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
hbox.addWidget(self.button)
hbox.addSpacing(40)
self.line = MyLine()
self.line.setLine(0, 0, 10, 10)
scene = QGraphicsScene()
scene.addItem(self.line)
view = QGraphicsView(scene)
hbox.addWidget(view)
self.anim = QPropertyAnimation(self.line, b"end") # crash without error here
# self.anim.setDuration(2500)
# self.anim.setLoopCount(1)
# self.anim.setStartValue(QPointF(10, 10))
# self.anim.setEndValue(QPointF(200, 200))
# self.button.clicked.connect(self.anim.start)
self.setGeometry(300, 300, 380, 250)
self.setWindowTitle('Color anim')
self.show()
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
You have to use QGraphicsView, QGraphicsScene with QGraphicsLineItem as I show below:
from PyQt5 import QtCore, QtGui, QtWidgets
class LineAnimation(QtCore.QObject):
def __init__(self, parent=None):
super(LineAnimation, self).__init__(parent)
self.m_line = QtCore.QLineF()
self.m_item = QtWidgets.QGraphicsLineItem()
self.m_item.setLine(self.m_line)
self.m_item.setPen(
QtGui.QPen(
QtGui.QColor("salmon"),
10,
QtCore.Qt.SolidLine,
QtCore.Qt.SquareCap,
QtCore.Qt.RoundJoin,
)
)
self.m_animation = QtCore.QPropertyAnimation(
self,
b"p2",
parent=self,
startValue=QtCore.QPointF(0, 0),
endValue=QtCore.QPointF(200, 200),
duration=5 * 1000,
)
self.m_animation.start()
def p1(self):
return self.m_line.p1()
def setP1(self, p1):
self.m_line.setP1(p1)
self.m_item.setLine(self.m_line)
def p2(self):
return self.m_line.p2()
def setP2(self, p2):
self.m_line.setP2(p2)
self.m_item.setLine(self.m_line)
p1 = QtCore.pyqtProperty(QtCore.QPointF, fget=p1, fset=setP1)
p2 = QtCore.pyqtProperty(QtCore.QPointF, fget=p2, fset=setP2)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
view = QtWidgets.QGraphicsView(
scene, alignment=QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop
)
self.setCentralWidget(view)
line_animation = LineAnimation(self)
scene.addItem(line_animation.m_item)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())