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.
Related
I want to create a pyqt5 application of which, I want to track every button click in the qtextbrowser.
To make it simple to see and also to understand, I want to import different qwidgets to a qmainwindow and build the QMainwindow application in the end.
Evary QWidget has their individual buttons, comboboxes and radiobuttons. I want to track all the activities by appending that activity in a QTextBrowser (which I will import to main window).
(If i click a button_A on a QWidget_1, I want to append the info msg as "Button_A has been clicked" on the QTextBrowser)
I can understand the process of doing this, when we work on a single widget application. But I want to create/build/complile different QWidgets and import that all to a QMainWindow Application (WHich will be my full fledged application).
Does anybody know hoe to track it?
import sys
from PyQt5.QtWidgets import *
from PrintWidget import PrinterWidget
from CameraWidget import CameraWidget
from LaserWidget import LaserWidget
from textbrowser import TextDisplay
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
layout_H = QHBoxLayout()
layout = QVBoxLayout()
layout.addLayout(layout_H)
layout_H.addWidget(PrinterWidget(self))
layout_H.addWidget(CameraWidget(self))
layout.addWidget(LaserWidget(self))
self.browser = TextDisplay()
layout_H.addWidget(self.browser)
self.central_widget = QWidget(self)
self.central_widget.setLayout(layout)
self.setCentralWidget(self.central_widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
In the above example, I could able to import the textbrowser as a widget to my mainwindow. But I could not ttrack the activities of individual widgets.
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?
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.
What I want to achieve: if a user clicks outside of the QMainWindow the window should hide.
How I tried to to tackle this problem: find a way to determine if the QMainWindow lost focus, and if so, hide the window using a followup function.
Unfortunately I can not totally grasp how to achieve this.
It can be done using the flag Qt::Popup but than I am not able to give any keyboard input to the widget my QMainWindow contains.
void QApplication::focusChanged(QWidget *old, QWidget *now)
This signal is emitted when the widget that has keyboard focus changed from old to now, i.e., because the user pressed the tab-key, clicked into a widget or changed the active window. Both old and now can be the null-pointer.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MyWin(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setFocus()
QtWidgets.qApp.focusChanged.connect(self.on_focusChanged)
#QtCore.pyqtSlot("QWidget*", "QWidget*")
def on_focusChanged(self, old, now):
if now == None:
print(f"\nwindow is the active window: {self.isActiveWindow()}")
# window lost focus
# do what you want
self.setWindowState(QtCore.Qt.WindowMinimized)
else: print(f"window is the active window: {self.isActiveWindow()}")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = MyWin()
MainWindow.show()
sys.exit(app.exec_())
Disclaimer: New to both python and qt designer
QT Designer 4.8.7
Python 3.4
PyCharm 5.0.3
Question - How do I add controls to the main form or a scroll area widget on the main form (created in QT Designer) programmatically?
I have created a MainWindow in qt designer and added my widgets. The following is the entire test program in PyCharm:
import sys
from PyQt4 import QtGui, QtCore, uic
from PyQt4.QtGui import *
from PyQt4.QtCore import *
qtCreatorFile = "programLauncher.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# Cannot resize or maximize
self.setFixedSize(1045, 770)
# Add button test
self.dateLabel = QtGui.QLabel("Test")
self.pushButton = QtGui.QPushButton('Test button')
# self.scrollArea_programs.addWidget()
grid = QtGui.QGridLayout()
# self.scrollArea_programs.addWidget(self.pushButton)
grid.addWidget(self.dateLabel,0,0)
grid.addWidget(self.pushButton,0,1)
self.setLayout(grid)
self.pushButton_exit.clicked.connect(self.closeEvent)
def closeEvent(self):
QtGui.QApplication.quit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
As you can see I tried to add controls to a grid but nothing shows up when the program runs - I have also tried to add a control to the scroll area. Can someone help me to just add 1 control to the scroll area at run time - so then I can know the proper way to do it or "a" proper way to do this.
Thanks in advance
Without having access to your programLauncher.ui and making minimal changes to your posted code, you can add your UI elements to the window like so:
from PyQt4 import QtGui
import sys
class MyApp(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
# Cannot resize or maximize
self.setFixedSize(1045, 770)
widget = QtGui.QWidget(self)
self.setCentralWidget(widget)
# Add button test
self.dateLabel = QtGui.QLabel("Test")
self.pushButton = QtGui.QPushButton('Test button')
grid = QtGui.QGridLayout()
grid.addWidget(self.dateLabel, 0, 0)
grid.addWidget(self.pushButton, 0, 1)
widget.setLayout(grid)
self.pushButton.clicked.connect(self.closeEvent)
def closeEvent(self, event):
QtGui.QApplication.quit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
This will get the controls on the screen, although the layout leaves a lot to be desired. You may have to make modifications to this based on what's in your .ui file. One thing that you'll want to note in this example is that the QMainWindow needs a central widget (widget in the example above). You then set the layout on that widget.
You can use the designer to create your .ui file
The you can load it in your .py using something like:
from PyQt4 import QtCore, QtGui, uic
class my_win(QtGui.QMainWindow):
def __init__(self):
self.ui = uic.loadUi('my_ui.ui',self)
then you can access all your widgets with something like
self.ui.actionQuit.triggered.connect(QtGui.qApp.quit)
or
self.ui.my_button.triggered.connect(self.do_someting)
Thanks to JCVanHamme (the programLauncher.ui hint) and also outside help I now learned most of what I need to know to access MainWindow at run time. So for anyone interested in this beginner tip:
Take a blank form in QT Designer
Add a control
Run pyuic4 batch file
Take a look at the generated .py file to learn EVERYTHING about how to add controls.
Don't let the power go to your head - cheers