Python and QsystemTray application - python

I have a code which runs on KDE system very well.
On Unity (Ubuntu 16.04 LTS) this code produces unexpected result.
Result on Unity:
wrong result on Unity
Bus the same code produces good result on KDE system:
Link to a good result
Question: Why the same code does not work on Unity?
And a code:
import sys
from PyQt4 import QtGui
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, icon, parent=None):
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
menu = QtGui.QMenu(parent)
edit = QtGui.QLineEdit(parent)
edit.setText("Tekstas kuris turi būti atsiradęs čia")
hl = QtGui.QVBoxLayout(parent)
hl.addWidget(QtGui.QLabel("Testuojame"))
hl.addWidget(edit)
w = QtGui.QWidget(parent)
w.setLayout(hl)
wa = QtGui.QWidgetAction(parent)
wa.setDefaultWidget(w)
menu.addAction(wa)
exitAction = menu.addAction("Blabla")
exitAction = menu.addAction("Blabla 2")
self.setContextMenu(menu)
def main():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
trayIcon = SystemTrayIcon(QtGui.QIcon("icons/close.png"), w)
trayIcon.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

I see the same behaviour on KDE 5.26.0 (Qt 5.6.1, Ubuntu 16.10), the defaultWidget is not shown in the context menu, only the (empty) iconText of the QWidgetAction is displayed. The way the context menu is shown is ultimately controlled by the tray (which is specific to the used desktop environment).
To get this to work consitently you can show your menu as a popup menu on activation instead of in the context menu. The difference is that it isn't activated on right click but on left click and that it may look different from the native trays context menu.
Your example would then look like this:
import sys
from PyQt4 import QtGui
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, icon, parent=None):
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
self.menu = menu = QtGui.QMenu()
edit = QtGui.QLineEdit()
edit.setText("Tekstas kuris turi būti atsiradęs čia")
w = QtGui.QWidget()
hl = QtGui.QVBoxLayout()
w.setLayout(hl)
hl.addWidget(QtGui.QLabel("Testuojame"))
hl.addWidget(edit)
wa = QtGui.QWidgetAction(menu)
wa.setDefaultWidget(w)
menu.addAction(wa)
exitAction = menu.addAction("Blabla")
exitAction = menu.addAction("Blabla 2")
self.activated.connect(self.showPopupMenu)
def showPopupMenu(self, reason):
if reason == QtGui.QSystemTrayIcon.Trigger:
self.menu.popup(QtGui.QCursor.pos())
def main():
app = QtGui.QApplication(sys.argv)
trayIcon = SystemTrayIcon(QtGui.QIcon("icons/close.png"))
trayIcon.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Related

PyQt5 on MacOs. Custom QMenuBar added to QMainWindow is not clickable

