I wrote a program that create a tray. I want to hide it with below code,but it not work(tray icon is visible). how solve this problem?
from PyQt5 import QtGui, QtWidgets
if __name__ == '__main__':
app = QtWidgets.QApplication([])
sysTray =QtWidgets.QSystemTrayIcon()
sysTray.setIcon(QtGui.QIcon('1.jpg'))
sysTray.hide()
app.exec_()
Just add sysTray.show() before sysTray.hide()
Try it:
import sys
from PyQt5.QtWidgets import QApplication, QMenu, QSystemTrayIcon, qApp, QMessageBox
from PyQt5.QtGui import QIcon
def run_something():
print("Running something...")
if __name__ == '__main__':
app = QApplication(sys.argv)
# Creating menu
menu = QMenu()
checkAction = menu.addAction("Check Now")
checkAction.triggered.connect(run_something)
quitAction = menu.addAction("Quit")
quitAction.triggered.connect(qApp.quit)
# Creating icon
icon = QIcon.fromTheme("system-help", QIcon('avatar.jpg')) # '1.jpg'
# Creating tray
trayIcon = QSystemTrayIcon(icon, app)
trayIcon.setContextMenu(menu)
# Showing tray
trayIcon.show()
trayIcon.setToolTip("unko!")
trayIcon.showMessage("hoge", "moge")
sys.exit(app.exec_())
Related
I'm just migrating my application from PyQt5 to PyQt6. I understand that the Qt module has been removed in Qt6. I have stuff like 'Qt.AlignCenter', 'Qt.ToolButtonTextUnderIcon', 'Qt.LeftToolBarArea', which are no longer working. Is there any alternative for this functionality in Qt6?
The Qt module only exists in PyQt5 (not in Qt5) that allowed access to any class or element of any submodule, for example:
$ python
>>> from PyQt5 import Qt
>>> from PyQt5 import QtWidgets
>>> assert Qt.QWidget == QtWidgets.QWidget
That module is different from the Qt namespace that belongs to the QtCore module, so if you want to access Qt.AlignCenter then you must import Qt from QtCore:
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QLabel
def main():
app = QApplication(sys.argv)
w = QLabel()
w.resize(640, 498)
w.setAlignment(Qt.Alignment.AlignCenter)
w.setText("Qt is awesome!!!")
w.show()
app.exec()
if __name__ == "__main__":
main()
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QApplication, QMainWindow, QStyle, QToolBar
def main():
import sys
app = QApplication(sys.argv)
toolbar = QToolBar()
toolbar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
icon = app.style().standardIcon(QStyle.StandardPixmap.SP_DesktopIcon)
toolbar.addAction(icon, "desktop")
w = QMainWindow()
w.addToolBar(Qt.ToolBarAreas.LeftToolBarArea, toolbar)
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Currently, the AlignCenter and others can be found under AlignmentFlag enum:
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QPushButton, QVBoxLayout
def create_widget():
layout = QVBoxLayout()
button = QPushButton('Cancel')
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(button)
I created a checkbox using PyQT, which normally works using mouse clicks.
I want to know if there is a way with which I can uncheck and check the checkbox using the program itself, and not a mouse click.
Basically I want to check and uncheck the box 10 times in 20 seconds and display it happening.
Here is my code for just the checkbox:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QCheckBox, QWidget
from PyQt5.QtCore import QSize
class ExampleWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(140, 40))
self.setWindowTitle("Checkbox")
self.b = QCheckBox("Yes",self)
self.b.move(20,20)
self.b.resize(320,40)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = ExampleWindow()
mainWin.show()
sys.exit( app.exec_() )
checked : bool
This property holds whether the button is checked
Only checkable buttons can be checked. By default, the button is unchecked.
The QTimer class provides repetitive and single-shot timers.
More ... https://doc.qt.io/qt-5/qtimer.html
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QCheckBox, QWidget
from PyQt5.QtCore import QSize
class ExampleWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(140, 40))
self.setWindowTitle("Checkbox")
self.b = QCheckBox("Yes",self)
self.b.move(20,20)
self.b.resize(320,40)
self.num = 0
self.timer = QtCore.QTimer()
self.timer.setInterval(2000) # msec
self.timer.timeout.connect(self.update_now)
self.timer.start()
def update_now(self):
self.b.setChecked(not self.b.isChecked()) # +++
self.num += 1
if self.num == 10: self.timer.stop()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = ExampleWindow()
mainWin.show()
sys.exit( app.exec_() )
I would like my application to consist only of a pop-up menu that opens immediately as soon as it is run. I attempted this solution but nothing appears when I run it:
#!/usr/bin/env python3
from PyQt5.QtCore import (Qt, QPoint)
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import (QApplication, QMenu, QAction)
def clicked():
print("CLICKED")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
menu = QMenu()
menu.addAction(QAction("&Click me", triggered=clicked))
menu.exec_(QCursor().pos())
sys.exit(app.exec_())
This will display a simple popup window with a single option, that calls the clicked function on click:
from PySide2.QtGui import QCursor
from PySide2.QtWidgets import QApplication, QMenu
def clicked():
print("CLICKED")
if __name__ == '__main__':
app = QApplication()
menu = QMenu()
menu.addAction("Click me", clicked)
menu.exec_(QCursor().pos())
Or if you want to use QAction still, then move its definition outside:
from PySide2.QtGui import QCursor
from PySide2.QtWidgets import QApplication, QMenu, QAction
def clicked():
print("CLICKED")
if __name__ == '__main__':
app = QApplication()
menu = QMenu()
action = QAction("&Click me", triggered=clicked)
menu.addAction(action)
menu.exec_(QCursor().pos())
As pointed out by ekhumoro in the comment below:
Qt does not take ownership of actions added via addAction. You must
keep an explicit reference to them, otherwise they will get
garbage-collected.
Note I am using PySide2, but it shouldn't change anything.
Okay I am not certain how minimalistic you want this Menu to be but this is a more static menu (aka it sticks around) with more than one option in case you are trying to build some kind of Menu driven Windowing platform or just a Menu of commands. Also it being a class allows it to be importable to whatever you might be developing large scale. Further you can expand the menu by adding additional menu items with different actions and lastly it follows basic pyqt programming methodologies
from sys import exit as sysExit
from PyQt5.QtWidgets import QApplication, QAction, QWidget, QHBoxLayout, QMenuBar
class MainMenu(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setMaximumSize(self.minimumSize())
self.Click1Act = QAction("&Click Me 1", triggered=self.Clicked1)
self.Click2Act = QAction("&Click Me 2", triggered=self.Clicked2)
self.SimpleMenu = QMenuBar()
self.ClickMenu = self.SimpleMenu.addMenu('Clickables')
self.ClickMenu.addAction(self.Click1Act)
self.ClickMenu.addSeparator()
self.ClickMenu.addAction(self.Click2Act)
HBox = QHBoxLayout()
HBox.addWidget(self.SimpleMenu)
self.setLayout(HBox)
def Clicked1(self):
print("CLICKED ONE")
def Clicked2(self):
print("CLICKED TWO")
if __name__ == "__main__":
MainThred = QApplication([])
MainGui = MainMenu()
MainGui.show()
sysExit(MainThred.exec_())
I have two separate files, one that creates a system tray icon and context menu, and another a window to take user input.
traywindow.py contains this:
import sys
import os
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import QSize
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(320, 172))
self.setWindowTitle("Set Account")
# Setup username field
self.username_label = QLabel(self)
self.username_label.setText('Username')
self.username_field = QLineEdit(self)
self.username_label.move(45, 20)
self.username_field.move(115, 23)
self.username_field.resize(150, 25)
# Setup OK button
pybutton = QPushButton('OK', self)
pybutton.clicked.connect(self.buttonClicked)
pybutton.resize(100,32)
pybutton.move(110, 128)
def buttonClicked(self):
print('Username: ' + self.username_field.text())
def displayWindow():
app = QtWidgets.QApplication(sys.argv)
preferences_window = MainWindow()
preferences_window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
displayWindow()
Which produces:
trayapp.py contains this:
import os
import sys
import traywindow
from PyQt5 import QtWidgets, QtCore, QtGui
class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
def __init__(self, icon, parent=None):
QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
menu = QtWidgets.QMenu(parent)
prefs_action = menu.addAction('Preferences...')
self.setContextMenu(menu)
prefs_action.triggered.connect(self.setPrefs)
def setPrefs(self):
traywindow.displayWindow()
def main(image):
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
trayIcon = SystemTrayIcon(QtGui.QIcon(image), w)
trayIcon.show()
sys.exit(app.exec_())
if __name__ == '__main__':
icon = 'icon.png'
main(icon)
Which produces:
I want to launch the window from my context menu, so when I click on Preferences... it will open the Set Account window, and when I fill in the field and click on OK, capture that into variables/pass those along as arguments in the trayapp.py file. Currently, my attempt in the code above gives me this when I click on Preferences...:
Traceback (most recent call last):
File "/Users/Username/Downloads/trayapp.py", line 17, in setPrefs
traywindow.displayWindow()
File "/Users/Username/Downloads/traywindow.py", line 36, in displayWindow
sys.exit(app.exec_())
SystemExit: -1
[Finished in 3.0s with exit code -6]
I'm new to PyQt5 and feel like I'm missing something fundamental. From the error I think it's to do with how each file is called at the end to produce its UI, but I haven't found an answer in the docs so far.
You can only have one QApplication and in displayWindow you are creating a second QApplication, instead create a MainWindow and do not call displayWindow.
def setPrefs(self):
self.window = traywindow.MainWindow()
self.window.show()
How to add image/icon with text in a qlistwidget in pyqt4 python? I want to add an icon with text just like a chat system. thanks
I have tried this right now and it works, supposing you have a file named tick.png in the same folder as this script.
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import QApplication, QDialog, QListWidgetItem, QListWidget, QIcon
def main():
app = QtGui.QApplication(sys.argv)
window = QDialog()
list = QListWidget( window )
itm = QListWidgetItem( "Tick" );
itm.setIcon(QIcon(r"tick.png"));
list.addItem(itm);
window.show( )
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The chat-like-icon system may be different from this, but right now I don't see a way to have a QListWidgetItem with multiple smileys and text.
You may think of smileys as a particular case of a QListWidgetItem where the text is blank and only the icon is present.
Another solution is using a read-only QTextEdit as chatboard and have the user typing its text + icon + text (etc.) in a separate editable QTextEdit. Then, when he presses the send button, append everything he typed to the read-only QTextEdit.
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import QApplication, QDialog, QListWidgetItem, QListWidget, QIcon, QTextEdit, QTextDocumentFragment
def main():
app = QtGui.QApplication(sys.argv)
window = QDialog()
list = QListWidget( window )
textEditor = QTextEdit( window );
textEditor.setReadOnly( True )
tick_icon = QTextDocumentFragment.fromHtml(r"<img src='tick.png'>");
textEditor.insertPlainText ( " ValiumKnight writes: " )
textEditor.textCursor().insertFragment(tick_icon);
textEditor.insertPlainText ( " Hello World " )
textEditor.textCursor().insertFragment(tick_icon);
textEditor.textCursor().insertFragment(tick_icon);
textEditor.textCursor().insertFragment(tick_icon);
window.show( )
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Bye!