i'm confused about eventFilter. I want fully disable QTabWidget being scrolled when mouse is hovering and wheel scrolling on it.
For example, i made a eventFilter that does scrolling QScrollArea when mouse is hovering and wheeling at QTabWidget. It works however QTabWidget will scrolling and change value too.
I tried with return False, True, or event.ignore() it still did not work that make QTabWidget stop changing value.
Here is my eventFilter code:
def eventFilter(self, obj, event):
# If mouse hovering genreTabData and wheel did scrolling
if obj is self.genreTabData and event.type() == QtCore.QEvent.Wheel:
self.scrollArea.horizontalScrollBar().setValue(self.scrollArea.horizontalScrollBar().value() + -event.angleDelta().y())
# Stop QTabWidget being change value after above code
# Tried return False, True, and event.ignore() but did not work
return super(mainForm, self).eventFilter(obj, event)
And this is my full code as example:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QEvent
import sys
class mainForm(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setupUi(self)
self.genreTabData.installEventFilter(self)
def setupUi(self, Form):
Form.resize(400, 101)
self.scrollArea = QtWidgets.QScrollArea(Form)
self.scrollArea.setGeometry(QtCore.QRect(10, 10, 381, 81))
self.scrollArea.setStyleSheet("QScrollBar:horizontal {height:12px;}\nQScrollBar:page:horizontal {border: 0px solid #999999;background-color: rgb(34, 35, 52);width:15px;margin: 0px 0px 0px 3px;}\nQScrollBar::handle:page:horizontal {min-height: 0px;border: 0px solid red;border-radius: 5px;background-color: rgb(92, 95, 141);}\nQScrollBar::add-line:horizontal {height: 0px;subcontrol-position: bottom;subcontrol-origin: margin;}\nQScrollBar::sub-line:horizontal {height: 0 px;subcontrol-position: top;subcontrol-origin: margin;}")
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 584, 67))
self.horizontalLayout = QtWidgets.QHBoxLayout(self.scrollAreaWidgetContents)
self.genreTabData = QtWidgets.QTabWidget(self.scrollAreaWidgetContents)
self.genreTabData.setMinimumSize(QtCore.QSize(0, 40))
self.genreTabData.setStyleSheet("QTabWidget::tab-bar {border: 1px solid gray;}\nQTabBar::tab {height: 20px; width: 100px; background: #EFF4F8; color: black; padding: 10px; border-radius: 15px; margin-left:10px; margin-right:10px;}\nQTabBar::tab:selected {background: #c3daf5;}\nQTabWidget::pane {border: none;}")
self.genreTabData.setUsesScrollButtons(False)
tabs = ["Test tab", "Test tab", "Test tab", "Test tab"]
for tab in tabs:
tabWidget = QtWidgets.QWidget()
self.genreTabData.addTab(tabWidget, tab)
self.horizontalLayout.addWidget(self.genreTabData)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
def eventFilter(self, obj, event):
if obj is self.genreTabData and event.type() == QtCore.QEvent.Wheel:
self.scrollArea.horizontalScrollBar().setValue(self.scrollArea.horizontalScrollBar().value() + -event.angleDelta().y())
return True
return super(mainForm, self).eventFilter(obj, event)
app = QtWidgets.QApplication(sys.argv)
w = mainForm()
w.show()
sys.exit(app.exec_())
The wheel event is managed by the tab bar, not the tab widget, so you need to install the filter on its tabBar():
self.genreTabData.tabBar().installEventFilter(self)
I need to change QComboBox background to red when mouse hover it;but in my qss style the QComboBox drop-down button change to red and the drop-down look like stranged(need to keep system default), it's look like raised style, that is not i wanted.
The simple qss style is:
QComboBox:hover {
background: red;
}
It looks like this when i try.
Try it:
import sys
from PyQt5 import QtWidgets
class Main(QtWidgets.QWidget):
def __init__(self):
super(Main, self).__init__()
sheets = [str(i) for i in range(1, 10)]
combo = QtWidgets.QComboBox()
combo.addItems(sheets)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(combo)
self.setLayout(layout)
StyleSheet = """
QComboBox {
border: 1px solid gray;
border-radius: 3px;
padding: 1px 18px 1px 3px;
min-width: 6em;
}
QComboBox:hover {
background: red;
color: #fff;
}
"""
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setStyleSheet(StyleSheet)
main = Main()
main.show()
sys.exit(app.exec_())
I have a code which reads sensor data and outputs it to a LCD number I am using python3 and pyqt5.
Now What i've been tyring to do with no luck is change the background colour of the LCD number when it reaches a certain value. e.g. when the value falls below 100 the background of the LCD widget is red or an image appears saying too low, if it is between 100-300 it is green and over 300 it goes red again. I hope this makes sense, does anyone know how I can achieve this using pyqt5?
here are the relevant segments of my code for the LCD Number
class Worker(QtCore.QThread):
valueFound = QtCore.pyqtSignal(int, name="valueFound")
...
def run(self):
while self.runFlag:
self.valueFound.emit(self.Pressure_Reading())
...
self.worker = Worker(self)
self.worker.valueFound.connect(self.OnValueFound)
....
def OnValueFound(self, value):
self.ui.lcdNumber.display(value)
Use Qt Style Sheets.
import sys
from random import randint
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QTimer
from ui import Ui_MainWindow
class Form(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.i = 0
self.voltageMin = 180
self.voltageMax = 180
self.ui.lcdNumberCur.display(self.i)
self.ui.lcdNumberCur.setStyleSheet("QLCDNumber { background-color: yellow }")
self.ui.pushButton.clicked.connect(self.startTimer)
self.timer = QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.updateData)
self.show()
def startTimer(self):
if self.ui.pushButton.text() == "Start Timer":
self.timer.start(1000)
self.ui.pushButton.setText("Stop Timer")
else:
self.ui.pushButton.setText("Start Timer")
self.timer.stop()
def updateData(self):
voltage = randint(80, 350) # <--- insert your average voltage here
self.ui.lcdNumberCur.display(voltage)
if voltage > self.voltageMax:
self.voltageMax = voltage
self.ui.lcdNumberMax.display(self.voltageMax)
if self.voltageMax > 300:
self.ui.lcdNumberMax.setStyleSheet("""QLCDNumber {
background-color: red;
color: white; }""")
else:
self.ui.lcdNumberMax.setStyleSheet("""QLCDNumber
{ background-color: green;
color: yellow;
}""")
elif voltage < self.voltageMin:
self.voltageMin = voltage
self.ui.lcdNumberMin.display(self.voltageMin)
if self.voltageMin < 90:
self.ui.lcdNumberMin.setStyleSheet("""QLCDNumber {
background-color: red;
color: white; }""")
else:
self.ui.lcdNumberMin.setStyleSheet("""QLCDNumber
{ background-color: green;
color: yellow;
}""")
if __name__ == '__main__':
app = QApplication(sys.argv)
frm = Form()
sys.exit(app.exec_())
I currently have a program which changes the color of the background of the QLCDumber widget when a certain value is displayed on the lcd number, is it possible for instead of a color being the background when a certain value is reached an image appears in the background, such as a smiley face?
Here is the relevant snippet of my code responsible for the change in color.
def OnValueFound(self, value):
self.ui.lcdNumber.display(value)
if 100 < value < 300:
self.ui.lcdNumber.setStyleSheet("""QLCDNumber {background-color: green; color: black;}""")
else:
self.ui.lcdNumber.setStyleSheet("""QLCDNumber {background-color:red; color: black;}""")
so instead of say the background color changing to another color it changes to an image?
I hope this makes sense.
I do not know if I understood you correctly. Try it border-image: url(E:/_Qt/img/heart.png);
import sys
from random import randint
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QTimer
from ui import Ui_MainWindow
class Form(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.i = 0
self.voltageMin = 180
self.voltageMax = 180
self.ui.lcdNumberCur.display(self.i)
self.ui.lcdNumberCur.setStyleSheet("""QLCDNumber {
background-color: yellow;
}""")
self.ui.pushButton.clicked.connect(self.startTimer)
self.timer = QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.updateData)
self.show()
def startTimer(self):
if self.ui.pushButton.text() == "Start Timer":
self.timer.start(1000)
self.ui.pushButton.setText("Stop Timer")
else:
self.ui.pushButton.setText("Start Timer")
self.timer.stop()
def updateData(self):
voltage = randint(80, 350) # <--- insert your average voltage here
self.ui.lcdNumberCur.display(voltage)
if voltage > self.voltageMax:
self.voltageMax = voltage
self.ui.lcdNumberMax.display(self.voltageMax)
if self.voltageMax > 300:
self.ui.lcdNumberMax.setStyleSheet("""QLCDNumber {
/* background-color: red; */
border-image: url(E:/_Qt/img/heart.png);
color: white; }""")
else:
self.ui.lcdNumberMax.setStyleSheet("""QLCDNumber
{ background-color: green;
color: yellow;
}""")
elif voltage < self.voltageMin:
self.voltageMin = voltage
self.ui.lcdNumberMin.display(self.voltageMin)
if self.voltageMin < 90:
self.ui.lcdNumberMin.setStyleSheet("""QLCDNumber {
background-color: red;
color: white; }""")
else:
self.ui.lcdNumberMin.setStyleSheet("""QLCDNumber
{ background-color: green;
color: yellow;
}""")
if __name__ == '__main__':
app = QApplication(sys.argv)
frm = Form()
sys.exit(app.exec_())
I am using PyQt to make an application that, amongst other things, shows information in a simple graphical diagram.
I have done this as a QWidget and reimplemented the paintEvent method to do the drawing. A small and very cut-down example is show below.
from PyQt4.QtCore import *
from PyQt4.QtGui import * # sloppy, I know, but done for speed! :-)
class Example(QMainWindow):
def __init__(self,parent=None):
super(Example,self).__init__(parent)
self.init_ui()
def init_ui(self):
base=QWidget()
layout=QVBoxLayout(base)
self.diagram=Diagram()
layout.addWidget(self.diagram)
self.setCentralWidget(base)
class Diagram(QWidget):
def __init__(self,parent=None):
super(Diagram,self).__init__(parent)
self.width=360
self.height=120
self.leftMargin=10
self.topMargin=10
def paintEvent(self,event=None):
painter=QPainter(self)
painter.setWindow(self.leftMargin,self.topMargin,self.width,self.height)
self.drawConnection(painter, 40, 25, 40, 90)
self.drawConnection(painter, 40, 90, 40, 110)
self.drawConnection(painter, 40, 110, 200, 100)
self.drawItem(painter, 40, 40)
self.drawItem(painter, 40, 90)
self.drawState(painter,200,100)
def drawConnection(self,painter,x0,y0,x1,y1):
pen=QPen()
pen.setWidth(4)
pen.setColor(QColor(50,50,200))
painter.setPen(pen)
painter.drawLine(x0,y0,x1,y1)
def drawItem(self,painter,x,y):
w=40
h=30
r=QRectF(x-(w/2),y-(h/2),w,h)
painter.drawRoundedRect(r,5.0,5.0)
grad=QLinearGradient(QPointF(15.0,20.0),QPointF(30.0,30.0))
pen=QPen()
pen.setWidth(2)
pen.setColor(QColor(10,10,10))
painter.setPen(pen)
brush=QBrush(QColor(0,200,10))
painter.setBrush(brush)
painter.drawRoundedRect(r,5.0,5.0)
def drawState(self,painter,x,y):
w=80
h=60
r=QRectF(x-(w/2),y-(h/2),w,h)
pen=QPen()
pen.setWidth(2)
pen.setColor(QColor(255,10,10))
painter.setPen(pen)
brush=QBrush(QColor(200,200,10))
painter.setBrush(brush)
painter.drawPie(r,5040,1440)
if __name__=='__main__':
app=QApplication(sys.argv)
example=Example()
example.show()
app.exec_()
Is it possible to add a QWidget instead of calling drawItem?
For example, a suitably styled QPushButton could go in place of the rounded rectangles.
Alternatively, what is the best way to go about creating a display that contains both widgets and painted items?
I have written a rounded child widget example, using the QSS.
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
ROUNDED_STYLE_SHEET = """QPushButton {
background-color: red;
border-style: outset;
border-width: 2px;
border-radius: 10px;
border-color: beige;
font: bold 14px;
min-width: 10em;
padding: 6px;
}
"""
class MyWidget(QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.mChildWidget = QPushButton(self)
self.resize(600, 400)
self.mChildWidget.resize(120, 80)
self.mChildWidget.move(300, 200)
self.mChildWidget.setStyleSheet(ROUNDED_STYLE_SHEET)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.show()
app.exec_()