PyQT5 menu not visible - qt

When executing this little PyQT5 script, I can't see the menu; it just displays an empty window (no errors or warnings) on ubuntu 14.04.
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow,self).__init__()
self.createUI()
def doAction(self):
print('action')
def createUI(self):
self.setWindowTitle('Test')
menu = self.menuBar().addMenu('File')
action = menu.addAction('Action')
action.triggered.connect(self.doAction)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
window.setGeometry(400, 200, 200, 200)
sys.exit(app.exec_())
Any ideas?

I had the same problem
Try to set native menu bar flag as false like this:
menu.setNativeMenuBar(False)

Related

how to set the QDockWidget Group color?

The picture bellow is a pyside6 application's capture, I move all QDockWidget into a single group, but the group's header's background has two different color. How to change them into a single color(qss or code)? Thanks very much!
Environment:
macos 11.6.5
python 3.9.12
pyside6 6.3.1
Reproduction Code:
# coding: utf-8
import sys
import platform
from PySide6.QtWidgets import QApplication, QMainWindow, QDockWidget, QTextEdit
from PySide6.QtCore import Qt, QSysInfo
def main():
app: QApplication = QApplication(sys.argv)
window = QMainWindow()
dock1 = QDockWidget("dock1")
dock2 = QDockWidget("dock2")
for dock in [dock1, dock2]:
dock.setFeatures(dock.DockWidgetFloatable | dock.DockWidgetMovable)
window.addDockWidget(Qt.LeftDockWidgetArea, dock1)
window.addDockWidget(Qt.RightDockWidgetArea, dock2)
os_info = QTextEdit()
os_info.setText(platform.version())
dock1.setWidget(os_info)
qt_info = QTextEdit()
info = QSysInfo()
qt_info.setText(f"{info.kernelVersion()}, {info.prettyProductName()}, {info.productVersion()}")
dock2.setWidget(qt_info)
window.show()
app.exec()
if __name__ == '__main__':
main()
I have solve it with the signal method myself:
# coding: utf-8
import sys
import platform
from PySide6.QtWidgets import QApplication, QMainWindow, QDockWidget, QTextEdit, QTabBar
from PySide6.QtCore import Qt, QSysInfo
def main():
app: QApplication = QApplication(sys.argv)
window = QMainWindow()
dock1 = QDockWidget("dock1")
dock2 = QDockWidget("dock2")
for dock in [dock1, dock2]:
dock.setFeatures(dock.DockWidgetFloatable | dock.DockWidgetMovable)
window.addDockWidget(Qt.LeftDockWidgetArea, dock1)
window.addDockWidget(Qt.RightDockWidgetArea, dock2)
os_info = QTextEdit()
os_info.setText(platform.version())
dock1.setWidget(os_info)
qt_info = QTextEdit()
info = QSysInfo()
qt_info.setText(f"{info.kernelVersion()}, {info.prettyProductName()}, {info.productVersion()}")
dock2.setWidget(qt_info)
style = """
QTabBar {
background-color: #ff0000;
}
"""
app.setStyleSheet(style)
# force update theme on dock change
for w in window.children():
if isinstance(w, QDockWidget):
w.dockLocationChanged.connect(lambda: app.setStyleSheet(style))
window.show()
app.exec()
if __name__ == '__main__':
main()

PyQt GUI Window NOT showing on VirtualBox Linux Mint

I've installed PyQt4 on my Linux Cinnamon Mint on my VirtualBox Machine (using : sudo apt-get install python-qt4) and tried running this code :
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window.setGeometry(0, 0, 500, 300)
window.setWindowTitle("PyQT Tuts!")
window.show()
It compiles without errors, but I do not see any Window for the show method.
I'm new in this so simple instructions will be appreciated.
Thanks for the read.
In Linux you have to include sys.exit(app.exec_()) below your window.show()
Example:
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window.setGeometry(0, 0, 500, 300)
window.setWindowTitle("whatever")
window.show()
sys.exit(app.exec_())
That's the only problem i can see.
try this
import sys
from PyQt4 import QtGui
def main():
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window.setGeometry(0, 0, 500, 300)
window.setWindowTitle("PyQT Tuts!")
window.show()
if __name__ == '__main__':
main()

Native Qt signal is not callable in PyCharm

I created a QMainWindow with menu and tools :
import sys
from PyQt4 import QtGui
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
Then, I created a quit action by shortcut :
def initUI(self):
exitaction=QtGui.QAction(QtGui.QIcon('exit.png'),'&Exit',self)
exitaction.setShortcut('Ctrl+Q')
exitaction.setStatusTip('EXIT application')
Now : pycharm tells me it can't find reference qApp in __init__.py :
exitaction.triggered().connect(QtGui.qApp.quit)
self.statusBar()
menubar=self.menuBar()
fileMenu=menubar.addMenu('&File')
fileMenu.addAction(exitaction)
self.setGeometry(300,300,250,150)
self.setWindowTitle('Menubar')
self.show()
def main():
app=QtGui.QApplication(sys.argv)
ex=Example()
sys.exit(app.exec_())
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Try to use QApplication istead of QtGui.qapp:
exitaction.triggered().connect(QApplication.instance().quit)
Compare the answer to: calling quit() method of QApplication

