PyQt application screen change notification - python

I checked some information. C++ has an onScreenChanged function to notify us of screen changes, but I tried it and found that PyQt does not have this onScreenChanged function. How should I know that the application has changed the screen display?

If you want to know if a window has changed screen then you must use the screenChanged signal of the associated QWindow(use windowHandle() method of QWidget). The QWindow is created after calling the show method:
from PyQt5 import QtWidgets
if __name__ == "__main__":
app = QtWidgets.QApplication([])
w = QtWidgets.QMainWindow()
w.show()
w.windowHandle().screenChanged.connect(lambda screen: print("new screen", screen))
w.resize(640, 480)
app.exec_()

Related

Can't Kill PyQT Window after closing it. Which requires me to restart the kernal

I guess that I am not closing my PyQT5 Window correctly. I am using spyder (3.3.5) which I have installed with anaconda, to program a pyqt5 program. I am using qt creator to design my ui file, which I load using the loadUi function in pyqt package. Everything works fine with the code, until I need to close it. I close the window via the close button (the x button in the top right). The window itself is closed, but it seems like the console (or shell) is stuck, and I can't give it further commands or to re run the program, without having to restart the kernel (to completely close my IDE and re opening it).
I have tried looking for solutions to the problem in the internet, but none seems to work for me. Including changing the IPython Console > Graphics to automatic.
Edit: Also Created an issure:
https://github.com/spyder-ide/spyder/issues/9991
import sys
from PyQt5 import QtWidgets,uic
from PyQt5.QtWidgets import QMainWindow
class Mic_Analysis(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.ui=uic.loadUi("qt_test.ui",self)
...
if __name__ == "__main__":
def run_app():
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app=QtWidgets.QApplication.instance()
mainWin=Mic_Analysis()
mainWin.show()
app.exec_()
run_app()
If someone have any suggestion I would be very happy to hear them.
For me, it helped to remove the 'app.exec_()' command.
But then it closes immediatly when running the code. To keep the window open, I needed to return the MainWindow instance to the global scope (or make it a global object). My code looks like this:
from PyQt5 import QtWidgets
import sys
def main():
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
main = MainWindow()
main.show()
return main
if __name__ == '__main__':
m = main()
Try adding :
app.setQuitOnLastWindowClosed(True)
to your main() function
def main():
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(True)
win = MainWindow()
win.show()
sys.exit(app.exec_())
Surprizinglly, for me this works well. No QApplication is needed.
It seems to work in another thread.
from PyQt5 import QtWidgets,uic
class Ui(QtWidgets.QDialog):
def __init__(self):
super().__init__()
uic.loadUi('./test.ui',self)
self.show()
w=Ui()

How to toggle window stays on top hint

I am trying to create a widget that the user should be able to select if it stays on top. Below is a sample code of what I am trying to achieve. Trying to set the Qt.WindowStaysOnTopHint after the widget has been created does not work:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
app = QApplication([])
win = QWidget()
def toggleTop():
win.setWindowFlags(Qt.WindowStaysOnTopHint)
win.show()
button = QPushButton('Top', win)
button.clicked.connect(toggleTop)
win.show()
app.exec_()
However, if I set the flag during widget creation, it works perfectly:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
app = QApplication([])
win = QWidget()
win.setWindowFlags(Qt.WindowStaysOnTopHint)
win.show()
app.exec_()
OS is Ubuntu 18.04.
Your toggleTop function is currently overwriting all the window flags with the same flag every time. To toggle a single window flag, you need to explicitly reset it based on the current state of the flag:
def toggleTop():
# get the current state of the flag
on = bool(win.windowFlags() & Qt.WindowStaysOnTopHint)
# toggle the state of the flag
win.setWindowFlag(Qt.WindowStaysOnTopHint, not on)
win.show()

How to input in console while running Qt Application in python?

I can't input anything from the user in the terminal while running a PyQt Application.
Actually i am creating something but i can't show the whole code here so there is the main of the code, and believe that i need the fix of it only:
from PyQt4.QtGui import *
import sys
def window():
app = QApplication(sys.argv)
window = QWidget()
btn = QPushButton()
btn.setText("Input In Console")
box = QFormLayout()
box.addRow(btn)
btn.clicked.connect(input_txt)
window.setLayout(box)
window.show()
sys.exit(app.exec_())
def input_txt():
input("Enter you Name ")
if __name__ == "__main__":
window()
And while running as i press the button a disaster of loop starts:
I really tried a lot configuring the solution of this problem but all failed. Hope these information helped, if any question regarding the post then please say in comment.
I don't need this anymore but still i am posting answer for if someone else having problem with the same.
Solution : Use Threads
from PyQt4.QtGui import *
import sys,threading
def window():
app = QApplication(sys.argv)
window = QWidget()
btn = QPushButton()
btn.setText("Input In Console")
box = QFormLayout()
box.addRow(btn)
btn.clicked.connect(input_txt)
window.setLayout(box)
window.show()
sys.exit(app.exec_())
def input_txt():
thread = threading.Thread(target=input)
thread.start()
if __name__ == "__main__":
window()

PyQt dialog closes entire app on exit

I have a PyQt wizard that includes a dialog box that asks the user a question. This dialog box is optional and only for use if the user wants it. A button sends a signal that the app receives and opens the window. The problem I have is that when the dialog is closed, it closes the whole app with it. How do I make sure that when the dialog is closed, the main app stays open and running? Here the code that handles the dialog box:
def new_item(self):
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.exec_()
I tried adding a 'Cancel' button to close it manually but the result was the same, the whole app closed.
QtCore.QObject.connect(self.cancel, QtCore.SIGNAL(_fromUtf8("clicked()")), Dialog.close)
You shouldn't create new QApplication objects in your code, and I am not surprised that destroying that object closes the application.
Your code should look 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.dialog = QtGui.QMessageBox(self)
self.dialog.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
self.dialog.setIcon(QtGui.QMessageBox.Question)
self.dialog.setText("Click on a button to continue.")
self.pushButtonQuestion = QtGui.QPushButton(self)
self.pushButtonQuestion.setText("Open a Dialog!")
self.pushButtonQuestion.clicked.connect(self.on_pushButtonQuestion_clicked)
self.layoutHorizontal = QtGui.QHBoxLayout(self)
self.layoutHorizontal.addWidget(self.pushButtonQuestion)
#QtCore.pyqtSlot()
def on_pushButtonQuestion_clicked(self):
result = self.dialog.exec_()
if result == QtGui.QMessageBox.Ok:
print "Dialog was accepted."
elif result == QtGui.QMessageBox.Cancel:
print "Dialog was rejected."
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
Try to use Dialog.reject instead of Dialog.close
.close() method is being used mith QMainWindow Widget, .reject() with QDialog.
In my case, I had QSystemTrayIcon as an "entry point" to my app instead of QMainWindow or QWidget.
Calling .setQuitOnLastWindowClosed(False) on my main QApplication instance helped, thanks to this answer

How to create a new window button PySide/PyQt?

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).

Categories

Resources