My day's question is about apply CSS in default button in Gtk.MessageDialog. I tried a lot things without result.
The deal is to find th good id like buttons, or GTKbutton, or GtkMessageDialog.Button,......
#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-
#demo_messagedialog_css.py
from gi.repository import Gtk,Gdk
class show_message_dlg:
def __init__(self, message, type_message=Gtk.MessageType.INFO,stock_message=Gtk.STOCK_DIALOG_INFO, decorate=True):
"""
This Function is used to show an message
error dialog when an error occurs.
error_string - The error string that will be displayed on the dialog.
==>type_message=gtk.MESSAGE_ERROR for error message
==>type_message=gtk.MESSAGE_INFO for information message
==>type_message=gtk.MESSAGE_WARNING for warning message
GTK_WIN_POS_NONE
GTK_WIN_POS_CENTER equivalent in python to Gtk.WindowPosition.CENTER
GTK_WIN_POS_MOUSE equivalent in python to Gtk.WindowPosition.MOUSE
GTK_WIN_POS_CENTER_ALWAYS equivalent in python to Gtk.WindowPosition.CENTER_ALWAYS
GTK_WIN_POS_CENTER_ON_PARENT equivalent in python to Gtk.WindowPosition.CENTER_ON_PARENT
"""
self.message = message
self.message_dlg = Gtk.MessageDialog(type = type_message
, buttons = Gtk.ButtonsType.OK)
self.message_dlg.set_decorated(decorate)
self.message_dlg.set_markup(self.message)
self.message_dlg.set_position(Gtk.WindowPosition.CENTER_ON_PARENT )
style_provider = Gtk.CssProvider()
css = """
GtkMessageDialog
{ background:linear-gradient(to bottom, green, rgba(0,255,0,0));}
#Buttons{ background-color: yellow}
"""
style_provider.load_from_data(css)
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def run(self):
reponse = self.message_dlg.run()
self.message_dlg.destroy()
return reponse
if __name__ == "__main__":
exemple = show_message_dlg(u"message in the box dialog ")
exemple.run()
Gtk.main()
after few white night and 150 black coffe I found a small part of answer
#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-
#demo_messagedialog_css1.py
from gi.repository import Gtk,Gdk
class MyButtonClass(Gtk.Button):
__gtype_name__ = 'MyButton'
def __init__(self, label):
Gtk.Button.__init__(self, label)
self.connect("clicked", self._clicked1)
def _clicked1(self, button):
print "button ok clicked"
class show_message_dlg:
def __init__(self, message, type_message=Gtk.MessageType.INFO,stock_message=Gtk.STOCK_DIALOG_INFO, decorate=True):
self.message = message
self.message_dlg = Gtk.MessageDialog(type = type_message)
self.message_dlg.set_decorated(decorate)
self.message_dlg.set_markup(self.message)
self.message_dlg.set_position(Gtk.WindowPosition.CENTER_ALWAYS )
button_v = MyButtonClass('Ok button')
self.message_dlg.add_action_widget(button_v, Gtk.ResponseType.OK)
self.message_dlg.set_default_response(Gtk.ResponseType.OK)
# line below necessary if button not defined like Gtk.MessageDialog(type = type_message, buttons = Gtk.ButtonsType.OK)
self.message_dlg.show_all()
style_provider = Gtk.CssProvider()
css = """
GtkMessageDialog
{ background:linear-gradient(to bottom, yellow, rgba(0,255,0,0));}
MyButton {
color: darkgrey;
font: Comic Sans 20;} /* run OK for label font */
MyButton GtkLabel{ background-color: blue} /* run OK for button background label*/
/*MyButton GtkLabel{ background:linear-gradient(to right, yellow, blue,yellow,green,red,orange);}*/ /* run OK for button background label*/
MyButton:active GtkLabel{ background-color: red;} /* do not run if state change */
"""
style_provider.load_from_data(css)
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def run(self):
reponse = self.message_dlg.run()
self.message_dlg.destroy()
return reponse
if __name__ == "__main__":
exemple = show_message_dlg(u"message in the dialog box ")
response = exemple.run()
if response == Gtk.ResponseType.OK:
print("OK button clicked and end")
else:
print("destroyed")
Gtk.main()
please note special class button with class atribut gtype_name = 'MyButton' and CSS command adressed by MyButton {}
Now I don't understand why part below not OK when I click on button
MyButton:active GtkLabel{ background-color: red;}
ok I found a solution for specific problem button
MyButton:active GtkLabel{ background: red;}
my exemple
#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-
#demo_messagedialog_css2.py
from gi.repository import Gtk,Gdk
class MyButtonClass(Gtk.Button):
__gtype_name__ = 'MyButton'
def __init__(self, label):
Gtk.Button.__init__(self, label)
self.connect("clicked", self._clicked1)
def _clicked1(self, button):
print "button ok clicked"
class show_message_dlg:
def __init__(self, message, type_message=Gtk.MessageType.INFO,stock_message=Gtk.STOCK_DIALOG_INFO, decorate=True):
self.message = message
self.message_dlg = Gtk.MessageDialog(type = type_message)
self.message_dlg.set_decorated(decorate)
self.message_dlg.set_markup(self.message)
self.message_dlg.set_position(Gtk.WindowPosition.CENTER_ALWAYS )
button_v = MyButtonClass('Ok button')
self.message_dlg.add_action_widget(button_v, Gtk.ResponseType.OK)
self.message_dlg.set_default_response(Gtk.ResponseType.OK)
# line below necessary if button not defined like Gtk.MessageDialog(type = type_message, buttons = Gtk.ButtonsType.OK)
self.message_dlg.show_all()
style_provider = Gtk.CssProvider()
css = """
GtkMessageDialog
{ background:linear-gradient(to bottom, yellow, rgba(0,255,0,0));}
MyButton {
color: darkgrey;
font: Comic Sans 20;}
MyButton:active { background: red;}
MyButton GtkLabel{ background:linear-gradient(to right, yellow, blue,yellow,green,red,orange);}
"""
style_provider.load_from_data(css)
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def run(self):
reponse = self.message_dlg.run()
self.message_dlg.destroy()
return reponse
if __name__ == "__main__":
exemple = show_message_dlg(u"message in the dialog box ")
response = exemple.run()
if response == Gtk.ResponseType.OK:
print("OK button clicked and end")
else:
print("destroyed")
Gtk.main()
Related
How can I implement this in Qt, I am using PyQt and Qt Designer but confusing how to use layering like in the following image.
I want to first layer in index 0 to show the image or video,
then the second layer in index 2 is media control which can hide when no move from mouse,
and layer 3 in index 3 when change the volume in example
layer 4 in index 4 for notification etc.
is possible to do this in Qt?
There is a simple way to implement "layers" - you can add child widgets without any layout and resize/move them on resize event of host widget (using event filter). First layer can be organized with any layout as usual.
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt
class Layer(QtCore.QObject):
def __init__(self, host, child, alignment = Qt.AlignLeft, setWidth = False, setHeight = False, parent = None):
super().__init__(parent)
self._host = host
self._child = child
self._alignment = alignment
self._setWidth = setWidth
self._setHeight = setHeight
child.setParent(host)
host.installEventFilter(self)
def eventFilter(self, watched, event):
if watched != self._host or event.type() != QtCore.QEvent.Resize:
return False
hostSize = event.size()
childSize = self._child.sizeHint()
alignment = self._alignment
x = 0
y = 0
dWidth = max(0, hostSize.width() - childSize.width())
dHeight = max(0, hostSize.height() - childSize.height())
if alignment & Qt.AlignRight:
x = dWidth
elif alignment & Qt.AlignHCenter:
x = dWidth / 2
if alignment & Qt.AlignVCenter:
y = dHeight / 2
elif alignment & Qt.AlignBottom:
y = dHeight
width = hostSize.width() if self._setWidth else childSize.width()
height = hostSize.height() if self._setHeight else childSize.height()
self._child.setGeometry(x, y, width, height)
return False
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
label1 = QtWidgets.QLabel("right label")
label2 = QtWidgets.QLabel("bottom label")
layer1 = Layer(widget, label1, Qt.AlignRight)
layer2 = Layer(widget, label2, Qt.AlignBottom | Qt.AlignHCenter, True)
widget.show()
sys.exit(app.exec_())
This is one of the very few cases for which using a layout is not suggested, as the visible widgets are "floating" and should be possibly moved around.
The solution is to create a "container" widget that has all those controls as children.
Then, some widgets will need some repositioning and resizing (for instance, the control bar should always be on bottom and occupy the whole width), and that can be implemented in the resizeEvent().
from PyQt5 import QtCore, QtGui, QtWidgets
class ControlBar(QtWidgets.QFrame):
def __init__(self, parent):
super().__init__(parent)
layout = QtWidgets.QVBoxLayout(self)
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
layout.addWidget(self.slider)
buttons = QtWidgets.QHBoxLayout()
layout.addLayout(buttons)
buttons.addWidget(QtWidgets.QToolButton(text='play'))
buttons.addWidget(QtWidgets.QToolButton(text='stop'))
buttons.addStretch()
class VolumeWidget(QtWidgets.QFrame):
def __init__(self, parent):
super().__init__(parent)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(2, 2, 2, 0)
layout.setSpacing(1)
handle = QtWidgets.QFrame()
handle.setFixedHeight(12)
handle.setStyleSheet('''
QFrame {
border: 1px solid darkGray;
border-radius: 2px;
background: #aa646464;
}
''')
layout.addWidget(handle)
volumeLayout = QtWidgets.QHBoxLayout()
layout.addLayout(volumeLayout)
for i in range(4):
volumeLayout.addWidget(QtWidgets.QSlider(QtCore.Qt.Vertical))
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.startPos = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() == QtCore.Qt.LeftButton:
delta = event.pos() - self.startPos
self.move(self.pos() + delta)
class Notification(QtWidgets.QFrame):
def __init__(self, parent):
super().__init__(parent)
layout = QtWidgets.QHBoxLayout(self)
self.label = QtWidgets.QLabel('Notification', alignment=QtCore.Qt.AlignCenter)
layout.addWidget(self.label)
class PlayerWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.video = QtWidgets.QLabel(self)
self.video.setPixmap(QtGui.QPixmap('movie.png'))
self.video.setScaledContents(True)
self.controlBar = ControlBar(self)
self.notification = Notification(self)
self.volumeWidget = VolumeWidget(self)
self.volumeWidget.move(30, 30)
self.setStyleSheet('''
VolumeWidget, ControlBar {
border: 1px outset darkGray;
border-radius: 4px;
background: #aad3d3d3;
}
VolumeWidget:hover, ControlBar:hover {
background: #d3d3d3;
}
Notification {
border: 1px outset darkGray;
border-radius: 4px;
background: #aa242424;
}
Notification QLabel {
color: white;
}
''')
def sizeHint(self):
if self.video.pixmap() and not self.video.pixmap().isNull():
return self.video.pixmap().size()
return QtCore.QSize(640, 480)
def resizeEvent(self, event):
# set the geometry of the "video"
videoRect = QtCore.QRect(
QtCore.QPoint(),
self.video.sizeHint().scaled(self.size(), QtCore.Qt.KeepAspectRatio))
videoRect.moveCenter(self.rect().center())
self.video.setGeometry(videoRect)
# control panel
controlHeight = self.controlBar.sizeHint().height()
controlRect = QtCore.QRect(0, self.height() - controlHeight,
self.width(), controlHeight)
self.controlBar.setGeometry(controlRect)
# notification
notificationWidth = max(self.notification.sizeHint().width(), self.width() * .6)
notificationRect = QtCore.QRect(
(self.width() - notificationWidth) * .5, 20,
notificationWidth, self.notification.sizeHint().height()
)
self.notification.setGeometry(notificationRect)
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.fillRect(self.rect(), QtCore.Qt.black)
Note that in this simple case I only used an image. If you want to play video, you should use the Qt Multimedia module, and in order to correctly have transparency of controls a QGraphicsView with a QGraphicsVideoItem must be used.
In this case, PlayerWidget can directly be a subclass of QGraphicsView.
This example:
# test1.py
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout, QVBoxLayout, QPushButton, QRadioButton, \
QGroupBox, QButtonGroup
from PyQt5.Qt import Qt
def main():
app = QApplication([])
mainForm = MainForm()
mainForm.show()
app.exec()
# end function
class MainForm(QWidget):
def __init__(self):
super().__init__()
self.rdoRed = QRadioButton('Red')
self.rdoGreen = QRadioButton('Green')
self.rdoBlue = QRadioButton('Blue')
self.vblColor = QVBoxLayout()
self.vblColor.addWidget(self.rdoRed)
self.vblColor.addWidget(self.rdoGreen)
self.vblColor.addWidget(self.rdoBlue)
self.gbColor = QGroupBox('Choose Color')
self.gbColor.setStyleSheet('QGroupBox:title {'
'subcontrol-origin: padding; }')
self.gbColor.setLayout(self.vblColor)
self.vboxLayout = QVBoxLayout()
self.vboxLayout.addWidget(self.gbColor)
self.setLayout(self.vboxLayout)
# end function
# end class
if __name__ == '__main__':
main()
Renders like this on Ubuntu 18.04:
I'd like the Choose Color text currently just above the top of the QGroupBox boundary line to instead be in line with the top of the QGroupBox boundary, like the Qt docs show:
Notice how Package selection is in line with the top boundary line of the QGroupBox, I'd like to do the same with the Choose Color title in the example I have above.
Is this an operating system limitation and what I'm asking isn't possible? I'm using Ubuntu 18.04.
Or is there a setStyleSheet parameter I can pass in to achieve this? As you can see in the example above I attempted to set some style sheet properties to achieve this but I was unable to find such a property. Or is there some other means with which this can be achieved?
Try it:
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout, QVBoxLayout, QPushButton, QRadioButton, \
QGroupBox, QButtonGroup
from PyQt5.Qt import *
class MainForm(QWidget):
def __init__(self):
super().__init__()
self.rdoRed = QRadioButton('Red')
self.rdoGreen = QRadioButton('Green')
self.rdoBlue = QRadioButton('Blue')
self.vblColor = QVBoxLayout()
self.vblColor.addWidget(self.rdoRed)
self.vblColor.addWidget(self.rdoGreen)
self.vblColor.addWidget(self.rdoBlue)
self.gbColor = QGroupBox('Choose Color')
self.gbColor.setStyleSheet('''
QGroupBox {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
border: 2px solid #999999;
border-radius: 5px;
margin-top: 2ex; /*leave space at the top for the title */
font-size: 13px;
color: black;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center; /* position at the top center */
padding: 0 3px;
font-size: 13px;
color: black;
}
''')
self.gbColor.setLayout(self.vblColor)
self.vboxLayout = QVBoxLayout()
self.vboxLayout.addWidget(self.gbColor)
self.setLayout(self.vboxLayout)
def main():
app = QApplication([])
mainForm = MainForm()
mainForm.show()
app.exec()
if __name__ == '__main__':
main()
I am looking for a way to align text in a QCheckBox to both the right and left side. I cannot seems to find any ways to modify just the alignment of the text and not the checkbox itself.
I don't know if you can access the label associated with the checkbox or not, but if you cannot, a hack would be to set the checkbox label with an empty string and use another QLabel where you can use setAlignment(Qt::AlignJustify) to adjust your text to both the right and left side.
But then I don't know if you consider this modify the checkbox itself and not just the alignement.
I solved it using a trick.
Create a QCheckBox without putting any text in it.
And create a QLable so that you can center the text and click it.
Then it's possible.
Below is the example code.
You can refer to it.
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class MyApp(QWidget):
###### Define StyleSheet ######
DEFAULT_COLOR = {
'border': '#000000',
'hover': '#29adff'
}
CP_DEFAULT_STYLE = '''
QCheckBox::indicator:hover {{
border: 1px solid {hover};
background: white;
}}
QCheckBox::indicator {{
border: 1px solid {border};
background: white;
}}
'''
CP_DEFAULT_STYLE_SET_VALUE = CP_DEFAULT_STYLE.format(**DEFAULT_COLOR)
################################
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.cb = QCheckBox(self)
cp_label = QLabel('Click\nHere Me!!', self)
self.cb.setStyleSheet(self.CP_DEFAULT_STYLE_SET_VALUE)
cp_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
cp_label.setGeometry(75+30, 50+15, 60, 30)
self.cb.move(75+90, 50+20)
self.cb.clicked.connect(self.cpClick)
cp_label.mousePressEvent = self.cpLabelClick
cp_label.leaveEvent = self.cpLabelLeave
cp_label.enterEvent = self.cpLabelEnter
self.setWindowTitle('QCheckBox')
self.setGeometry(300, 300, 300, 200)
self.show()
def cpClick(self):
if not self.cb.isChecked():
self.cb.setStyleSheet(
self.CP_DEFAULT_STYLE_SET_VALUE
)
else:
self.cb.setStyleSheet('')
def cpLabelClick(self, _):
self.cb.setStyleSheet('')
self.cb.setChecked(
not self.cb.isChecked()
)
def cpLabelLeave(self, _):
self.cb.setStyleSheet('')
def cpLabelEnter(self, _):
if not self.cb.isChecked():
setColer = self.DEFAULT_COLOR.copy()
setColer['border'] = self.DEFAULT_COLOR['hover']
self.cb.setStyleSheet(
self.CP_DEFAULT_STYLE.format(**setColer)
)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
sys.exit(app.exec_())
or
If you use Qt Designer,
After creating one Qwidget, make QCheckBox and QLabel inside
Bring the QLabel to the front and make the QCheckBox deselected.
And if you write it like the code below, it works perfectly!
import os
import sys
from PyQt5.uic import loadUi
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
def resource_path(*relative_Path_AND_File):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = getattr(sys, '_MEIPASS', os.path.dirname(
os.path.abspath(__file__)))
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, '/'.join(relative_Path_AND_File))
class MyApp_Define:
cb: QCheckBox
cb_label: QLabel
class MyApp(QMainWindow, MyApp_Define):
###### Define StyleSheet ######
DEFAULT_COLOR = {
'border': '#000000',
'hover': '#29adff'
}
CP_DEFAULT_STYLE = '''
QCheckBox::indicator:hover {{
border: 1px solid {hover};
background: white;
}}
QCheckBox::indicator {{
border: 1px solid {border};
background: white;
}}
'''
CP_DEFAULT_STYLE_SET_VALUE = CP_DEFAULT_STYLE.format(**DEFAULT_COLOR)
################################
def __init__(self):
super().__init__()
loadUi(resource_path("TEST.ui"), self)
self.cb_label.installEventFilter(self)
self.cb_label.leaveEvent = self.cbLabelLeave
self.cb_label.mousePressEvent = self.cbLabelClick
def eventFilter(self, source: QObject, event: QEvent):
# 자동 종료 체크박스 안에 들어갈시
if (
source is self.cb_label and
event.type() == QEvent.Type.MouseMove and
not self.cb.isChecked()
):
self.cbLabelEnter()
return super().eventFilter(source, event)
def cbLabelClick(self, _):
self.cb.setStyleSheet('')
self.cb.setChecked(
not self.cb.isChecked()
)
if not self.cb.isChecked():
self.cbLabelEnter()
def cbLabelLeave(self, _):
self.cb.setStyleSheet('')
def cbLabelEnter(self, _=None):
if not self.cb.isChecked():
setColer = self.DEFAULT_COLOR.copy()
setColer['border'] = self.DEFAULT_COLOR['hover']
self.cb.setStyleSheet(
self.CP_DEFAULT_STYLE.format(**setColer)
)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
ex.show()
sys.exit(app.exec_())
The image below is an example of QtDesigner.
I am looking into using QMovie for some animated icons in my application. The code below demonstrates some basic usage of this class which I would like to also add as functionality to my application. The problem that I'm facing is that whenever QMovie is paused, scaling the content doesn't seem to work (see screenshots after code). The behaviour is observed in both ways - upscaling (resulting from increase of size of the window) and downscaling (resulting from the decrease of size of the window).
Any idea how to fix that?
from sys import exit, argv
from PyQt4.QtGui import QApplication, QWidget, QCheckBox, QPushButton, QLabel, QGridLayout, QIcon, QSizePolicy, QMovie
from PyQt4.QtCore import Qt, QSize, pyqtSlot, pyqtSignal, QPoint, QRect
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.toggled = False
self.initUI()
def initUI(self):
self.layout = QGridLayout()
self.label = QLabel()
self.label.setMinimumWidth(100)
self.label.setMinimumHeight(100)
self.label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
self.label_animation = QMovie('circles.gif')
self.label_animation.setScaledSize(QSize(100, 100))
self.label.setMovie(self.label_animation)
self.label_animation.start()
self.label_animation.setPaused(True)
# self.label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.layout.addWidget(self.label, 0, 0)
self.button = QPushButton()
self.button.setObjectName('button')
# self.button.setIcon(QIcon('icon.png'))
self.button.setStyleSheet('QPushButton#button{border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-top-left-radius: 10px; border-bottom-left-radius: 10px; border-image: url("icon.png"); background: transparent;}')
self.button.setMinimumWidth(100)
self.button.setMinimumHeight(100)
self.button.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
self.button.clicked.connect(self.toggle)
self.layout.addWidget(self.button, 0, 1)
self.setGeometry(200, 200, 400, 400)
self.setWindowTitle('Icons, Images && Video with PyQt')
self.setLayout(self.layout)
self.resize(self.layout.sizeHint())
def resizeEvent(self, event):
self.label_animation.setScaledSize(QSize(self.label.width(), self.label.height()))
#pyqtSlot()
def toggle(self):
style = 'QPushButton#button{border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-top-left-radius: 10px; border-bottom-left-radius: 10px; border-image: url("icon.png"); '
if not self.toggled:
style = style + 'background-color: rgb(255, 0, 0);}'
else:
style = style + 'background: transparent;}'
self.button.setStyleSheet(style)
self.label_animation.setPaused(self.toggled)
self.toggled = not self.toggled
def main():
app = QApplication(argv)
ex = Example()
ex.show()
exit(app.exec_())
if __name__ == '__main__':
main()
Screenshots:
Resizing window (paused QMovie) - QPushButton on the right with its border image is resized properly however on the left the QMovie's content inside the QLabel (label itself IS resized!). The screenshot below demonstrates failure to upscale the animation.
Resizing window (unpaused QMovie) - content of QMovie gets scaled properly the moment the animation is unpaused.
I made the gui in Qt Designer and then converted it into python using pyuic4. Now i want to capture the mouseover event on the buttons.
class window_b(QtGui.QDialog):
def __init__(self,parent=None):
super(window_b, self).__init__(parent)
window_a.setEnabled(False)
self.ui = Ui_Form_window_b()
self.ui.setupUi(self)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
def mouseMoveEvent (self,event):
source= self.sender()
#print source.name()
# The action I want to do when the mouse is over the button:
source.setStyleSheet("background-color:#66c0ff;border-radius: 5px;")
I put the mouseMoveEvent method on the widget and I want to detect which button on the Dialog sent the mouseOver event. I tried source.name() but it throws me this error
print source.name()
AttributeError: 'NoneType' object has no attribute 'name'
Any suggestion.
sender() is only useful for signals but the mouse hovering is an event not a signal (actually 2 events: QEvent.Enter and QEvent.Leave).
And to be able to handle events outside the buttons that received them, you need to install your window_b instance as an event filter for each button.
class window_b(QtGui.QDialog):
def __init__(self,parent=None):
super(window_b, self).__init__(parent)
window_a.setEnabled(False)
self.ui = Ui_Form_window_b()
self.ui.setupUi(self)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
# Get all the buttons (you probably don't want all of them)
buttons = self.findChildren(QtGui.QAbstractButton)
for button in buttons:
button.installEventFilter(self)
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.Enter:
print("mouse entered %s" % obj.objectName())
elif event.type() == QtCore.QEvent.Leave:
print("mouse leaved %s" % obj.objectName())
return super(window_b, self).eventFilter(obj, event)
If you only need to change the style, you can simply use the pseudo-state ":hover" in a stylesheet (from the designer, or in the constructor with self.setStyleSheet):
QPushButton {
border: 1px solid black;
padding: 5px;
}
QPushButton:hover {
border: 1px solid black;
border-radius: 5px;
background-color:#66c0ff;
}