PyQt5 can't delete flag WindowStaysOnTopHint under Ubuntu 18.04 - python

I'm trying to make a button which would place window on top of others. Using recommends from other questions, I put in my class setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) to set and setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint) to delete flag. It sets the flag, but when i change the button state, it still has that flag enabled. Here is code example:
from PyQt5 import QtWidgets, QtCore
import sys
class widget(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.resize(500, 500)
box = QtWidgets.QVBoxLayout()
self.setLayout(box)
self.btn = QtWidgets.QPushButton("pin")
box.addWidget(self.btn)
self.btn.setCheckable(True)
self.btn.toggled.connect(self.setOnTop)
def setOnTop(self):
if self.btn.isChecked():
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
print("checked")
else:
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
print("unchecked")
self.show()
def main(self):
app = QtWidgets.QApplication(sys.argv)
ex = widget()
ex.show()
sys.exit(app.exec_())
main()

Related

I can't get window to resize when I hide a widget

I found some code on here that shows an example of how you can get the window to resize when the widget is hidden, and it works for me. Here is the code:
from PyQt4 import QtCore, QtGui
import sys
class MainWindow(QtGui.QWidget):
def __init__(self):
self.app = QtGui.QApplication(sys.argv)
super(MainWindow, self).__init__()
self.button = QtGui.QPushButton('Show/Hide')
self.button.setCheckable(True)
self.frame = QtGui.QFrame()
self.frame.setFixedHeight(100)
self.layout = layout = QtGui.QVBoxLayout()
layout2 = QtGui.QVBoxLayout()
self.setLayout(layout)
self.frame.setLayout(layout2)
layout.addWidget(self.button)
layout.addWidget(self.frame)
layout.addStretch(1)
layout2.addWidget(QtGui.QLabel('Yoyoyo'))
self.button.toggled.connect(self.clickAction)
def startup(self):
self.show()
sys.exit(self.app.exec_())
def clickAction(self):
checked = self.button.isChecked()
if checked:
self.frame.show()
else:
self.frame.hide()
QtCore.QTimer.singleShot(0, self.resizeMe)
def resizeMe(self):
self.resize(self.minimumSizeHint())
if __name__ == "__main__":
myApp = MainWindow()
myApp.startup()
I then tried to modify this to match my existing code by separating the mainWindow class and the widget class. Here is the code that does that.
from PySide import QtGui,QtCore
import sys
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.w = testW(self)
self.setCentralWidget(self.w)
self.show()
class testW(QtGui.QWidget):
def __init__(self,parent):
super(testW,self).__init__()
self.parent = parent
self.button = QtGui.QPushButton('Show/Hide')
self.button.setCheckable(True)
self.button.setChecked(True);
self.frame = QtGui.QFrame()
self.frame.setFixedHeight(100)
self.layout = layout = QtGui.QVBoxLayout()
layout2 = QtGui.QVBoxLayout()
self.setLayout(layout)
self.frame.setLayout(layout2)
layout.addWidget(self.button)
layout.addWidget(self.frame)
layout.addStretch(1)
layout2.addWidget(QtGui.QLabel('Yoyoyo'))
self.button.toggled.connect(self.clickAction)
def clickAction(self):
checked = self.button.isChecked()
if checked:
self.frame.show()
else:
self.frame.hide()
QtCore.QTimer.singleShot(0, self.resizeMe)
def resizeMe(self):
self.resize(self.minimumSizeHint())
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myApp = MainWindow()
sys.exit(app.exec_())
#time.sleep(1)
Running the first code does what I want it to. After I hide the widget, the window resizes to the correct size. The second implementation of the code does not shrink and expand the window when I hide and show the widget. Is this because the MainWindow is in a separate class?
Use size policies for your widgets. For your example you can change UI creation code as follows:
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.w = testW(self)
self.w.setSizePolicy(
QtWidgets.QSizePolicy.MinimumExpanding,
QtWidgets.QSizePolicy.MinimumExpanding
)
self.setCentralWidget(self.w)
self.show()
Please note new setSizePolicy call which say Qt layout engine how to change the size of your widget according to its content.
Unfortunately QMainWindow does not respect sizeHint automatically, but it is calculated properly, so you can adjustSize manually:
def clickAction(self):
checked = self.button.isChecked()
if checked:
self.frame.show()
else:
self.frame.hide()
QtCore.QTimer.singleShot(0, self.parent.adjustSize)
You do not need to resize your widget itself, because it will be resized according to the policy. Even sizeHint will be calculated automatically so you need only to call adjustSize of QMainWindow.
PS: I used PySide2 instead of PySide so the imports are different a little bit:
from PySide2 import QtWidgets, QtCore

PyQt 5 call a function without clicking in python

Hi guys im new in python and PyQt already im using PyQt 5 lib and already faced with really primary problem.
I want to call print function (or any other functions like this) with just cursor moving no clicking on that.
some thing like tooltips that not needed to click on any button.
Thank you for your help.
There are several ways to implement:
1. customized button.
from PyQt5 import QtCore, QtWidgets
class HoverButton(QtWidgets.QPushButton):
hovered = QtCore.pyqtSignal()
def enterEvent(self, event):
self.hovered.emit()
super(HoverButton, self).enterEvent(event)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
btn = HoverButton("Press me")
btn.hovered.connect(self.onHovered)
lay.addWidget(btn)
lay.addWidget(QtWidgets.QLineEdit())
def onHovered(self):
print("hovered")
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
2. eventFilter
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
self.btn = QtWidgets.QPushButton("Press me")
self.btn.installEventFilter(self)
lay.addWidget(self.btn)
lay.addWidget(QtWidgets.QLineEdit())
def eventFilter(self, obj, event):
if obj == self.btn and event.type() == QtCore.QEvent.HoverEnter:
self.onHovered()
return super(Widget, self).eventFilter(obj, event)
def onHovered(self):
print("hovered")
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

shortcut doesn't work in PyQt5 in tray dropdown menu

I was trying to set a shortcut for dropdown menu. The code is below
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QAction
class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
def __init__(self, icon, parent=None):
super(SystemTrayIcon, self).__init__(icon, parent)
menu = QtWidgets.QMenu(parent)
# add actions and shortcuts for them.
exitAction = QAction('Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.triggered.connect(parent.close)
menu.addAction(exitAction)
restoreAction = QAction('Restore', self)
restoreAction.setShortcut("Ctrl+R")
restoreAction.triggered.connect(self.restore)
menu.addAction(restoreAction)
self.setContextMenu(menu)
def restore(self):
print 'restore'
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Icon')
self.tray_icon = SystemTrayIcon(QtGui.QIcon('/opt/WizNote/wiznote.png'), self)
self.tray_icon.show()
self.show()
if __name__ == '__main__':
app = QtWidgets.QApplication([])
w = MainWindow()
sys.exit(app.exec_())
The shortcut doesn't work. Is there something wrong with my code?
Python2.7 and PyQt5 was installed in my laptop.
I had exactly the same problem as yours, and I solved it by respecting the following pattern for each action:
menu.addAction(exitAction)
parent.addAction(exitAction) # line to be added

Not able to display Qlabel on PyQt4

Hi i have posted the code below through which i'm unable to display label in pyqt4. Any suggestions would be helpful .
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys
class Entry_view(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(25, 25, 800, 480)
label = QtGui.QLabel()
label.setText("Welcome To Python GUI")
label.resize(100, 50)
# label.show(self)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = Entry_view()
sys.exit(app.exec_())
You did not keep a reference to the label, so it got garbage-collected before it could be shown. Try this instead:
self.label = QtGui.QLabel(self)
self.label.setText("Welcome To Python GUI")
self.label.resize(100, 50)
Why did you set the text but don't process the app using thus:
app.processEvents() # On the QApplication.
Or just do:
label = QtGui.QLabel(text="Welcome to Python GUI!")
Or:
label = QtGui.QLabel("Welcomme To Python GUI!")
Or another way is:
label.show() # No widgets on it.
code below is the solution ,
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys
class Entry_view(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(25, 25, 800, 480)
label = QtGui.QLabel()
label.setText("Swipe The Card")
vbox = QtGui.QVBoxLayout()
label.setAlignment(Qt.AlignCenter)
vbox.addWidget(label)
vbox.addStretch()
self.setLayout(vbox)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = Entry_view()
sys.exit(app.exec_())

toggle QMainWindow WindowStaysOnTopHint flag pyside

Why, when I toggle the QMainWindow's SetWindowFlags to WindowStaysOnTopHint, does my window disappear, and more importantly not stay on top? I'm using PySide and a QMainWindow.
import sys
from PySide import QtGui, QtCore
class Browser(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Browser, self).__init__(parent)
self.resize(200, 150)
self.setWindowTitle('Assets')
self.initUI()
def initUI(self):
self.mi_stay_on_top = QtGui.QAction('Stay On Top', self)
self.mi_stay_on_top.setShortcut('Ctrl+T')
self.mi_stay_on_top.setCheckable(True)
self.mi_stay_on_top.triggered.connect(self.toggle_stay_on_top)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(self.mi_stay_on_top)
grid = QtGui.QVBoxLayout()
grid.setContentsMargins(10,10,10,10)
self.setLayout(grid)
def toggle_stay_on_top(self):
if self.mi_stay_on_top.isChecked():
# enabled
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
else:
# disable
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
def main():
app = QtGui.QApplication(sys.argv)
ex = Browser()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The setWindowFlags method resets the parent, which hides the window.
So you need to do this:
def toggle_stay_on_top(self):
if self.mi_stay_on_top.isChecked():
# enabled
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
else:
# disable
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
# re-show the window after changing flags
self.show()

Categories