class MenuBarWidget(QMenuBar):
sig_new_file = pyqtSignal()
sig_open_file = pyqtSignal()
sig_save_file = pyqtSignal()
sig_page_setup = pyqtSignal()
sig_print = pyqtSignal()
sig_exit = pyqtSignal()
sig_status_bar = pyqtSignal(bool)
def __init__(self):
super().__init__()
self.init_menu_file()
# self.init_menu_edit()
# self.init_menu_format()
# self.init_menu_view()
# self.init_menu_help()
# self.set_all_text()
def init_menu_file(self):
self.act_new_file = QAction('File', self)
self.act_new_file.setShortcut(QKeySequence('Ctrl+N'))
self.act_new_file.triggered.connect(lambda: self.sig_new_file.emit())
self.act_open_file = QAction('Open', self)
self.act_open_file.setShortcut(QKeySequence('Ctrl+O'))
self.act_new_file.triggered.connect(lambda: self.sig_open_file.emit())
self.act_save_file = QAction('Save', self)
self.act_save_file.setShortcut(QKeySequence('Ctrl+S'))
self.act_save_file.triggered.connect(lambda: self.sig_save_file.emit())
self.act_print = QAction('Print', self)
self.act_print.setShortcut(QKeySequence('Ctrl+P'))
self.act_print.triggered.connect(lambda: self.sig_print.emit())
self.act_quit = QAction('Quit', self)
self.act_quit.setShortcut(QKeySequence('Ctrl+Q'))
self.act_quit.triggered.connect(lambda: self.sig_exit.emit())
self.menu_file = self.addMenu('&File')
self.menu_file.addAction(self.act_new_file)
self.menu_file.addAction(self.act_open_file)
self.menu_file.addAction(self.act_save_file)
self.menu_file.addSeparator()
self.menu_file.addAction(self.act_print)
self.menu_file.addSeparator()
self.menu_file.addAction(self.act_quit)
if __name__ == '__main__':
class Form(QMainWindow):
sig_new_file = pyqtSignal()
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(640, 480)
self.setWindowTitle('MenuBar')
self.menu = MenuBarWidget()
self.setMenuBar(self.menu)
app = QApplication(sys.argv)
form = Form()
form.show()
exit(app.exec_())
I wanted to make a menubar for a window on MacOs 10.15.6 with PyQt 5.15
I used QMenuBar class for custom menubar ,created some submenus under 'File' Menu and added it to QMainWindow
and I can see global menubar is created on the top of display just like the other MacOs.
I tried both
QMenuBar() , QMainWIndow.setMenuBar()
sub_menu = QAction('Someting else..',self)
fileMenu = QMainWindow.menuBar().addMenu('File')
fileMenu.addAction(sub_menu)
However created global menubar is not clickable. I clicked it but it does not show submenus below 'File' Menu.
But This way using 'setNativeMenuBar(False)' below works fine like Windows Applications but I wanna use native MacOs menubar
QMainWindow.menuBar() and QMainWindow.setNativeMenuBar(False)
Here are images.
https://imgur.com/a/Yp6c9YW
# This worked on PyQt5 on macOS Big Sur (ver 11.6)
# it is the result on painful trial and error
# and reading the Qt Docs
def _createMenuBar(self):
menuBar = self.menuBar()
# File menu
fileMenu = menuBar.addMenu("File")
fileMenu.addAction("New")
save = QAction("Save",self)
save.setShortcut("Ctrl+S")
fileMenu.addAction(save)
quit = QAction("\0Quit",self)
quit.setShortcut("Ctrl+Q")
fileMenu.addAction(quit)
# Edit menu
editMenu = menuBar.addMenu("Edit")
editMenu.addAction("Copy")
editMenu.addAction("Paste")
# Help menu
helpMenu=menuBar.addMenu("Help")
helpMenu.addAction(self.helpContentAction)
helpMenu.addAction(self.aboutAction)
This might help
from PyQt5.QtWidgets import QMenuBar
Mainmenu=self.menuBar();# creates a menu bar widget
Filemenu=Mainmenu.addMenu('file');#this adds file to menubar
Editmenu=Mainmenu.addMenu('Edit');#this adds edit to menubar

QFileDialog.getOpenFileName change button text from 'Open' to 'Remove'

