PyQt4: how to make undercorated window with reserved space - python

I'd like to make a panel-like application using PyQt4 for Linux. for this i need the window i created:
to be undecorated
to have reserved space
to appear on all workspaces
From reading the documentation i've got the idea that i should use QtWindowFlags. But i have no clue as to how to do that. Also i believe there should be a Qt.WindowType hint somewhere telling the WM the window's a "dock" application. I have made this with pygtk following this thread, but here with Qt i don't really know how to handle this. (I need Qt for its ability to theme/skin application more easily.)
Below is the current code i made (nothing extraordinary).
import sys
from PyQt4 import QtGui
class Panel(QtGui.QWidget):
def __init__(self, parent=None): ## should the QtWindowFlag be here?
QtGui.QWidget.__init__(self, parent) ## should the QtWindowFlag be there as well?
self.setWindowTitle('QtPanel')
self.resize(QtGui.QDesktopWidget().screenGeometry().width(), 25)
self.move(0,0)
def main():
app = QtGui.QApplication(sys.argv)
panel = Panel()
panel.show()
sys.exit(app.exec_())
return 0
if __name__ == '__main__':
main()
Can anyone help me with this? Thanks :)

Read about the QWidget.windowFlags property: http://doc.qt.nokia.com/4.7/qwidget.html#windowFlags-prop
Example:
>>> from PyQt4 import QtGui, QtCore
>>> app = QtGui.QApplication([])
>>> win = QtGui.QMainWindow()
>>> win.setWindowFlags(win.windowFlags() | QtCore.Qt.FramelessWindowHint)
>>> win.show()

import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
qbtn = QtGui.QPushButton('Quit', self)
#qbtn.clicked.connect(QtCore.QCoreApplication.instance().quit)
qbtn.clicked.connect(self.test)
qbtn.resize(qbtn.sizeHint())
qbtn.move(50, 50)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Quit button')
self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)
self.show()
def test(self):
print "test"
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

The solution is to use Python-Xlib, and it has been described in an answer on a universal way to reserve screen space on X.

Related

how to close a window in pyqt5 and terminate the program? program gets stuck

I want to create a window in pyqt5 and then close it. For some reason the program does not exit after closing the window. It gets stuck. I have been reading several related posts but none give a clear answer.
I have already tried code such as "self.object.close()", "app.quit()", even "self.object.destroy()", but all work in the same way. The only thing that really closes the window is by clicking the x (close) at the window itself. But this is not the behavior I need. I would like to close the window using my code.
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSlot, pyqtSignal
class window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 480, 300)
self.setWindowTitle('Hello World')
self.setWindowLayout()
def setWindowLayout(self):
self.w = QtWidgets.QWidget(self)
self.layout = QtWidgets.QHBoxLayout()
self.label = QtWidgets.QLabel('Hello World Label')
self.layout.addWidget(self.label)
self.w.setLayout(self.layout)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main_window = window()
main_window.show()
main_window.close()
sys.exit(app.exec_())
Once I close the window using
main_window.close(). I want my program to exit.
I apologize if this was resolved in a different post. I searched the answer and none solves my problem.
Thanks.
It seems to me that it is a bug since according to the docs the application should be closed if there is no top-level window but it seems that it is not verified if the closing of the window is not after the event-loop starts. A workaround is to use QTimer.singleShot(0, ...) to close the window:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 480, 300)
self.setWindowTitle('Hello World')
self.setWindowLayout()
def setWindowLayout(self):
self.w = QtWidgets.QWidget(self)
self.layout = QtWidgets.QHBoxLayout()
self.label = QtWidgets.QLabel('Hello World Label')
self.layout.addWidget(self.label)
self.w.setLayout(self.layout)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main_window = window()
main_window.show()
QtCore.QTimer.singleShot(0, main_window.close) # <---
sys.exit(app.exec_())

Pyside2 second window(QDialog) closes the main one

import sys
from PySide2.QtCore import QFile
from PySide2.QtWidgets import QApplication, QMainWindow
from PySide2.QtUiTools import QUiLoader
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
loader = QUiLoader()
self.ui = loader.load("mainWindow.ui", self)
self.ui.pushButton_call_dialog.clicked.connect(self.call_dialog)
self.ui.close()
self.ui.show()
def call_dialog(self):
loader = QUiLoader()
self.dialog = loader.load("dialog.ui")
self.dialog.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyMainWindow()
window.show
sys.exit(app.exec_())
Hi everyone,
any idea why the second (dialog) window closes the entire application?
Of course, it is not a crash since i'm getting a message saying:
Process finished with exit code 0
Thanks for your help
You could handle your QDialog on a separate class, and then make them interact only, the structure might change a bit, but you can see if it's a viable answer:
import sys
from PySide2.QtWidgets import *
class MyWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
button = QPushButton("Dialog")
button.clicked.connect(self.open_dialog)
self.setCentralWidget(button)
def open_dialog(self):
dialog = MyDialog()
dialog.show()
dialog.exec_()
class MyDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
button = QPushButton("Close")
button.clicked.connect(self.close_dialog)
layout = QHBoxLayout()
layout.addWidget(button)
self.setLayout(layout)
def close_dialog(self):
self.close()
if __name__ == "__main__":
app = QApplication()
m = MyWindow()
m.show()
sys.exit(app.exec_())
Just notice that you should include the setUp step on each class.
Hope it helps.
To put the dialog into a separate class didn't work for either.
Every time the Dialog.close() event was called, it closes the whole application.
What worked for me, was to use hide() instead

