Форум сайта python.su
Подскажите пожалуйста - нашел в инете код для вывода сообщений в трее, использующий pyqt4, сообщение в трее выводится, но программа при этом не завершается… завершается если выбрать в трее пункт меню quit - выводя :
Traceback (most recent call last):
File "C:\tmp2\testicontrey", line 28, in <module>
sys.exit(app.exec_())
SystemExit: 0
import sys, os
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QApplication
from PyQt4.QtGui import QIcon
from PyQt4.QtGui import QMenu
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QSystemTrayIcon
from PyQt4.QtCore import QString
from PyQt4.QtCore import SLOT
from PyQt4.QtCore import QTimer
if __name__ == "__main__":
app = QApplication(sys.argv)
plik = QString("/usr/share/icons/crystalsvg/16x16/apps/wine.png")
menu = QMenu()
quitAction = menu.addAction('Quit')
sicon = QIcon(plik)
tray = QSystemTrayIcon(sicon)
tray.setContextMenu(menu)
tray.show()
quitAction.connect(quitAction, SIGNAL("triggered()"), app, SLOT("quit()"))
tray.setToolTip("Ale czad!")
def show_message():
tray.showMessage("Title of the message", "Body of the message")
QTimer.singleShot(2000, show_message)
sys.exit(app.exec_())
Офлайн
Причина в том, что QSystemTrayIcon не задан родитель. Возможно связано только с Python'ом.
Фикс:
from PyQt4 import QtCore dummy_parent = QtCore.QObject() # ... tray = QSystemTrayIcon(sicon, parent=dummy_parent)
Офлайн
reclosedev
tray = QSystemTrayIcon(sicon, parent=dummy_parent)
import sys, os
from PyQt4 import QtCore
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QApplication
from PyQt4.QtGui import QIcon
from PyQt4.QtGui import QMenu
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QSystemTrayIcon
from PyQt4.QtCore import QString
from PyQt4.QtCore import SLOT
from PyQt4.QtCore import QTimer
if __name__ == "__main__":
dummy_parent = QtCore.QObject()
app = QApplication(sys.argv)
plik = QString("/usr/share/icons/crystalsvg/16x16/apps/wine.png")
menu = QMenu()
quitAction = menu.addAction('Quit')
sicon = QIcon(plik)
tray = QSystemTrayIcon(sicon, parent=dummy_parent)
tray.setContextMenu(menu)
tray.show()
quitAction.connect(quitAction, SIGNAL("triggered()"), app, SLOT("quit()"))
tray.setToolTip("Ale czad!")
def show_message():
tray.showMessage("Title of the message", "Body of the message")
QTimer.singleShot(2000, show_message)
sys.exit(app.exec_())
Офлайн
Не понимаю что вы хотите? Чтобы программа завершилась, но потом как-то отправляла сообщения?
Или вы о том, что app.exec_() блокирует дальнейшее выполнение?
У меня первый код, до добавления parent, при нажатии на quit вообще вылетал с ошибкой в QtCore. Думал вопрос об этом.
Офлайн
у меня работает,в трее нажав quit завершается
windows7 python2.7.4
Офлайн
reclosedev
Не понимаю что вы хотите? Чтобы программа завершилась, но потом как-то отправляла сообщения?Или вы о том, что app.exec_() блокирует дальнейшее выполнение?У меня первый код, до добавления parent, при нажатии на quit вообще вылетал с ошибкой в QtCore. Думал вопрос об этом.
Отредактировано MarkHammer (Июнь 25, 2013 21:55:58)
Офлайн
Если уже есть GUI приложение, проблем добавить иконку нет, примеров много в сети.
Если правильно понял, у вас не GUI приложение.
Для работы Qt нужен запущенный цикл обработки событий (app.exec_()), но он блокирует все дальнейшие действия. Поэтому работу нужно выполнять в отдельном потоке.
Примитивный пример:
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import time from PyQt4 import QtGui, QtCore class WorkerThread(QtCore.QThread): def __init__(self, tray_icon): QtCore.QThread.__init__(self) self.tray_icon = tray_icon self._need_to_stop = False def run(self): counter = 0 while not self._need_to_stop: print 'Doing work' self.tray_icon.showMessage('Test', 'Test message %s' % counter) counter += 1 time.sleep(1) print 'exiting' QtGui.QApplication.quit() def stop(self): self._need_to_stop = True app = QtGui.QApplication(sys.argv) tray = QtGui.QSystemTrayIcon( QtGui.QIcon(":/trolltech/styles/commonstyle/images/standardbutton-open-128.png") ) worker = WorkerThread(tray) menu = QtGui.QMenu() quit_action = menu.addAction('Quit') quit_action.triggered.connect(worker.stop) tray.setContextMenu(menu) tray.show() worker.start() app.exec_()
QtCore.QTimer.singleShot(0, my_main_loop)
Офлайн
Не получается сделать проверку на изменение в буфере обмена(выводить сообщение только при изменении инфо в буфере)…
скрипт переводит на русский язык
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import time from Tkinter import * import urllib2 import Tkinter from PyQt4 import QtGui, QtCore def translate(to_translate, to_langage="auto", langage="auto"): '''Return the translation using google translate you must shortcut the langage you define (French = fr, English = en, Spanish = es, etc...) if you don't define anything it will detect it or use english by default Example: print(translate("salut tu vas bien?", "en")) hello you alright?''' agents = {'User-Agent':"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)"} before_trans = 'class="t0">' link = "http://translate.google.com/m?hl=%s&sl=%s&q=%s" % (to_langage, langage, to_translate.replace(" ", "+")) request = urllib2.Request(link, headers=agents) page = urllib2.urlopen(request).read() result = page[page.find(before_trans)+len(before_trans):] result = result.split("<")[0] return result tk = Tk() class WorkerThread(QtCore.QThread): def __init__(self, tray_icon): QtCore.QThread.__init__(self) self.tray_icon = tray_icon self._need_to_stop = False def run(self): while not self._need_to_stop: try: #tk.withdraw() cb = tk.selection_get(selection = "CLIPBOARD")# извлечь из буфера обмена to_translate = cb #print("%s >> %s" % (to_translate, translate(to_translate))) tr= ("%s >> %s" % (to_translate, translate(to_translate, 'ru').decode("utf-8"))) #tk.clipboard_clear() #tk.destroy() self.tray_icon.showMessage('Translate', tr) time.sleep(4) except: pass print 'exiting' QtGui.QApplication.quit() def stop(self): self._need_to_stop = True app = QtGui.QApplication(sys.argv) tray = QtGui.QSystemTrayIcon( QtGui.QIcon(":/trolltech/styles/commonstyle/images/standardbutton-open-128.png") ) worker = WorkerThread(tray) menu = QtGui.QMenu() quit_action = menu.addAction('Quit') quit_action.triggered.connect(worker.stop) tray.setContextMenu(menu) tray.show() worker.start() app.exec_()
Отредактировано sanodin (Июнь 26, 2013 20:21:39)
Офлайн
sanodin
Зачем вы смешиваете PyQt и Tkinter?
В PyQt за буфером можно следить: QClipboard.dataChanged
import sys from PyQt4 import QtGui def on_clipboard_changed(): text = app.clipboard().text() # ... tray.showMessage('Title', 'Translate: %s' % text) app = QtGui.QApplication(sys.argv) app.clipboard().dataChanged.connect(on_clipboard_changed) tray = QtGui.QSystemTrayIcon( QtGui.QIcon(":/trolltech/styles/commonstyle/images/standardbutton-open-128.png") ) menu = QtGui.QMenu() quit_action = menu.addAction('Quit') quit_action.triggered.connect(app.quit) tray.setContextMenu(menu) tray.show() app.exec_()
sanodinНаверное.
или надо было новую тему создать?
Офлайн
reclosedevСпасибо
sanodinЗачем вы смешиваете PyQt и Tkinter? В PyQt за буфером можно следить: QClipboard.dataChanged
Офлайн