I'm trying to change the font size of the menu whenever you right click on the plot in PyQtGraph. When I change the font size of the entire application using setStyleSheet, it also changes the font size of the menu.
Before
After
I don't want to individually change the font-size of the button because I have many other widgets in the GUI so I changed the app font-size. But it also changes the font-size of the plot menu. How can I make the font-size of the menu smaller? Either changing the font-size smaller or somehow making the menu larger so the words don't cut off would work.
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
import sys
if __name__ == '__main__':
app = QtGui.QApplication([])
main_window = QtGui.QMainWindow()
widget = QtGui.QWidget()
main_layout = QtGui.QVBoxLayout()
widget.setLayout(main_layout)
main_window.setCentralWidget(widget)
button = QtGui.QPushButton('hello')
plot_widget = pg.PlotWidget()
plot = plot_widget.plot()
layout = QtGui.QHBoxLayout()
layout.addWidget(button)
layout.addWidget(plot_widget)
main_layout.addLayout(layout)
main_window.show()
app.setStyleSheet('QWidget {font-size: 30px}')
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
Considering the MWE that you have provided (1) the solution is to create another rule in QSS to set the font of QMenu and its children widgets:
app.setStyleSheet("""
QWidget {font-size: 30px}
QMenu {font-size: 15px}
QMenu QWidget {font-size: 15px}
""")
(1) For a more complex widget my solution could modify other parts, so there is no general solution but it depends on the widget itself.
Related
How do I create a drop-down widget, such as a drop-down QLabel, drop-down QTextBrowser, etc.?
For example, I log information in a QTextBrowser, but I don't want it taking up space on the screen. So I want to be able to click a QToolbutton and have a scrollable QTextBrowser drop-down. (A QComboBox would work too, but I can't just add each event as a separate item - I need the text to wrap, not be elided. Thus a drop-down QTextBrowser.)
Or, for example, I want a drop-down QLabel containing a picture, etc...
Create a QWidgetAction for the drop-down widget, and add it to the tool-button's menu:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QHBoxLayout(self)
self.button = QtGui.QToolButton(self)
self.button.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.button.setMenu(QtGui.QMenu(self.button))
self.textBox = QtGui.QTextBrowser(self)
action = QtGui.QWidgetAction(self.button)
action.setDefaultWidget(self.textBox)
self.button.menu().addAction(action)
layout.addWidget(self.button)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(100, 60)
window.show()
sys.exit(app.exec_())
Is it possible to make mainWindow completely transparent while other widgets remains visible?
For example:
I want to make app transparent and make everything else visible (like, mainFrame, close button, minimize button)
As #Felipe mentioned you can use
window.setAttribute(QtCore.Qt.WA_TranslucentBackground)
here is a little example:
import sys
from PyQt5 import QtWidgets, QtCore
app = QtWidgets.QApplication(sys.argv)
# create invisble widget
window = QtWidgets.QWidget()
window.setAttribute(QtCore.Qt.WA_TranslucentBackground)
window.setWindowFlags(QtCore.Qt.FramelessWindowHint)
window.setFixedSize(800, 600)
# add visible child widget, when this widget is transparent it will also be invisible
visible_child = QtWidgets.QWidget(window)
visible_child.setStyleSheet('QWidget{background-color: white}')
visible_child.setObjectName('vc')
visible_child.setFixedSize(800, 600)
layout = QtWidgets.QGridLayout()
# add a close button
close_button = QtWidgets.QPushButton()
close_button.setText('close window')
close_button.clicked.connect(lambda: app.exit(0))
layout.addWidget(close_button)
# add a button that makes the visible child widget transparent
change_size_button = QtWidgets.QPushButton()
change_size_button.setText('change size')
change_size_button.clicked.connect(lambda: visible_child.setStyleSheet('QWidget#vc{background-color: transparent}'))
layout.addWidget(change_size_button)
visible_child.setLayout(layout)
window.show()
app.exec()
I am currently developing an application in which i cannot use modal windows (due to some application constraints). However, in some cases i would like to simulate a popup window. To do so i dynamically create a widget that has the centralwidget as parent and i use the move() method to place it where i want.
I would like to know if there is a way to get a widget's dimensions at a given time (considering the mainWindow can be resized at any time) so that i will be able to center the placeholder popup (a simple widget) at the middle of the centralwidget.
Thank you
For getting Qt Widget size:
import sys
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QWidget()
width = mainWindow.frameGeometry().width()
height = mainWindow.frameGeometry().height()
For gettting screen size
import sys
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QWidget()
screenShape = QtGui.QDesktopWidget().screenGeometry()
mainWindow.resize(self.screenShape.width(), self.screenShape.height())
mainWindow.show()
You can use frameGeometry or geometry depending on your needs.
I'm getting this weird result when using QMenuBar I've used this exact code before for the QMenuBar and it worked perfectly. But it doesn't show more than 1 QMenu
This is my code:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
from functools import partial
class MainMenu(QWidget):
def __init__(self, parent = None):
super(MainMenu, self).__init__(parent)
# background = QWidget(self)
lay = QVBoxLayout(self)
lay.setContentsMargins(5, 35, 5, 5)
self.menu()
self.setWindowTitle('Control Panel')
self.setWindowIcon(self.style().standardIcon(getattr(QStyle, 'SP_DialogNoButton')))
self.grid = QGridLayout()
lay.addLayout(self.grid)
self.setLayout(lay)
self.setMinimumSize(400, 320)
def menu(self):
menubar = QMenuBar(self)
viewMenu = menubar.addMenu('View')
viewStatAct = QAction('Dark mode', self, checkable=True)
viewStatAct.setStatusTip('enable/disable Dark mode')
viewMenu.addAction(viewStatAct)
settingsMenu = menubar.addMenu('Configuration')
email = QAction('Set Email', self)
settingsMenu.addAction(email)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainMenu()
main.show()
sys.exit(app.exec_())
Result:
I am aware that I am using QWidget when I should be using QMainWindow But is there a workaround???
(I apologize in advance for the terrible quality of the image, there is no good way to take a picture of a QMenuBar)
The problem is that with a QWidget you are not using the "private" layout that a QMainWindow has, which automatically resizes specific children widgets (including the menubar, the statusbar, the dock widgets, the toolbars and, obviously, the "centralWidget").
Remember that a QMainWindow has its own layout (which can't and shouldn't be changed), because it needs that specific custom layout to lay out the aforementioned widgets. If you want to set a layout for the main window, you'll need to apply it to its centralWidget.
Read carefully how the Main Window Framework behaves; as the documentation reports:
Note: Creating a main window without a central widget is not supported. You must have a central widget even if it is just a placeholder.
In order to work around that when using a basic QWidget, you'll have to manually resize the children widgets accordingly. In your case, you only need to resize the menubar, as long as you have a reference to it:
def menu(self):
self.menubar = QMenuBar(self)
# any other function has to be run against the *self.menubar* object
viewMenu = self.menubar.addMenu('View')
# etcetera...
def resizeEvent(self, event):
# calling the base class resizeEvent function is not usually
# required, but it is for certain widgets (especially item views
# or scroll areas), so just call it anyway, just to be sure, as
# it's a good habit to do that for most widget classes
super(MainMenu, self).resizeEvent(event)
# now that we have a direct reference to the menubar widget, we are
# also able to resize it, allowing all actions to be shown (as long
# as they are within the provided size
self.menubar.resize(self.width(), self.menubar.height())
Note: you can also "find" the menubar by means of self.findChild(QtWidgets.QMenuBar) or using the objectName, but using an instance attribute is usually an easier and better solution.
Set minimum width
self.setMinimumSize(320,240)
I want a combobox with width adjusted to its (longest) content, so I use AdjustToContents. However, at least with my settings and the Oxygen style, I sometimes get a too short box and the contents are clipped. This seems to happen especially with digits:
Note that the 8 at the end is clipped. If I comment out that item, the length looks ok.
Is it a bug? Is there an easy way to fix it maybe with stylesheets or subclassing?
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
class HelloWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle("Test")
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
gridLayout = QHBoxLayout()
centralWidget.setLayout(gridLayout)
label = QLabel("Name")
combobox = QComboBox()
combobox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
combobox.addItem("Short")
combobox.addItem("Longer text")
combobox.addItem("abcdefghijklmnopqr")
combobox.addItem("123456789012345678")
gridLayout.addWidget(label)
gridLayout.addWidget(combobox)
gridLayout.addStretch(1)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = HelloWindow()
mainWin.show()
sys.exit( app.exec_() )
try:
combobox = QComboBox(self)
It seems I found the culprit. I had the "Force fonts DPI" option in KDE fonts settings enabled and set to 96 (while xdpyinfo | grep resolution says 101 dpi). Disabling the option makes it work fine with all styles I have available (Breeze, Oxygen, Windows, Fusion).
Now, is this a KDE bug, a Qt bug or just a limitation?