Python PySide with Qt Designer

I'm trying to make a PySide application. I've watched some tutorials to try to solve the problem but none worked and i do not have any errors in my code.
Here's the file where i'd do the scripting
main.py
import sys
from PySide import QtGui
from ui import Ui_Form
class Main(QtGui.QMainWindow):
def __init__(self):
super(QtGui.QMainWindow)
self.ui = Ui_Form()
self.ui.setupUi(self)
if __name__ == '__init__':
app = QtGui.QApplication(sys.argv)
wid = QtGui.QWidget()
wid.resize(250, 150)
wid.setWindowTitle('Simple')
wid.show()
sys.exit(app.exec_())
It has to be '__main__'
if __name__ == '__main__':
You have class Main() but you don't use it
wid = Main()
You have to execute super() in correct way
super(Main, self).__init__()
BTW: and you have wrong indentions inside class
Working example - without ui because I don't have it - but it shows window.
from PySide import QtGui
import sys
#from ui import Ui_Form
class Main(QtGui.QMainWindow):
def __init__(self):
super(Main, self).__init__()
#self.ui = Ui_Form()
#self.ui.setupUi(self)
self.resize(250, 150)
self.setWindowTitle('Simple')
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
wid = Main()
sys.exit(app.exec_())
Well i just realized that i never actually ran self.show().
Problem solved

How to show the correct frame with python and pyQt

I'm a beginner in python , and I try to generate the frame with pyQt.
Here is my code , and I have some trouble that can not show a correct frame .
At first I wrote , and it can showed the result that I want.
#!/usr/bin/python
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
widget.resize(250, 150)
widget.setWindowTitle('simple2')
widget.show()
sys.exit(app.exec_())
I changed the wording of object-oriented later , and it can't show a frame which I except.
#!/usr/bin/python
import sys
from PyQt4 import QtGui
class Apple(QtGui.QWidget):
def _int_(self,parent=None):
super().__init__()
self.widget = QtGui.QWidget()
self.resize(250, 150)
self.setWindowTitle('simple2')
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
mywidget = Apple()
mywidget.show()
sys.exit(app.exec_())
Someone knows how do I fix my error ?
You have made a typo in your code
def _int_(self,parent=None):
should be
def __init__(self, parent=None):
Edit your code this way:
#!/usr/bin/python
# -* coding: utf-8 -*-
import sys
from PyQt4 import QtGui
class Apple(QtGui.QMainWindow):
def _init_(self): # if you have no parent you don't need to write parent = None. And yes, there was a typo
super(Apple, self).__init__() # it's a little bit better than super().__init__()
#self.widget = QtGui.QWidget() # you've already init QWidget. This code do nothing
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
mywidget = Apple()
mywidget.setWindowTitle('simple2') # here must be window title
mywidget.resize(250, 150) # and resizing
mywidget.show()
sys.exit(app.exec_())
Now you get what you want

Qt QGraphicsDropShadowEffect is not showing

I am creating a custom widget my_widget inheriting from QWidget.
Here, I have a label to which I would like to apply QGraphicsDropShadowEffect however it does not seem to be working since I don't see any shadows.
My code is in Python and it's:
eff = QGraphicsDropShadowEffect()
self.my_widget_label.setGraphicsEffect(eff)
I tried various alterations to this code to no avail.
After doing a through search on Google, I came across many similar questions without answers.
What might be the cause? How can I get the shadow?
Works for me in C++. I did the following in a QDialog containing a QLabel object named titleLabel. I'm using Qt 4.8.4 on a Windows XP computer.
QGraphicsDropShadowEffect* eff = new QGraphicsDropShadowEffect(this);
eff->setBlurRadius(5);
titleLabel->setGraphicsEffect(eff);
See if this works for you:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class testShadow(QWidget):
def __init__(self, parent=None):
super(testShadow, self).__init__(parent)
self.resize(94, 35)
self.verticalLayout = QVBoxLayout(self)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QLabel(self)
self.label.setText("Text Label")
self.shadow = QGraphicsDropShadowEffect(self)
self.shadow.setBlurRadius(5)
self.label.setGraphicsEffect(self.shadow)
self.verticalLayout.addWidget(self.label)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = testShadow()
main.show()
sys.exit(app.exec_())
I have only every tried to use this (and used it successfully) in QGraphicsScene situations. This works for me, while trying to set it on a normal QWidget actually crashes the entire application:
from PyQt4 import QtGui
class Graphics(QtGui.QWidget):
def __init__(self):
super(Graphics, self).__init__()
layout = QtGui.QVBoxLayout(self)
layout.setMargin(0)
shad = QtGui.QGraphicsDropShadowEffect(self)
shad.setBlurRadius(5)
self.scene = QtGui.QGraphicsScene(self)
self.view = QtGui.QGraphicsView(self)
self.view.setScene(self.scene)
text = self.scene.addText("Drop Shadow!")
text.setGraphicsEffect(shad)
layout.addWidget(self.view)
if __name__ == "__main__":
app = QtGui.QApplication([])
main = Graphics()
main.show()
main.raise_()
app.exec_()

Categories