Emit signal from QAction passing custom widget value - python

I have created a simple menu using a custom widget. How can i make the menu QAction emit the color value of the swatch clicked? Each color swatch contains a property called 'color'. If the user clicks 'Reset' i would like the value emitted to be 'None'
I tried to overload the triggered signal to pass the color of the swatch clicked but it didn't work either.
import sys
from PySide import QtGui, QtCore
class QColorSwatch(QtGui.QPushButton):
colorClicked = QtCore.Signal(object)
colorChanged = QtCore.Signal(object)
def __init__(self, *args, **kwargs):
super(QColorSwatch, self).__init__(*args, **kwargs)
self.setFixedWidth(18)
self.setFixedHeight(18)
self.setAutoFillBackground(True)
self._color = None
self.color = QtGui.QColor(0,0,0)
self.pressed.connect(self.color_clicked)
#property
def color(self):
return self._color
#color.setter
def color(self, value):
self._color = value
self.setIconSize(self.size())
pixmap = QtGui.QPixmap(self.size())
pixmap.fill(QtCore.Qt.black)
painter = QtGui.QPainter(pixmap)
painter.setBrush(QtGui.QColor(self.color))
painter.setPen(QtGui.QPen(QtCore.Qt.white, 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
painter.drawRect(1,1,self.size().width()-3,self.size().height()-3)
painter.end()
self.setIcon(pixmap)
self.colorChanged.emit(value)
def color_clicked(self):
self.colorClicked.emit(self.color)
class ColorFilters(QtGui.QWidget):
def __init__(self, action):
super(ColorFilters,self).__init__()
self.action = action
self.ui_any_color = QtGui.QLabel('Reset')
self.ui_swatch_01 = QColorSwatch()
self.ui_swatch_01.color = QtGui.QColor(255,0,0)
self.ui_swatch_02 = QColorSwatch()
self.ui_swatch_02.color = QtGui.QColor(0,255,0)
self.ui_swatch_03 = QColorSwatch()
self.ui_swatch_03.color = QtGui.QColor(0,0,255)
lay_main = QtGui.QGridLayout()
lay_main.setSpacing(5)
lay_main.setContentsMargins(5,5,5,5)
lay_main.addWidget(self.ui_any_color,0,0,1,4)
lay_main.addWidget(self.ui_swatch_01,1,0)
lay_main.addWidget(self.ui_swatch_02,1,1)
lay_main.addWidget(self.ui_swatch_03,1,2)
self.setLayout(lay_main)
# connections
self.ui_swatch_01.colorClicked.connect(self.clicked_swatch)
self.ui_swatch_02.colorClicked.connect(self.clicked_swatch)
self.ui_swatch_03.colorClicked.connect(self.clicked_swatch)
def mouseReleaseEvent(self,e):
self.action.trigger()
def clicked_swatch(self, col):
col = self.sender().color
self.action.trigger()
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
colAction = QtGui.QWidgetAction(self)
ql = ColorFilters(colAction)
colAction.setDefaultWidget(ql)
colAction.triggered.connect(self.clicked_color)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(colAction)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Menubar')
self.show()
def clicked_color(self):
print 'Clicked'
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

Instead of trying to use the triggered signal it creates a new signal that sends that information. Also you should know that a signal can also connect to another signal as I show below.
import sys
from PySide import QtGui, QtCore
class QColorSwatch(QtGui.QPushButton):
colorClicked = QtCore.Signal(QtGui.QColor)
colorChanged = QtCore.Signal(object)
def __init__(self, *args, **kwargs):
super(QColorSwatch, self).__init__(*args, **kwargs)
self.setFixedWidth(18)
self.setFixedHeight(18)
self.setAutoFillBackground(True)
self._color = None
self.color = QtGui.QColor(0,0,0)
self.pressed.connect(self.color_clicked)
#property
def color(self):
return self._color
#color.setter
def color(self, value):
self._color = value
self.setIconSize(self.size())
pixmap = QtGui.QPixmap(self.size())
pixmap.fill(QtCore.Qt.black)
painter = QtGui.QPainter(pixmap)
painter.setBrush(QtGui.QColor(self.color))
painter.setPen(QtGui.QPen(QtCore.Qt.white, 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
painter.drawRect(1,1,self.size().width()-3,self.size().height()-3)
painter.end()
self.setIcon(pixmap)
self.colorChanged.emit(value)
def color_clicked(self):
self.colorClicked.emit(self.color)
class ColorFilters(QtGui.QWidget):
colorSelected = QtCore.Signal(QtGui.QColor)
def __init__(self, parent=None):
super(ColorFilters, self).__init__(parent)
lay_main = QtGui.QGridLayout(self)
lay_main.setSpacing(5)
lay_main.setContentsMargins(5,5,5,5)
self.ui_any_color = QtGui.QLabel('Reset')
lay_main.addWidget(self.ui_any_color,0,0,1,4)
self.ui_any_color.installEventFilter(self)
for i, color in enumerate((QtGui.QColor(255,0,0), QtGui.QColor(0,255,0), QtGui.QColor(0,0,255))):
ui_swatch = QColorSwatch()
ui_swatch.color = color
lay_main.addWidget(ui_swatch,1,i+1)
ui_swatch.colorClicked.connect(self.colorSelected)
def eventFilter(self, obj, event):
if obj == self.ui_any_color and event.type() == QtCore.QEvent.Type.MouseButtonPress:
self.colorSelected.emit(QtGui.QColor)
return super(ColorFilters, self).eventFilter(obj, event)
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
colAction = QtGui.QWidgetAction(self)
ql = ColorFilters(self)
colAction.setDefaultWidget(ql)
ql.colorSelected.connect(self.clicked_color)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(colAction)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Menubar')
self.show()
def clicked_color(self, color):
if not color.isValid():
print("reset")
else:
print('Clicked', color)
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

Related

How can i capture a mouse clicks onto the main Window in a child class

I would like to capture mouse clicks onto the MainWindow in a child class of the application.
I've tried the following but without success:
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
from abc import ABCMeta, abstractmethod
class BaseView(object):
def __init__(self,parent, page=None):
self.parent = parent
self.page = page
#abstractmethod
def preprare_view(self):
pass
#abstractmethod
def clean_up_view(self):
pass
class FooView(BaseView):
def __init__(self, parent, page):
super(FooView, self).__init__(parent, page)
self.parent = parent
def mousePressEvent(self, QMouseEvent):
print(parent.QMouseEvent.pos())
def mouseReleaseEvent(self, QMouseEvent):
cursor = QtGui.QCursor()
print(parent.cursor.pos())
class Example(QtWidgets.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.foo = "fooview"
self.Foo = FooView(self,self.foo)
qbtn = QtWidgets.QPushButton('Quit', self)
qbtn.resize(qbtn.sizeHint())
qbtn.move(50, 50)
self.setGeometry(0, 0, 1024, 768)
self.setWindowTitle('Quit button')
self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)
self.show()
def main():
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I'm wondering how I can capture the mouse clicks in the FooView child class - is that even possible?
There is terminology that the OP uses that is confusing, for example FooView is a child class of BaseView but that has nothing to do with Qt so it is irrelevant for this case so I will omit that class and show the example of how another class can obtain information about the click event of a widget.
The logic is to create a class that inherits from QObject and apply an event filter to the other widget, then override the eventFilter method where the events of the widget are obtained.
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
class MouseObserver(QtCore.QObject):
def __init__(self, widget):
super(MouseObserver, self).__init__(widget)
self._widget = widget
self.widget.installEventFilter(self)
#property
def widget(self):
return self._widget
def eventFilter(self, obj, event):
if obj is self.widget:
if event.type() == QtCore.QEvent.MouseButtonPress:
print(event.pos(), QtGui.QCursor.pos())
elif event.type() == QtCore.QEvent.MouseButtonRelease:
print(event.pos(), QtGui.QCursor.pos())
return super(MouseObserver, self).eventFilter(obj, event)
class Example(QtWidgets.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.observer = MouseObserver(self)
qbtn = QtWidgets.QPushButton("Quit", self)
qbtn.resize(qbtn.sizeHint())
qbtn.move(50, 50)
self.setGeometry(0, 0, 1024, 768)
self.setWindowTitle("Quit button")
self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)
self.show()
def main():
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

PyQt5, how to make image toggle button with QAbstractButton

I have a PicButton class based on QAbtractButton that has the normal, hover and pressed. However, when clicked the button only changed to the pixmap_pressed briefly and then switch back to standard.
How can I make it behaves like a toggle button so that the pressed pixmap will stay after pressed?
import numpy as np
import time, sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QMainWindow
class PicButton(QAbstractButton):
def __init__(self, pixmap, pixmap_hover, pixmap_pressed, parent=None):
super(PicButton, self).__init__(parent)
self.pixmap = pixmap
self.pixmap_hover = pixmap_hover
self.pixmap_pressed = pixmap_pressed
self.pressed.connect(self.update)
# self.released.connect(self.update)
def paintEvent(self, event):
pix = self.pixmap_hover if self.underMouse() else self.pixmap
if self.isDown():
pix = self.pixmap_pressed
painter = QPainter(self)
painter.drawPixmap(event.rect(), pix)
def enterEvent(self, event):
self.update()
def leaveEvent(self, event):
self.update()
def sizeHint(self):
return self.pixmap.size()
class App(QMainWindow):
def __init__(self):
super().__init__()
self.left = 0
self.top = 0
self.width = 800
self.height = 800
self.initUI()
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
self.recBtn = PicButton(QPixmap('./img/playrecstop/rec_512.png'),QPixmap('./img/playrecstop/recHL_512.png'),\
QPixmap('./img/playrecstop/recActive_512.png'))
self.recBtn.setText("rec")
self.recBtn.clicked.connect(self.controlButtons)
self.stopBtn = PicButton(QPixmap('./img/playrecstop/stop_512.png'), QPixmap('./img/playrecstop/stopHL_512.png'),\
QPixmap('./img/playrecstop/stopActive_512.png'))
self.stopBtn.setText("stop")
self.stopBtn.clicked.connect(self.controlButtons)
self.leftLayout = QHBoxLayout()
self.rightLayout = QHBoxLayout()
self.rightLayout.addWidget(self.recBtn)
self.rightLayout.addWidget(self.stopBtn)
self.mainLayout = QHBoxLayout()
self.mainLayout.addLayout(self.leftLayout)
self.mainLayout.addLayout(self.rightLayout)
self.setCentralWidget(QWidget(self))
self.centralWidget().setLayout(self.mainLayout)
self.show()
def controlButtons(self):
sender = self.sender()
if (sender.text() == 'stop'):
print ("Stop")
elif (sender.text() == 'rec'):
print ("REC...")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Thanks
QAbstractButton has a checkable property that allows you to implement the logic you want:
class PicButton(QAbstractButton):
def __init__(self, pixmap, pixmap_hover, pixmap_pressed, parent=None):
super(PicButton, self).__init__(parent)
self.pixmap = pixmap
self.pixmap_hover = pixmap_hover
self.pixmap_pressed = pixmap_pressed
self.setCheckable(True)
def paintEvent(self, event):
pix = self.pixmap_hover if self.underMouse() else self.pixmap
if self.isChecked():
pix = self.pixmap_pressed
painter = QPainter(self)
painter.drawPixmap(event.rect(), pix)
def enterEvent(self, event):
self.update()
def leaveEvent(self, event):
self.update()
def sizeHint(self):
return self.pixmap.size()

pyqt closing a custom dialog in main window via mouse click

Q. is it possible, dialog closes itself and return color name just when user clicked or double clicked color item
Below is working example (hopefully to demonstrate problem). clicking on canvas area will pop up color dialog. currently user has to select color and then hit 'OK' button, where as intent is complete when user click on color. Just wanted to save user time, one bit.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic, QtMultimedia, QtMultimediaWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
colorsDict = { 'White': '0xFFFFFF','DarkGray': '0xA9A9A9','DarkSlateGray': '0x2F4F4F','LightSlateGray': '0x778899','DimGray': '0x696969','Gray': '0x808080','SlateGray': '0x708090','Black': '0x000000','DarkRed': '0x8B0000','Darkorange': '0xFF8C00','FireBrick': '0xB22222','Crimson': '0xDC143C','Salmon': '0xFA8072'}
def hexToQColor (h):
h = h.lstrip('#') # general usage safety
# h = h.lstrip('0x') # my use case
if h.find('0x') == 0:
h = h.split('0x')[1]
rgb = tuple(int(h[i:i+2], 16) for i in (0, 2 ,4))
return QColor(rgb[0],rgb[1],rgb[2])
class FfmpegColorDialog(QDialog):
"""
Custom FFMPEG Color Picker class
"""
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(FfmpegColorDialog, self).__init__(parent)
# self.ui = uic.loadUi('ui/ffmpeg_colors.ui', self)
self.setWindowTitle("FFMPEG Color Picker")
self.listWidget = QListWidget()
self.readPrefs()
self.listWidget.setFlow(QListView.LeftToRight)
self.listWidget.setResizeMode(QListView.Adjust)
self.listWidget.setGridSize(QSize(32, 32))
self.listWidget.setSpacing(5)
self.listWidget.setViewMode(QListView.IconMode)
self.listWidget.itemClicked.connect(self.itemClicked)
self.listWidget.itemDoubleClicked.connect(self.itemDoubleClicked)
layout = QVBoxLayout(self)
layout.addWidget(self.listWidget)
# OK and Cancel buttons
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def readPrefs(self):
"""
reading preferences from module for Data in UI
"""
for each in colorsDict.keys():
item = colorsDict[each]
listItem = QListWidgetItem()
listItem.setToolTip(each)
listItem.setSizeHint(QSize(30, 30))
color = hexToQColor(item)
listItem.setBackground(QBrush(color))
self.listWidget.addItem(listItem)
def itemClicked(self,item):
self.listWidget.setCurrentItem(item)
# self.accept()
def itemDoubleClicked(self,item):
c = item.background().color()
self.listWidget.setCurrentItem(item)
result = self.exec_()
return(c,result==QDialog.Accepted)
def getResults(self):
if self.exec_() == QDialog.Accepted:
item = self.listWidget.currentItem()
# print (item.toolTip())
return ( item.toolTip())
else:
return None
def getUserColor(self):
return (self.listWidget.currentItem().toolTip())
#staticmethod
def getFinalColor(parent=None):
dialog = FfmpegColorDialog(parent)
result = dialog.exec_()
color = dialog.getUserColor()
return(color,result==QDialog.Accepted)
class MainWindow(QMainWindow):
central_widget = None
layout_container = None
def __init__(self):
super(MainWindow, self).__init__()
self.central_widget = QWidget()
self.layout_container = QVBoxLayout()
self.central_widget.setLayout(self.layout_container)
self.setCentralWidget(self.central_widget)
self.layout_container.addWidget(GraphicsView())
class GraphicsView(QGraphicsView):
def __init__(self):
super(GraphicsView, self).__init__()
self.scene = QGraphicsScene()
self.setScene(self.scene)
self.text = None
self.createText()
def createText(self):
self.text = QGraphicsTextItem()
font = QFont()
font.setPixelSize(40)
self.text.setFont(font)
self.text.setPlainText("Sample Text To Test")
self.scene.addItem(self.text)
def mousePressEvent(self, event):
r,ok = FfmpegColorDialog.getFinalColor()
hc = colorsDict[r]
rgb = hexToQColor(hc)
self.text.setDefaultTextColor(rgb)
if __name__ == '__main__':
app = QApplication(sys.argv)
# dia = FfmpegColorDialog()
# dia.show()
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
Just connect the clicked signal of the QListWidget to the accept slot of FfmpegColorDialog:
class FfmpegColorDialog(QDialog):
"""
Custom FFMPEG Color Picker class
"""
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(FfmpegColorDialog, self).__init__(parent)
# ...
self.listWidget = QListWidget()
self.listWidget.clicked.connect(self.accept) # <---
# ...

Pyqt5 - Back to hidden MainWindows

I'm making a program to specify a specific area using pyqt5.
If I click on the capture button, I will hide the MainWindow and display a screen to specify the area. I want to clear the screen and return to the mainwindow by pressing the esc key. But MainWindow does not show again. How should I work it?
form_class = uic.loadUiType("prototype.ui")[0]
class MainWindow(QtWidgets.QMainWindow, form_class) :
def __init__(self):
super().__init__()
self.setupUi(self)
self.Capture_Button.clicked.connect(self.Capture_Btn_clicked)
self.CaptureWindow = CaptureWidget()
self.CaptureWindow.hide()
def Capture_Btn_clicked(self) :
self.hide()
self.CaptureWindow.close()
self.CaptureWindow.__init__()
self.CaptureWindow.show()
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
def enterEvent(self, QEvent):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.setWindowOpacity(1)
This is the class that specifies the area (some of the code is omitted).
class CaptureWidget(QtWidgets.QDialog):
def __init__(self):
super().__init__()
root = tk.Tk()
self.setupUi(self)
def setupUi(self) :
self.screen_width = root.winfo_screenwidth()
self.screen_height = root.winfo_screenheight()
self.setGeometry(0, 0, self.screen_width, self.screen_height)
self.setWindowTitle(' ')
self.begin = QtCore.QPoint()
self.end = QtCore.QPoint()
self.setWindowOpacity(0.3)
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
self.setWindowFlags(QtCore.Qt.FramelessWindowHint|QtCore.Qt.WindowStaysOnTopHint)
print('Capture the screen...')
self.is_set_region = False
self.is_mouse_click = False
self.show()
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_Escape:
print('esc')
self.close()
elif key == Qt.Key_F1:
self.close()
self.__init__()
First of all, instead of overwriting the keyPressEvent method, it is easier to use QShortcut. On the other hand for this case it is better to create a signal that indicates when the escape key is pressed connecting it to the show method.
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class CaptureWidget(QtWidgets.QDialog):
escape_pressed = QtCore.pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi()
def setupUi(self):
self.setWindowOpacity(0.3)
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
shorcut_scaped = QtWidgets.QShortcut(QtCore.Qt.Key_Escape, self)
shorcut_scaped.activated.connect(self.escape_pressed)
shorcut_scaped.activated.connect(self.close)
shorcut = QtWidgets.QShortcut(QtCore.Qt.Key_F1, self)
shorcut.activated.connect(self.close)
form_class, _ = uic.loadUiType("prototype.ui")
class MainWindow(QtWidgets.QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
self.Capture_Button.clicked.connect(self.Capture_Btn_clicked)
self.CaptureWindow = CaptureWidget()
self.CaptureWindow.escape_pressed.connect(self.show)
#QtCore.pyqtSlot()
def Capture_Btn_clicked(self):
self.hide()
self.CaptureWindow.showFullScreen()
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
def enterEvent(self, QEvent):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.setWindowOpacity(1)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

PyQt4: Use QVariantAnimation to animate between two values

I have a custom progress bar that I would like to animate as it changes from one value to another. When I get a value, I repaint the rectangle which represents the progress bar - so I think this should be as simple as animating the value itself and redrawing on each change. I've been looking through the Animation Framework documentation and I"m pretty sure subclassing a QVariantAnimation will do what I need - but there are little to no Python examples that I can find, and I'm a bit lost.
Here's where I've got so far (please excuse me if this is way off):
import sys
from PyQt4 import QtGui, QtCore
class AnimateBetweenNums(QtCore.QVariantAnimation):
def __init__(self):
QtCore.QVariantAnimation.__init__(self)
def updateCurrentValue(self, value):
print value.toString()
class MyProgressbar(QtGui.QWidget):
def __init__(self):
super(MyProgressbar, self).__init__()
self.initUI()
def initUI(self):
self.setMinimumSize(2, 2)
self.value = 50
def setValue(self, value):
oldValue = 10
newValue = 70
anim = AnimateBetweenNums()
anim.setStartValue(oldValue)
anim.setEndValue(newValue)
anim.setDuration(1000)
anim.start()
anim.valueChanged.connect(self.updateValue)
def updateValue(self, value):
self.value = value
self.repaint()
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
self.drawWidget(qp)
qp.end()
def drawWidget(self, qp):
size = self.size()
w = size.width()
h = size.height()
till = int(((w / 100.0) * self.value))
#the bar
qp.setPen(QtGui.QColor(255, 255, 255))
qp.setBrush(QtGui.QColor(0, 228, 47))
qp.drawRect(0, 0, till, h)
#the box
pen = QtGui.QPen(QtGui.QColor(75,80,100), 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setBrush(QtCore.Qt.NoBrush)
qp.drawRect(0, 0, w - 1, h - 1)
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QtGui.QVBoxLayout()
self.button10 = QtGui.QPushButton("10")
hbox.addWidget(self.button10)
self.button70 = QtGui.QPushButton("70")
hbox.addWidget(self.button70)
self.progress = MyProgressbar()
hbox.addWidget(self.progress)
self.setLayout(hbox)
self.setGeometry(300, 300, 390, 210)
self.show()
self.button10.clicked.connect(self.changeValue10)
self.button70.clicked.connect(self.changeValue70)
def changeValue10(self, value):
self.progress.setValue(10)
self.progress.repaint()
def changeValue70(self, value):
self.progress.setValue(70)
self.progress.repaint()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Below is a re-written version of your script that hopefully does what you intended. The animation object should only be created once, and because you are using Python 2 with PyQt4, you need to make sure any QVariant values are converted correctly. I also changed the setValue() method so that it restarts from the previous value.
import sys
from PyQt4 import QtGui, QtCore
class AnimateBetweenNums(QtCore.QVariantAnimation):
def __init__(self):
QtCore.QVariantAnimation.__init__(self)
def updateCurrentValue(self, value):
print value.toString()
class MyProgressbar(QtGui.QWidget):
def __init__(self):
super(MyProgressbar, self).__init__()
self.initUI()
def initUI(self):
self.setMinimumSize(2, 2)
self.anim = AnimateBetweenNums()
self.anim.setDuration(1000)
self.anim.valueChanged.connect(self.updateValue)
self.value = 50
def setValue(self, value):
self.anim.setStartValue(self.value)
self.anim.setEndValue(value)
self.anim.start()
def updateValue(self, value):
self.value = QtCore.QVariant(value).toInt()[0]
self.repaint()
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
self.drawWidget(qp)
qp.end()
def drawWidget(self, qp):
size = self.size()
w = size.width()
h = size.height()
till = int(((w / 100.0) * self.value))
#the bar
qp.setPen(QtGui.QColor(255, 255, 255))
qp.setBrush(QtGui.QColor(0, 228, 47))
qp.drawRect(0, 0, till, h)
#the box
pen = QtGui.QPen(QtGui.QColor(75,80,100), 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setBrush(QtCore.Qt.NoBrush)
qp.drawRect(0, 0, w - 1, h - 1)
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QtGui.QVBoxLayout()
self.button10 = QtGui.QPushButton("10")
hbox.addWidget(self.button10)
self.button70 = QtGui.QPushButton("70")
hbox.addWidget(self.button70)
self.progress = MyProgressbar()
hbox.addWidget(self.progress)
self.setLayout(hbox)
self.setGeometry(300, 300, 390, 210)
self.show()
self.button10.clicked.connect(self.changeValue10)
self.button70.clicked.connect(self.changeValue70)
def changeValue10(self, value):
self.progress.setValue(10)
def changeValue70(self, value):
self.progress.setValue(70)
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Categories

Resources