import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
style = self.style()
# Set the window and tray icon to something
icon = style.standardIcon(QtGui.QStyle.SP_MediaSeekForward)
self.tray_icon = QtGui.QSystemTrayIcon()
self.tray_icon.setIcon(QtGui.QIcon(icon))
self.setWindowIcon(QtGui.QIcon(icon))
# Restore the window when the tray icon is double clicked.
self.tray_icon.activated.connect(self.restore_window)
# why this doesn't work?
self.hide()
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.Tool)
def event(self, event):
if (event.type() == QtCore.QEvent.WindowStateChange and
self.isMinimized()):
# The window is already minimized at this point. AFAIK,
# there is no hook stop a minimize event. Instead,
# removing the Qt.Tool flag should remove the window
# from the taskbar.
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.Tool)
self.tray_icon.show()
return True
else:
return super(Example, self).event(event)
def closeEvent(self, event):
reply = QtGui.QMessageBox.question(
self,
'Message',"Are you sure to quit?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
event.accept()
else:
self.tray_icon.show()
self.hide()
event.ignore()
def restore_window(self, reason):
if reason == QtGui.QSystemTrayIcon.DoubleClick:
self.tray_icon.hide()
# self.showNormal will restore the window even if it was
# minimized.
self.showNormal()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I want to make it only show the tray icon on startup, the example is from here:
PyQt4 Minimize to Tray
I added the following to initUI(), but still it shows a blank window on startup. If I minimize the window, it disppears, leaving only the tray icon - but how can I make this happen on startup automatically?
self.hide()
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.Tool)
edit: I tried this code on two different machines with Fedora 13 , and CentOS 7
The solution is to show the tray-icon, but hide the window. Your example works for me on Windows if I make the following changes:
def initUI(self):
...
self.hide()
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.Tool)
# explicitly show the tray-icon
self.tray_icon.show()
def main():
...
ex = Example()
# don't re-show the window!
# ex.show()
sys.exit(app.exec_())
QWidget::hide() should do what you want. The problem is you are calling show() on the new instance which is undoing the call to self.hide() in the constructor.
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show() # Remove this line
sys.exit(app.exec_())
Related
I have Mainwindow and Messagebox. On clicking Ok on messagebox, I want to close the messagebox and hide the mainwindow. Post that I want to launch the Main window based on certain condition. But this line self.msg.exec_() or self.msg.show(), ending the program with Process finished with exit code 0. I don't want to end the Mainwindow, just want to hide it and launch it again.
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
import sys
class Main(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.centralwidget = QWidget(self)
self.Close = QPushButton('Close', self)
self.Close.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
self.Close.setStyleSheet(
'QPushButton {background-color: Gray;}')
self.Close.clicked.connect(lambda: self.popup_close())
vbox = QVBoxLayout()
vbox.addWidget(self.Close)
self.centralwidget.setLayout(vbox)
self.setCentralWidget(self.centralwidget)
self.show()
def popup_close(self):
self.msg = QMessageBox()
self.msg.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.WindowTitleHint)
self.msg.setIcon(QMessageBox.Critical)
self.msg.setText("Warning.")
self.msg.setStandardButtons(QMessageBox.Ok)
if self.msg == QMessageBox.Ok:
self.msg.accept()
self.hide() #hide the main window on closing the warning popup
self.msg.show()
# self.msg.exec_()
#resp = time_api.api_calls.isSubmitted(self)
#if resp['isLocked'] == True and resp['submitted'] == True:
# Main()
class Starter():
def start(self):
app = QApplication(sys.argv)
Main()
sys.exit(app.exec_())
if __name__ == "__main__":
s = Starter()
s.start()
I want to build a window which has no title bar, so i do. But it is not any more draggable. You cannot make my window move from here to there.
I know it is because of me, removing the title bar, but how to fix it?
This is my code:
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QWidget
import sys
def window():
app = QApplication(sys.argv)
win = QMainWindow()
win.setGeometry(300, 300, 300, 300)
win.setWindowTitle("Test")
win.setWindowFlags(QtCore.Qt.FramelessWindowHint)
label = QLabel(win)
label.setText("Hello world")
win.show()
sys.exit(app.exec_())
window()
Any help will be appreciated. Please help me with this...
You need to reimplement the mousePress and mouseMove methods of the widget (mouseRelease is technically not mandatory, but is actually required for consistency, as the release event has to be correctly intercepted by Qt to avoid any confusion). The former will get the current cursor position relative to the geometry (self.offset), while the latter will compute the new "window" position by adding the new position to the current one and subtracting the offset.
I would also suggest you to use a QWidget instead of a QMainWindow. While QMainWindow implementation is very similar to that of QWidgets, subclassing a QMainWindow for your purpose might be a bit harder, as it's widget more complex than it seems.
If you only need a QMainWindow to get a status bar, just add a new one to the widget layout; if you also need a menubar, add it to the widget's layout using setMenuBar.
class FramelessWidget(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Test")
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.label = QLabel("Hello world", self)
self.offset = None
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.offset = event.pos()
else:
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if self.offset is not None and event.buttons() == QtCore.Qt.LeftButton:
self.move(self.pos() + event.pos() - self.offset)
else:
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
self.offset = None
super().mouseReleaseEvent(event)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = FramelessWidget()
win.setGeometry(300, 300, 300, 300)
win.show()
sys.exit(app.exec_())
I'm trying to make a button which would place window on top of others. Using recommends from other questions, I put in my class setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) to set and setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint) to delete flag. It sets the flag, but when i change the button state, it still has that flag enabled. Here is code example:
from PyQt5 import QtWidgets, QtCore
import sys
class widget(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.resize(500, 500)
box = QtWidgets.QVBoxLayout()
self.setLayout(box)
self.btn = QtWidgets.QPushButton("pin")
box.addWidget(self.btn)
self.btn.setCheckable(True)
self.btn.toggled.connect(self.setOnTop)
def setOnTop(self):
if self.btn.isChecked():
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
print("checked")
else:
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
print("unchecked")
self.show()
def main(self):
app = QtWidgets.QApplication(sys.argv)
ex = widget()
ex.show()
sys.exit(app.exec_())
main()
I am trying to add a splashscreen to my PyQt4 GUI application. The code is working fine until I close the application which makes Python crash with "Python.exe has stopped working". Here's the code.
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
#Splashscreen
movie = QMovie("giphy-downsized.gif")
splash = MovieSplashScreen(movie)
splash.show()
start = time.time()
while movie.state() == QMovie.Running and time.time() < start + 10:
app.processEvents()
MainWindow = QtGui.QMainWindow()
splash.finish(MainWindow)
movie.stop()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
splash.close()
sys.exit(app.exec_())
I have tried everything. The application closes perfectly if I DO NOT add splashscreen. However, python crashes after I add splashscreen and close the application. Thus, the problem lies with the objects remaining in memory or something like that but I am not able to solve it yet. Please help.
class MovieSplashScreen(QSplashScreen):
def __init__(self, movie, parent = None):
movie.jumpToFrame(0)
pixmap = QPixmap(movie.frameRect().size())
QSplashScreen.__init__(self, pixmap)
self.movie = movie
self.movie.frameChanged.connect(self.repaint)
def showEvent(self, event):
self.movie.start()
def hideEvent(self, event):
self.movie.stop()
def paintEvent(self, event):
painter = QPainter(self)
pixmap = self.movie.currentPixmap()
self.setMask(pixmap.mask())
painter.drawPixmap(0, 0, pixmap)
def sizeHint(self):
return self.movie.scaledSize()
I'm developing a Qt application and changed the closing behavior with the closeEvent virtual function this way:
class MainWindow(QMainWindow):
def closeEvent(self, event):
event.ignore()
self.hide()
self.trayicon.showMessage('Running', 'Running in the background.')
This works as expected. If I remove event.ignore() the application quits as expected, everything is fine.
I want to control the minimize event too, so when the user clicks the minimize button on the title bar, I want to move the window instead of minimize.
I cannot use the hideEvent virtual function, because the event will be sent to the window anyway, so this code:
def hideEvent(self, event):
event.ignore()
self.move(0,0)
moves the window to the top left AND then minimize it. event.ignore() has no effect here, so I tried using QtCore.QObject.event this way:
def event(self, event):
if event.type() == QEvent.WindowStateChange:
if self.isMinimized():
event.ignore()
self.move(0,0)
return True
return False
The window moves but minimizes again. What is wrong with this ? How can I override the minimize event completely ?
Try the changeEvent and filter for WindowMinimized events, something like this:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtGui, QtCore
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.systemTrayIcon = QtGui.QSystemTrayIcon(self)
self.systemTrayIcon.setIcon(QtGui.QIcon.fromTheme("face-smile"))
self.systemTrayIcon.setVisible(True)
self.systemTrayIcon.activated.connect(self.on_systemTrayIcon_activated)
self.label = QtGui.QLabel(self)
self.label.setText("Minimize me!")
self.layoutVertical = QtGui.QVBoxLayout(self)
self.layoutVertical.addWidget(self.label)
#QtCore.pyqtSlot(QtGui.QSystemTrayIcon.ActivationReason)
def on_systemTrayIcon_activated(self, reason):
if reason == QtGui.QSystemTrayIcon.DoubleClick:
if self.isHidden():
self.show()
else:
self.hide()
def changeEvent(self, event):
if event.type() == QtCore.QEvent.WindowStateChange:
if self.windowState() & QtCore.Qt.WindowMinimized:
event.ignore()
self.close()
return
super(MyWindow, self).changeEvent(event)
def closeEvent(self, event):
event.ignore()
self.hide()
self.systemTrayIcon.showMessage('Running', 'Running in the background.')
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())