I am using QFileDialog.getOpenFileName(self,'Remove File', "path", '*.pdf') to select a file and get the path in order to remove it from my application. The issue is the QFileDialog.getOpenFileName window button says 'Open' when selecting a file which will be confusing to the user.
Is there any way to change the button text from 'Open' to 'Remove'/'Delete'
When using the static method QFileDialog::getOpenFileName() the first thing is to obtain the QFileDialog object and for that we use a QTimer and the findChild() method:
# ...
QtCore.QTimer.singleShot(0, self.on_timeout)
filename, _ = QtWidgets.QFileDialog.getOpenFileName(...,
options=QtWidgets.QFileDialog.DontUseNativeDialog)
def on_timeout(self):
dialog = self.findChild(QtWidgets.QFileDialog)
# ...
Then you can get the text iterating over the buttons until you get the button with the searched text and change it:
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == "&Open":
btn.setText("Remove")
That will work at the beginning but every time you interact with the QTreeView they show, update the text to the default value, so the same logic will have to be applied using the currentChanged signal from the selectionModel() of the QTreeView but for synchronization reasons it is necessary Update the text later using another QTimer.singleShot(), the following code is a workable example:
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Press me")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
#QtCore.pyqtSlot()
def on_clicked(self):
QtCore.QTimer.singleShot(0, self.on_timeout)
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
"Remove File",
"path",
"*.pdf",
options=QtWidgets.QFileDialog.DontUseNativeDialog,
)
def on_timeout(self):
dialog = self.findChild(QtWidgets.QFileDialog)
dialog.findChild(QtWidgets.QTreeView).selectionModel().currentChanged.connect(
lambda: self.change_button_name(dialog)
)
self.change_button_name(dialog)
def change_button_name(self, dialog):
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == self.tr("&Open"):
QtCore.QTimer.singleShot(0, lambda btn=btn: btn.setText("Remove"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
The first step can be avoided if the static method is not used and create the dialog using an instance of QFileDialog:
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Press me")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
#QtCore.pyqtSlot()
def on_clicked(self):
dialog = QtWidgets.QFileDialog(
self,
"Remove File",
"path",
"*.pdf",
supportedSchemes=["file"],
options=QtWidgets.QFileDialog.DontUseNativeDialog,
)
self.change_button_name(dialog)
dialog.findChild(QtWidgets.QTreeView).selectionModel().currentChanged.connect(
lambda: self.change_button_name(dialog)
)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
filename = dialog.selectedUrls()[0]
print(filename)
def change_button_name(self, dialog):
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == self.tr("&Open"):
QtCore.QTimer.singleShot(0, lambda btn=btn: btn.setText("Remove"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
While I appreciate the solution provided by #eyllanesc, I'd like to propose a variation.
Under certain circumstances, the code for that answer might fail, specifically:
the delay that X11 suffers from mapping windows;
the checking of localized button strings;
the selection using the file name edit box;
Considering the above, I propose an alternate solution, based on the points above.
For obvious reasons, the main point remains: the dialog must be non-native.
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class FileDialogTest(QWidget):
def __init__(self):
super().__init__()
layout = QHBoxLayout(self)
self.fileEdit = QLineEdit()
layout.addWidget(self.fileEdit)
self.selectBtn = QToolButton(icon=QIcon.fromTheme('folder'), text='…')
layout.addWidget(self.selectBtn)
self.selectBtn.clicked.connect(self.showSelectDialog)
def checkSelectDialog(self):
dialog = self.findChild(QFileDialog)
if not dialog.isVisible():
# wait for dialog finalization, as testOption might fail
return
# dialog found, stop the timer and delete it
self.sender().stop()
self.sender().deleteLater()
if not dialog.testOption(dialog.DontUseNativeDialog):
# native dialog, we cannot do anything!
return
def updateOpenButton():
selection = tree.selectionModel().selectedIndexes()
if selection and not tree.model().isDir(selection[0]):
# it's a file, change the button text
button.setText('Select my precious file')
tree = dialog.findChild(QTreeView)
button = dialog.findChild(QDialogButtonBox).button(
QDialogButtonBox.Open)
# check for selected files on open
updateOpenButton()
# connect the selection update signal
tree.selectionModel().selectionChanged.connect(
lambda: QTimer.singleShot(0, updateOpenButton))
def showSelectDialog(self):
QTimer(self, interval=10, timeout=self.checkSelectDialog).start()
path, filter = QFileDialog.getOpenFileName(self,
'Select file', '<path_to_file>',
"All Files (*);;Python Files (*.py);; PNG Files (*.png)",
options=QFileDialog.DontUseNativeDialog)
if path:
self.fileEdit.setText(path)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
ex = FileDialogTest()
ex.show()
sys.exit(app.exec())
Obviously, for PyQt6 you'll need to use the proper Enum namespaces (i.e. QFileDialog.Option.DontUseNativeDialog, etc.).

Dynamically change translation of application with a combobox with pyqt

I'm creating a simple window with a combobox to let user choose the text language to be displayed throughout the app
I have created the necessary .qm files, and the text is being updated when I start the aplication. But how can I link this to the options on the combobox, and change the language dinamically from within the mainWindow?
My code:
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
GUI
'''
import sys
import os.path as osp
import os
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow,self).__init__()
# Set MainWindow geometry, use settings of last session. If it's first session,
# use defaulted settings
self.settings = QtCore.QSettings('Paul',QtCore.QSettings.NativeFormat)
self.resize(self.settings.value("size", QtCore.QSize(500, 300)).toSize())
self.move(self.settings.value("pos", QtCore.QPoint(5, 5)).toPoint());
self.initUI()
def closeEvent(self, e):
#Save MainWindow geometry session when closing the window
self.settings.setValue("size",self.size())
self.settings.setValue("pos",self.pos())
e.accept()
def initUI(self):
self.hbox = QtGui.QVBoxLayout(self) # Create Vertival box layout to put the buttons
self.myButtons = QtGui.QPushButton('button',self) #create push button
self.myButtons.setStyleSheet("""QPushButton { background-color: red; font:bold 20px}""")
self.myButtons.setToolTip('Push this button')
self.myButtons.setText(self.tr('yes'))
comboBox=QtGui.QComboBox(self) #create drop down menu
comboBox.addItem('English')
comboBox.addItem('Portugues')
self.hbox.addWidget(comboBox,1,QtCore.Qt.AlignRight) #add drop down menu to box layout
self.hbox.addStretch(3) # set separation between buttons
self.hbox.addWidget(self.myButtons,1,QtCore.Qt.AlignRight) #add button to box layout
self.setWindowTitle('Test2')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
translator = QtCore.QTranslator()
translator.load("~/translations/qt_pt.qm")
app.installTranslator(translator)
app.setWindowIcon(QtGui.QIcon(path))
ex = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Basically I would like to have the combobox do something like this:
self.comboBox.currentIndexChanged.connect(self.combochange)
def combochange(self):
if self.comboBox.currentText()=='Portugues':
translator = QtCore.QTranslator()
translator.load('~/translations/qt_pt.qm')
app.installTranslator(translator) #Obviously this doesn't work
I assume I have to somehow pass an argument from the mainWindow to the main() function and reload everything.
Is this even possible?
Python 2.7, QT 5.9.1, PyQt4 4.12.1 on OSX 10.11.6
EDIT:
I found this post on QT wiki page that does what I want, unfortunately I am not proficient in C, at all. If someone could help me translate this to python I would be greatly appreciated.
Here is a more appropriated way to do it:
#create a new translator and load the desired translation file
translator = QtCore.QTranslator()
translator.load("monAppli_fr.qm")
#install translator to the app
#app is the variable created in (if __name__ == "__main__":) section, make it gloabl
app.installTranslator(translator)
#call retranslateUi on ui, which is defined in the same section as app
#MainWindow : created in the same section
ui.retranslateUi(MainWindow)
That's it, and my if __name__ == '__main__': section looks like :
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Ok, I found a way to do it, I don't know if it is a very "pythonic" solution, but it works
my main() function now looks like this:
if __name__ == '__main__':
lang =1 #default language
i=0
while i>=0:
i=i+1
if lang == 1:
print "i'm english"
if i>1:
app2=None # to erase the previous aplication when we loop between two language choices
app = QtGui.QApplication(sys.argv)
translator = QtCore.QTranslator()
translator.load("~/translations/qt_pt.qm")
app.removeTranslator(translator)
ex = MainWindow(lang)
ex.show()
lang =app.exec_()
elif lang==0:
print "i'm portuguese"
app=None
app2 = QtGui.QApplication(sys.argv)
translator = QtCore.QTranslator()
translator.load("~/translations/qt_pt.qm")
app2.installTranslator(translator)
ex = MainWindow(lang)
ex.show()
lang=app2.exec_()
print "im here"
To now which language my aplication needs to load, following user input in the combobox I defined my "combochange" function like so:
def combochange(self,e):
#print self.comboBox.currentText()
if self.comboBox.currentText()=="Portugues":
MainWindow.lang=0
QtGui.qApp.exit(MainWindow.lang)
else:
MainWindow.lang=1
QtGui.qApp.exit(MainWindow.lang)
"lang" is passed outside my mainWindow, which triggers one application to close and be reopened with a different language.
It doesn't look very elegant, but it works.
The full code is:
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
GUI
'''
import sys
import os.path as osp
import os
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QWidget):
def __init__(self,lang2):
super(MainWindow,self).__init__()
# Set MainWindow geometry, use settings of last session. If it's first session,
# use defaulted settings
self.settings = QtCore.QSettings('Paul',QtCore.QSettings.NativeFormat)
self.resize(self.settings.value("size", QtCore.QSize(500, 300)).toSize())
self.move(self.settings.value("pos", QtCore.QPoint(5, 5)).toPoint());
self.initUI(lang2)
def closeEvent(self, e):
#Save MainWindow geometry session when closing the window
self.settings.setValue("size",self.size())
self.settings.setValue("pos",self.pos())
e.accept()
sys.exit()
def initUI(self,lang2):
self.hbox = QtGui.QVBoxLayout(self) # Create Vertival box layout to put the buttons
self.myButtons = QtGui.QPushButton('button',self) #create push button
self.myButtons.setStyleSheet("""QPushButton { background-color: red; font:bold 20px}""")
self.myButtons.setToolTip('Push this button')
#self.myButtons.setText(QtCore.QString(self.tr('yes')))
self.myButtons.setText(self.tr("yes"))
self.comboBox=QtGui.QComboBox(self) #create drop down menu
if lang2 == 1:
self.comboBox.addItem('English')
self.comboBox.addItem('Portugues')
else:
self.comboBox.addItem('Portugues')
self.comboBox.addItem('English')
self.comboBox.currentIndexChanged.connect(self.combochange)
self.hbox.addWidget(self.comboBox,1,QtCore.Qt.AlignRight) #add drop down menu to box layout
self.hbox.addStretch(3) # set separation between buttons
self.myButtons.clicked.connect(self.buttonClicked) # what should the button do
self.hbox.addWidget(self.myButtons,1,QtCore.Qt.AlignRight) #add button to box layout
self.setWindowTitle('Test2')
def combochange(self,e):
#print self.comboBox.currentText()
if self.comboBox.currentText()=="Portugues":
MainWindow.lang=0
QtGui.qApp.exit(MainWindow.lang)
else:
MainWindow.lang=1
QtGui.qApp.exit(MainWindow.lang)
def buttonClicked(self):
msbox= QtGui.QMessageBox()
choice=msbox.warning(self,'ok',"This button doesn't do anything!!!")
if choice == QtGui.QMessageBox.No:
print('nanan')
else:
print('Bye')
self.settings.setValue("size",self.size());
self.settings.setValue("pos",self.pos());
sys.exit()
if __name__ == '__main__':
lang =1
i=0
while i>=0:
i=i+1
print i
if lang == 1:
print "i'm english"
if i>1:
app2=None
app = QtGui.QApplication(sys.argv)
translator = QtCore.QTranslator()
translator.load("/Users/paulmota/Documents/BlueBerryProject/basefiles/translations/qt_pt.qm")
app.removeTranslator(translator)
ex = MainWindow(lang)
ex.show()
lang =app.exec_()
elif lang==0:
print "i'm portuguese"
app=None
app2 = QtGui.QApplication(sys.argv)
translator = QtCore.QTranslator()
translator.load("/Users/paulmota/Documents/BlueBerryProject/basefiles/translations/qt_pt.qm")
app2.installTranslator(translator)
ex = MainWindow(lang)
ex.show()
lang=app2.exec_()
print "im here"

Return value from PYQt slot of QwebView to main window widget (PYQt python)

i am building a desktop application using PyQt python which has a QwebBrowser. now i am running some function using javascript which is returning a value say abc as per following example.
class QWebView(QWebView):
def contextMenuEvent(self,event):
menu = QMenu()
self.actionShowXpath = menu.addAction("Show Xpath")
QObject.connect(self.actionShowXpath,SIGNAL("triggered()"),self,SLOT("slotshowxpath()"))
menu.exec_(self.mapToGlobal(QPoint(event.x(),event.y())))
#pyqtSlot()
def slotshowxpath(self):
frame.evaluateJavaScript("var abc = function get()");
result = frame.evaluateJavaScript("abc").toString()
**some code code to put result in QLineEdit Widget**
# something like below
# xpath.setText(result)
def window():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
web = QWebView(w)
web.load(QUrl("http://www.indiatimes.com/"))
web.show()
xpath = QtGui.QLineEdit("", w)
sys.exit(app.exec_())
if __name__ == '__main__':
window()
now, i want to put the value of abc in a QLineEdit widget("xpath") present in my application.please give me suggestion that how i can i do this?
I can't work up an example because QtWebkit has been removed from Qt 5.6, but if the problem you are having is because you don't have a reference to your QLineEdit, then pass the QLineEdit to your QWebView class's __init__() function:
def start_app():
app = QtGui.QApplication(sys.argv)
main_window = QtGui.QWidget()
xpathInput = QtGui.QLineEdit(main_window)
web_view = MyWebView(main_window, xpathInput) #<===HERE
web_view.load(QUrl("http://www.indiatimes.com/"))
main_window.show()
sys.exit(app.exec_())
Then in your QWebView class:
class MyWebView(QWebView):
def __init__(self, parent, xpath_widget):
#QWebView.__init__(parent)
QWebView.__init__(self, parent)
#or: super(MyWebView, self).__init__(parent)
self.xpath_widget = xpath_widget
def contextMenuEvent(self,event):
menu = QMenu()
self.actionShowXpath = menu.addAction("Show Xpath")
#QObject.connect(
# self.actionShowXpath,
# SIGNAL("triggered()"),
# self,SLOT("slotshowxpath()")
#)
self.actionShowXpath.triggered.connect(self.show_xpath)
menu.exec_(self.mapToGlobal(QPoint(event.x(),event.y())))
##pyqtSlot()
def show_xpath(self):
frame = ...
frame.evaluateJavaScript("var abc = function get()");
result = frame.evaluateJavaScript("abc").toString()
#some code code to put result in QLineEdit Widget**
self.xpath_widget.setText(result)
But I think a better way to organize your code would be to do something like this:
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.xpathInput = QtGui.QLineEdit(self)
self.web_view = QWebView(self)
self.web_view.load(QUrl("http://www.indiatimes.com/"))
self.menu = QMenu()
self.actionShowXpath = self.menu.addAction("Show Xpath")
#QObject.connect(
# self.actionShowXpath,
# SIGNAL("triggered()"),
# self,SLOT("slotshowxpath()")
#)
self.actionShowXpath.triggered.connect(self.show_xpath)
menu.exec_(self.mapToGlobal(QPoint(event.x(),event.y())))
def show_path(self):
frame = ...
result = frame.evaluateJavaScript("abc").toString()
self.xpathInput.setText(result)
def start_app():
app = QtGui.QApplication(sys.argv)
main_window = MyWindow()
main_window.show()
sys.exit(app.exec_())

PyQt : How to set up a widget hidding an other widget if it's visible?

Let's say I created two QObject in my interface (ui). I would like to connect these two widgets and let them controling each other depending on their visual status. If one is hidden, the other one must be visible. And vice versa.
Can you help me ? :)
Thanks !
Nico
Possible solution: Sublclass widgets and override hideEvent and showEvent:
#!/usr/bin/env python
import sys
from PyQt4 import QtCore, QtGui
class CustomWidget(QtGui.QLabel):
signal_hided = QtCore.pyqtSignal()
signal_shown = QtCore.pyqtSignal()
def hideEvent(self, event):
print 'hideEvent'
super(CustomWidget, self).hideEvent(event)
self.signal_hided.emit()
def showEvent(self, event):
print 'showEvent'
super(CustomWidget, self).showEvent(event)
self.signal_shown.emit()
class MainWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.widget1 = CustomWidget('Widget1')
self.widget2 = CustomWidget('Widget2')
# connect signals, so if one widget is hidden then other is shown
self.widget1.signal_hided.connect(self.widget2.show)
self.widget2.signal_hided.connect(self.widget1.show)
self.widget2.signal_shown.connect(self.widget1.hide)
self.widget1.signal_shown.connect(self.widget2.hide)
# some test code
self.button = QtGui.QPushButton('test')
layout = QtGui.QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.widget1)
layout.addWidget(self.widget2)
self.setLayout(layout)
self.button.clicked.connect(self.do_test)
def do_test(self):
if self.widget1.isHidden():
self.widget1.show()
else:
self.widget2.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
widget = MainWidget()
widget.resize(640, 480)
widget.show()
sys.exit(app.exec_())

Categories

Resources