I wanted a module programmed on PyQt5 that would make notifications appear on the right side of the screen, so i found a question here:
PyQt5 notification from QWidget
and i used this code with only a few changes, but the problem is, it creates a new window and does not show the QWidget on screen.
Here is the code
class Message(QWidget):
def __init__(self, title, message, parent=None):
QWidget.__init__(self, parent)
self.setLayout(QGridLayout())
self.titleLabel = QLabel(title, self)
self.titleLabel.setStyleSheet(
"font-family: 'Roboto', sans-serif; font-size: 14px; font-weight: bold; padding: 0;")
self.messageLabel = QLabel(message, self)
self.messageLabel.setStyleSheet(
"font-family: 'Roboto', sans-serif; font-size: 12px; font-weight: normal; padding: 0;")
self.buttonClose = QPushButton(self)
self.buttonClose.setIcon(QIcon("extra/close.png"))
self.buttonClose.setFixedSize(14, 14)
self.layout().addWidget(self.titleLabel, 0, 0)
self.layout().addWidget(self.messageLabel, 1, 0)
self.layout().addWidget(self.buttonClose, 0, 1, 2, 1)
class Notification(QWidget):
signNotifyClose = pyqtSignal(str)
def __init__(self, parent=None):
super(QWidget, self).__init__(parent)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
resolution = QDesktopWidget().screenGeometry(-1)
screenWidth = resolution.width()
screenHeight = resolution.height()
self.nMessages = 0
self.mainLayout = QVBoxLayout(self)
self.move(screenWidth, 0)
def setNotify(self, title, message):
m = Message(title, message, self)
self.mainLayout.addWidget(m)
m.buttonClose.clicked.connect(self.onClicked)
self.nMessages += 1
self.setStyleSheet("background-color: black;")
self.show()
def onClicked(self):
self.mainLayout.removeWidget(self.sender().parent())
self.sender().parent().deleteLater()
self.nMessages -= 1
self.adjustSize()
if self.nMessages == 0:
self.close()
and this is the file importing the previous one:
from notifierP import *
import sys
class Example(QWidget):
counter = 0
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setLayout(QVBoxLayout())
btn = QPushButton("Send Notify", self)
self.layout().addWidget(btn)
self.notification = Notification()
btn.clicked.connect(self.notify)
def notify(self):
self.counter += 1
print(self.counter)
self.notification.setNotify("Title{}".format(self.counter),
"message{}".format(self.counter))
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Example()
w.show()
sys.exit(app.exec_())
My Question is, why does this happen, and how can i fix it?
How it is on my screen
This all it shows, nothing else.
okay the problem here was that the
self.move()
was moving the widget outside the screen, after i changed its possition to inside the screen it works perfectly.
Related
I'm trying to replicate this with Python and PyQt6. I have been successful in creating a working prototype of it.
The problem:
SequenceMemory.request_round is a PyQt6.QtCore.pyqtSignal that is emitted when the user is to be displayed a new round for the game, be it at the start of the game or after a previous round. However, for some reason, when request_round is emitted, the GUI goes unresponsive for about half a second.
I've pin-pointed the problem to the self.request_round.emit() line in the new_round() method of the SequenceMemory class (after commenting out that line the GUI does not go unresponsive), but I can't seem to figure out why this occurs.
I thought the sleep() function in the CreateSequenceWorker class might be the cause but changing the integer passed to sleep() didn't change how long the GUI went unresponsive so I don't think that's the cause.
import sys
import queue
import random
import itertools
import functools
from time import perf_counter
from PyQt6 import QtWidgets as qtw
from PyQt6 import QtGui as qtg
from PyQt6 import QtCore as qtc
class SequenceMemory(qtw.QMainWindow):
SQUARE_PER_ROW = 3
request_round = qtc.pyqtSignal()
kill_thread = qtc.pyqtSignal()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.sequence_history = []
self.sequence_queue = queue.Queue()
self.main_menu()
def main_menu(self):
start_button = qtw.QPushButton("Start")
start_button.released.connect(self.start)
self.main_widget = self.takeCentralWidget()
self.setCentralWidget(start_button)
self.show()
def start(self):
self.setup_GUI()
self.create_board()
self.setup_thread()
self.start_button = self.takeCentralWidget()
self.setCentralWidget(self.main_widget)
self.new_round()
def setup_GUI(self):
self.main_widget = qtw.QWidget()
self.main_widget.setStyleSheet("background-color: white;")
self.main_widget.setLayout(qtw.QGridLayout())
self.main_widget.layout().setSpacing(0)
self.main_widget.layout().setContentsMargins(5, 5, 5, 10)
def setup_thread(self):
self.create_sequence_worker = CreateSequenceWorker()
self.create_sequence_worker_thread = qtc.QThread()
self.create_sequence_worker.moveToThread(
self.create_sequence_worker_thread
)
self.create_sequence_worker_thread.start()
self.create_sequence_worker.show_block.connect(self.update_board)
self.create_sequence_worker.hide_block.connect(self.update_board)
self.request_round.connect(self.create_sequence_worker.create_sequence)
def create_board(self):
self.buttons = [
tuple(
qtw.QPushButton()
for _ in range(self.SQUARE_PER_ROW)
)
for _ in range(self.SQUARE_PER_ROW)
]
for row, column in itertools.product(
range(self.SQUARE_PER_ROW), repeat=2
):
button = self.buttons[row][column]
button.setStyleSheet(
"""
background-color: rgb(186, 196, 255);
border: 5px solid white;
border-radius: 15px;
"""
)
button.setMinimumHeight(150)
self.main_widget.layout().addWidget(
button, row, column, 1, 1
)
def update_board(self, mode: int, row: int, column: int):
if mode:
button = self.buttons[row][column]
button.setStyleSheet(
"""
background-color: rgb(186, 255, 196);
border: 5px solid white;
border-radius: 15px;
"""
)
else:
button = self.buttons[row][column]
button.setStyleSheet(
"""
background-color: rgb(186, 196, 255);
border: 5px solid white;
border-radius: 15px;
"""
)
def new_round(self):
self.request_round.emit()
def closeEvent(self, a0: qtg.QCloseEvent):
self.kill_thread.emit()
self.create_sequence_worker_thread.quit()
self.main_menu()
class CreateSequenceWorker(qtc.QObject):
queue_ready = qtc.pyqtSignal(queue.Queue)
show_block = qtc.pyqtSignal(int, int, int)
hide_block = qtc.pyqtSignal(int, int, int)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.kill = False
self.sequence_history = []
self.sequence_queue = queue.Queue()
def sleep(self, duration: float):
start_time = perf_counter()
while perf_counter() - start_time < duration:
if self.kill:
return False
return True
def create_sequence(self):
self.sleep(0.5)
for row, column in self.sequence_history:
self.sequence_queue.put((row, column))
self.show_block.emit(1, row, column)
if self.sleep(0.5):
self.hide_block.emit(0, row, column)
else:
return
i = 0
while i < len(self.sequence_history) - self.sequence_queue.qsize() + 1:
row, column = random.randrange(3), random.randrange(3)
if self.sequence_history and (row, column) == self.sequence_history[-1]:
continue
self.sequence_history.append((row, column))
self.sequence_queue.put((row, column))
i+=1
self.show_block.emit(1, row, column)
if self.sleep(0.5):
self.hide_block.emit(0, row, column)
else:
return
self.queue_ready.emit(self.sequence_queue)
def kill_thread_event(self):
self.kill = True
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setMinimumHeight(450)
self.setMinimumWidth(450)
self.setWindowFlags(qtc.Qt.WindowType.FramelessWindowHint)
self.setLayout(qtw.QVBoxLayout())
self.layout().setContentsMargins(0, 0, 0, 0)
self.widget = SequenceMemory()
self.layout().addWidget(self.widget)
self.show()
def closeEvent(self, a0) -> None:
self.widget.close()
return super().closeEvent(a0)
if __name__ == "__main__":
app = qtw.QApplication(sys.argv)
mw = MainWindow()
sys.exit(app.exec())
Above is as minimal as I could get the program to be, without diverging too far away from the program's structure. The full program (in a single file) can be found here.
I'm trying to set blur to the background of a QStackWidget. Main window is set to be transparent and the stack widget is made semi-transparent with style sheet. When I try to blur the stack widget, it blurs everything in it. How do I blur only stack widget background without blurring out the widgets in it?
import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
li = ["item1", "item2"]
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.setAttribute(Qt.WA_TranslucentBackground)
self.resize(500, 400)
self.label = QLabel("Noting to see here")
self.tab1 = QLabel("You can't see me")
self.tab1.setAlignment(Qt.AlignCenter)
self.tab2 = QLabel("Now you can")
self.tab2.setAlignment(Qt.AlignCenter)
self.tab3 = QLabel("Now you don't")
self.tab3.setAlignment(Qt.AlignCenter)
self.tabWidget = QTabWidget()
self.tabWidget.addTab(self.tab1, "t1")
self.tabWidget.addTab(self.tab2, "t2")
self.tabWidget.addTab(self.tab3, "t2")
self.tabWidget.setTabPosition(QTabWidget.West)
self.Blur = QGraphicsBlurEffect()
self.tabWidget.tabBar().setGraphicsEffect(self.Blur)
self.tabWidget.setStyleSheet("QTabWidget{background: none;"
"border: 0px;"
"margin: 0px;"
"padding: 0px;}"
"QTabBar:tab{background: rgba(0, 200, 220, 20);}"
"QTabBar:tab:hover{background: rgba(200, 200, 200, 120);}"
"QTabBar:tab:selected{background: rgb(0, 150, 220);}")
self.sw = QStackedWidget()
self.sw.addWidget(self.label)
self.sw.addWidget(self.tabWidget)
self.sw.setStyleSheet("background: rgba(255, 255, 255, 10);")
if li is None:
self.sw.setCurrentWidget(self.label)
else:
self.sw.setCurrentWidget(self.tabWidget)
self.toolBar = QToolBar()
self.toolBar.setFixedHeight(30)
self.toolBar.setStyleSheet("background: grey;")
self.layout = QVBoxLayout()
self.layout.setSpacing(0)
self.layout.setMargin(0)
self.layout.addWidget(self.toolBar)
self.layout.addWidget(self.sw)
self.setLayout(self.layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
Simply put, I want blur like in the image.
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_())
could someone please answer my questions?
1) I want when I push a button, the color of the button changes permanently until I push it again and it comes back to the original color.
2) how can I change he shape of the button for example to a circle?
#PyQt pushButton setstylesheet
#This is the example code for PyQt pushButton setstylesheet
#If your are not expecting this answer, sorry.
#QPushButton color change while clicking on same QPushButton
#Circle QPushButton
import sys, os
from PyQt4 import QtGui, QtCore
class Window (QtGui.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.pushButton = QtGui.QPushButton(self)
self.pushButton.setObjectName('pushButton')
self.pushButton.setGeometry (QtCore.QRect(20, 10, 250, 50))
self.pushButton.setStyleSheet('background-color: rgb()')
self.pushButton.setText ('Color')
self.pushButton_2 = QtGui.QPushButton(self)
self.pushButton_2.setObjectName('pushButton_2')
self.pushButton_2.setGeometry (QtCore.QRect(20, 70, 150, 150))
self.pushButton_2.setText('Cricle')
#width = 150
#height = width
#border-radius = width/2
#self.pushButton_2.setStyleSheet ('background-color: red;border-style: outset;border-width: 2px;border-radius: 200px;border-color: beige;font: bold 14px;min-width: 10em;padding: 6px;')
self.pushButton_2.setStyleSheet ('background-color: red; border-width: 2px; border-radius: 75px;')
self.resize(300, 240)
self.pushButton.clicked.connect (self.colorChange)
self.pushButton_2.clicked.connect (self.cricle)
self.currentColor = 'default'
def colorChange (self) :
if self.currentColor=='default' :
self.pushButton.setStyleSheet('background-color: red')
self.currentColor = 'red'
else :
self.pushButton.setStyleSheet('background-color: rgb()')
self.currentColor = 'default'
def cricle (self) :
print 'Hai...............'
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
#Thanks,
#Subin Gopi