In the below mentioned example when I click on 'Help' submenu under 'View' menu multiple times its creating multiple windows. Can anyone tell me how to resolve this issue?
import sys
from PySide import Qt Gui
from PySide.QtCore import Qt
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.menu_bar()
def menu_bar(self):
helpAction = QtGui.QAction('&Help', self)
helpAction.setShortcut('Ctrl+H')
helpAction.triggered.connect(self.add_helpWindow)
menu = self.menuBar().addMenu('View')
menu.addAction(helpAction)
def add_helpWindow(self):
window = QtGui.QMainWindow(self)
window.setWindowTitle('New Window')
window.show()
if __name__ == '__main__':
import sys
app=QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(300, 300)
window.show()
sys.exit(app.exec_())
You help window is just a QMainWindow, which is not modal and there are no restrictions on the number that can exist. Hence why if you select the help option multiple times, you get multiple windows.
You likely want to use a QMessageBox which has its modal property set. While there is nothing forcing only one dialog to exist at a time, being modal means that the use can only interact with that window so long as it is open. Example:
from Pyside.QtGui import QMessageBox
def add_helpWindow(self):
help_dialog = QMessageBox.information(self, 'Help', 'Some Help Text Here')
help_dialog.setModal(True)
return help_dialog.exec_()
You can also get a more generic dialog box using QDialog, which is the parent class of QMessageBox.
If that's not the behavior you want, you'll need to manually track whether the user has opened that window before, and then connect a signal that is emitted when the user closes the help window to a slot that reset the existence tracker. Here is an example using a non-modal QDialog:
from Pyside.QtGui import QDialog
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.menu_bar()
self.help_open = False # Tracks if the help dialog is already open
def help_closed(self):
self.help_open = False
...
def add_helpWindow(self):
if not self.help_open:
self.help_open = True
help_dialog = QDialog(self)
# Any other setup code here
help_dialog.setModal(False)
help_dialog.accepted.connect(self.help_closed)
help_dialog.rejected.connect(self.help_closed)
help_dialog.show()
Related
I want to create a pyqt5 application of which, I want to track every button click in the qtextbrowser.
To make it simple to see and also to understand, I want to import different qwidgets to a qmainwindow and build the QMainwindow application in the end.
Evary QWidget has their individual buttons, comboboxes and radiobuttons. I want to track all the activities by appending that activity in a QTextBrowser (which I will import to main window).
(If i click a button_A on a QWidget_1, I want to append the info msg as "Button_A has been clicked" on the QTextBrowser)
I can understand the process of doing this, when we work on a single widget application. But I want to create/build/complile different QWidgets and import that all to a QMainWindow Application (WHich will be my full fledged application).
Does anybody know hoe to track it?
import sys
from PyQt5.QtWidgets import *
from PrintWidget import PrinterWidget
from CameraWidget import CameraWidget
from LaserWidget import LaserWidget
from textbrowser import TextDisplay
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
layout_H = QHBoxLayout()
layout = QVBoxLayout()
layout.addLayout(layout_H)
layout_H.addWidget(PrinterWidget(self))
layout_H.addWidget(CameraWidget(self))
layout.addWidget(LaserWidget(self))
self.browser = TextDisplay()
layout_H.addWidget(self.browser)
self.central_widget = QWidget(self)
self.central_widget.setLayout(layout)
self.setCentralWidget(self.central_widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
In the above example, I could able to import the textbrowser as a widget to my mainwindow. But I could not ttrack the activities of individual widgets.
Okay... This has been bugging me for hours. I have a qtmainwindow with a menubar. I've managed to connect an action in tje menubar to an independent Qwidget. But as soon as the Qwidget appears it disappears. I'm using the latest version of pyqt.
Here's the code:
Import sys
from PyQt4 import QtGui, QtCore
Class Main(QtGui.QtMainWindow) :
def __init__(self) :
QtGui.QtMainWindow.__init__(self)
self.setGeometry(300,300,240,320)
self.show()
menubar = self. menuBar()
filemenu = menubar. addMenu('&File')
new = QtGui.QAction(QtGui.QIcon('new.png'), 'New', self)
new.triggered.connect(self.pop)
filemenu.addAction(new)
def pop(self) :
pop = Pop()
class Pop(QtGui.QWidget) :
def __init__(self) :
QtGui.QWidget.__init__(self)
self.setGeometry(300,300,240,320>
self.setWindowTitle('Pop up')
self.show()
Update the pop(self) method as:
def pop(self):
self.window = Pop()
you need to store object of newly created window in a member variable, other wise as soon as the method finishes with the execution, local variables will be destroyed by the Python Garbage Collector.
if you implement this code, you will see the window gets created and disappears immediately.
import sys
from PyQt5 import QtGui, QtWidgets,QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setGeometry(50,50,500,500)
window.setWindowTitle("GUI window")
window.show()
To solve that problem write "sys.exit(app.exec_())" after window.show() and the window will stay on the screen.
I need to control my GUI with shortcuts, so I created some actions to assign the shortcuts. However, I have to put the actions in a menu (so they are visible) to enable them. And some of this action are very basic, like change tab, and don't deserve to appear in a menu.
Is there a way to hide them without disabling them ?
self.changeTabAction.setVisible(False)
This line hides the action, but disables it.
Just add it to your widget with addAction. It will be added to your widget but it wont be visible. Here is an example:
import sys
from PySide import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
action = QtGui.QAction(self)
action.setShortcut('Ctrl+t')
action.triggered.connect(self.on_triggered)
self.addAction(action)
def on_triggered(self):
print('triggered')
app = QtGui.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
I'm having problems with a "New Window" function in PyQt4/PySide with Python 2.7. I connected a initNewWindow() function, to create a new window, to an action and put it in a menu bar. Once a common function in desktop software. Instead of giving me a new persistent window alongside the other one the new window pops up and closes. The code I'm working on is proprietary so I created an example that does the same thing with the same error below. Is there any way to get this to work? Runs in PySide with Python 2.7. It was written in and tested in Windows.
from PySide.QtCore import QSize
from PySide.QtGui import QAction
from PySide.QtGui import QApplication
from PySide.QtGui import QLabel
from PySide.QtGui import QMainWindow
from PySide.QtGui import QMenuBar
from PySide.QtGui import QMenu
from sys import argv
def main():
application = QApplication(argv)
window = QMainWindow()
window.setWindowTitle('New Window Test')
menu = QMenuBar(window)
view = QMenu('View')
new_window = QAction('New Window', view)
new_window.triggered.connect(initNewWindow)
view.addAction(new_window)
menu.addMenu(view)
label = QLabel()
label.setMinimumSize(QSize(300,300))
window.setMenuBar(menu)
window.setCentralWidget(label)
window.show()
application.exec_()
def initNewWindow():
window = QMainWindow()
window.setWindowTitle('New Window')
window.show()
if __name__ == '__main__':
main()
If a function creates a PyQt object that the application needs to continue using, you will have to ensure that a reference to it is kept somehow. Otherwise, it could be deleted by the Python garbage collector immediately after the function returns.
So either give the object a parent, or keep it as an attribute of some other object. (In principle, the object could also be made a global variable, but that is usually considered bad practice).
Here's a revised version of your example script that demonstrates how to fix your problem:
from PySide import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
menu = self.menuBar().addMenu(self.tr('View'))
action = menu.addAction(self.tr('New Window'))
action.triggered.connect(self.handleNewWindow)
def handleNewWindow(self):
window = QtGui.QMainWindow(self)
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.setWindowTitle(self.tr('New Window'))
window.show()
# or, alternatively
# self.window = QtGui.QMainWindow()
# self.window.setWindowTitle(self.tr('New Window'))
# self.window.show()
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(300, 300)
window.show()
sys.exit(app.exec_())
When initNewWindow() returns, the window variable is deleted and the window's reference count drops to zero, causing the newly created C++ object to be deleted. This is why your window closes immediately.
If you want to keep it open, make sure to keep a reference around. The easiest way to do this is to make your new window a child of the calling window, and set its WA_DeleteOnClose widget attribute (see Qt::WidgetAttribute).
I'm a beginner in PyQt. I was trying to create a simple app to try some of the toolkit's many features. My question is, how can I hide the app icon from the taskbar?
I don't want the user to be able to see the icon in taskbar and to minimize it using this icon. Is there any window flags that I can use to achieve this?
This should do the trick:
myApp.setWindowFlags(QtCore.Qt.Tool)
This drove me nuts for days. Complete app code to implement below.
Key bits:
override closeEvent(), enabling it to do either of just hiding window
or true exit
create some facility for user to choose either hide or
exit behavior
don't show() main window on instantiation, just exec_() the App
import sys
from PyQt4.QtGui import QAction, QApplication, QFrame, QIcon, \
QMainWindow, QMenu, QSystemTrayIcon
from PyQt4.QtCore import SIGNAL
class MyApp(QMainWindow):
def __init__(self, parent, title):
super(QMainWindow, self).__init__(parent)
self.exitOnClose = False
exit = QAction(QIcon(), "Exit", self)
self.connect(exit, SIGNAL("triggered()"), self.exitEvent)
self.trayIcon = QSystemTrayIcon(QIcon(), self)
menu = QMenu(self)
menu.addAction(exit)
self.trayIcon.setContextMenu(menu)
self.connect(self.trayIcon, \
SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), \
self.trayIconActivated)
self.trayIcon.show()
self.trayIcon.showMessage("MyApp is running!", "Click to open window\nRight click for menu" )
def trayIconActivated(self, reason):
if reason == QSystemTrayIcon.Context:
self.trayIcon.contextMenu().show()
elif reason == QSystemTrayIcon.Trigger:
self.show()
self.raise_()
def closeEvent(self, event):
if self.exitOnClose:
self.trayIcon.hide()
del self.trayIcon
event.accept()
else:
self.hide()
event.setAccepted(True)
event.ignore()
def exitEvent(self):
self.exitOnClose = True
self.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
myapp = MyApp(None, "My System Tray App")
app.exec_()
Adapted from this thread:
import sys
from PyQt4.QtGui import *
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = QWidget()
mainWindow = QMainWindow(widget)
mainWindow.show()
sys.exit(app.exec_())
I wouldn't recommend trying to hide an application's taskbar presence, especially if the application is visible. If you are only trying to prevent minimizing from the taskbar then you can achieve this by creating your top level widget with the following window flags like this:
QWidget *mainWindow = new QWidget(0, Qt::CustomizeWindowHint
| Qt::WindowTitleHint | Qt::WindowSystemMenuHint
| Qt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint);
If you don't want a maximize flag, you can leave that one out of the list too.
The various window flags that Qt can use are documented here (Qt::WindowFlags).
If you are on Ubuntu with Unity and want to hide an application's icon from the launcher on the left-hand-side, you will probably need Qt.SplashScreen. This worked for me but I don't remember if I also needed Qt.Tool, which is enough on Windows. For the SplashScreen attempt you may have to reimplement the resize functionality as it disables this feature of a QStatusBar (that has a SizeGrip) for example.
Here is a little example to try out window flags.
Just initialise your main window like this self.setWindowFlags(Qt.ToolTip)