Animating a window on startup

I am trying to animate the window in startup but it doesn't seem to work, I have written the code below.
from PyQt4 import QtCore,QtGui
import sys
class AnimatedWindow(QtGui.QMainWindow):
"""docstring for AnimatedWindow"""
def __init__(self):
super(AnimatedWindow, self).__init__()
animation = QtCore.QPropertyAnimation(self, "geometry")
animation.setDuration(10000);
animation.setStartValue(QtCore.QRect(0, 0, 100, 30));
animation.setEndValue(QtCore.QRect(250, 250, 100, 30));
animation.start();
if __name__ == "__main__":
application = QtGui.QApplication(sys.argv)
main = AnimatedWindow()
main.show()
sys.exit(application.exec_())
The problem with this code is, when you create an object of QPropertyAnimation it is destroyed by the python garbage collector after animation.start() statement as animation variable is a local variable, hence the animation does not take place. To overcome this problem you need to make the animation as member variable (self.animation)
Here is the updated code which works fine:
from PyQt4 import QtCore,QtGui
import sys
class AnimatedWindow(QtGui.QMainWindow):
"""docstring for AnimatedWindow"""
def __init__(self):
super(AnimatedWindow, self).__init__()
self.animation = QtCore.QPropertyAnimation(self, "geometry")
self.animation.setDuration(1000);
self.animation.setStartValue(QtCore.QRect(50, 50, 100, 30));
self.animation.setEndValue(QtCore.QRect(250, 250, 500, 530));
self.animation.start();
if __name__ == "__main__":
application = QtGui.QApplication(sys.argv)
main = AnimatedWindow()
main.show()
sys.exit(application.exec_())

catch link clicks in QtWebView and open in default browser

I am opening a page in QtWebView (in PyQt if that matters) and I want to open all links in the system default browser. I.e. a click on a link should not change the site in the QtWebView but it should open it with the default browser. I want to make it impossible to the user to change the site in the QtWebView.
How can I do that?
Thanks,
Albert
That does it:
import sys, webbrowser
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
app = QApplication(sys.argv)
web = QWebView()
web.load(QUrl("http://www.az2000.de/projects/javascript-project/"))
web.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
def linkClicked(url): webbrowser.open(str(url.toString()))
web.connect(web, SIGNAL("linkClicked (const QUrl&)"), linkClicked)
web.show()
sys.exit(app.exec_())
Updated example for PyQt5 (the magic is to re-implement the "acceptNavigationRequest" method):
from PyQt5 import QtWidgets, QtCore, QtGui, QtWebEngineWidgets
class RestrictedQWebEnginePage(QtWebEngineWidgets.QWebEnginePage):
""" Filters links so that users cannot just navigate to any page on the web,
but just to those pages, that are listed in allowed_pages.
This is achieved by re-implementing acceptNavigationRequest.
The latter could also be adapted to accept, e.g. URLs within a domain."""
def __init__(self, parent=None):
super().__init__(parent)
self.allowed_pages = []
def acceptNavigationRequest(self, qurl, navtype, mainframe):
# print("Navigation Request intercepted:", qurl)
if qurl in self.allowed_pages: # open in QWebEngineView
return True
else: # delegate link to default browser
QtGui.QDesktopServices.openUrl(qurl)
return False
class RestrictedWebViewWidget(QtWidgets.QWidget):
"""A QWebEngineView is required to display a QWebEnginePage."""
def __init__(self, parent=None, url=None, html_file=None):
super().__init__(parent)
self.view = QtWebEngineWidgets.QWebEngineView()
self.page = RestrictedQWebEnginePage()
if html_file:
print("Loading File:", html_file)
self.url = QtCore.QUrl.fromLocalFile(html_file)
self.page.allowed_pages.append(self.url)
self.page.load(self.url)
elif url:
print("Loading URL:", url)
self.url = QtCore.QUrl(url)
self.page.allowed_pages.append(self.url)
self.page.load(self.url)
# associate page with view
self.view.setPage(self.page)
# set layout
self.vl = QtWidgets.QVBoxLayout()
self.vl.addWidget(self.view)
self.setLayout(self.vl)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
web = RestrictedWebViewWidget(url="YOUR URL") # or YOUR local HTML file
web.show()
sys.exit(app.exec_())
When you click a link that has the target="_blank" attribute, QT calls the CreateWindow method in QWebEnginePage to create a new tab/new window.
The key is to re-implement this method to, instead of opening a new tab, open a new browser window.
class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
def createWindow(self, _type):
page = WebEnginePage(self)
page.urlChanged.connect(self.open_browser)
return page
def open_browser(self, url):
page = self.sender()
QDesktopServices.openUrl(url)
page.deleteLater()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.url = QUrl("https://stackoverflow.com/")
self.webView = QWebEngineView()
self.page = WebEnginePage(self.webView)
self.webView.setPage(self.page)
self.webView.load(self.url)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
web = MainWindow()
web.show()
sys.exit(app.exec_())

Resources