Put a QToolBar in a QWidget instead of QMainWindow - python

I am trying to put a QToolBar on a layout of a QWidget instead of QMainWindow. On QMainWindow and QWidget is working fine, but when i try to add it on a layout first, is not. Am I doing something wrong? Is it possible? Here is my code:
from PyQt4 import QtGui, QtCore
import sys
img = '../../Images/logo.png'
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWin = QtGui.QMainWindow()
widget = QtGui.QWidget()
hLayout = QtGui.QHBoxLayout()
'''ToolBar On main Window '''
basicToolBar = mainWin.addToolBar('Basic')
basicToolBar.addAction(QtGui.QAction('Test', mainWin))
# basicToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), 'Test', mainWin))
# mainWin.show()
'''ToolBar On Widget '''
# Case 1: Set widget as parent
# widgetToolBar = QtGui.QToolBar(widget)
# widgetToolBar.addAction(QtGui.QAction('Test', widget))
# widgetToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), QtGui.QAction('Test', widget))
# Case 2: Set toolBat on a layout
widgetToolBar = QtGui.QToolBar()
widgetToolBar.addAction(QtGui.QAction('Test', None))
# widgetToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), 'Test', None))
hLayout.addWidget(widgetToolBar)
widget.setLayout(hLayout)
widget.show()
# Run
sys.exit(app.exec_())

QToolBar can only be in a QMainWindow since the QMainWindow has a special layout.
So you can use a secondary QMainWindow without problems as I show below:
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.tabwidget = QtGui.QTabWidget()
self.setCentralWidget(self.tabwidget)
for name in ("tab1", "tab2", "tab3"):
self.create_widgets(name)
def create_widgets(self, name):
w = QtGui.QMainWindow()
self.tabwidget.addTab(w, name)
basicToolBar = w.addToolBar('Basic')
basicToolBar.addAction('Test')
basicToolBar.addAction(QtGui.QIcon("home.png"), 'Test')
tab = QtGui.QTabWidget()
w.setCentralWidget(tab)
for i in range(10):
tab.addTab(QtGui.QWidget(), "tab-{}".format(i))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Hmmm have you read the description of QToolBar? http://doc.qt.io/qt-5/qtoolbar.html#details
I think it won't work like this if your Object isn't a child of QMainWindow. The documentation says:
When a QToolBar is not a child of a QMainWindow, it loses the ability to populate the extension pop up with widgets added to the toolbar using addWidget(). Please use widget actions created by inheriting QWidgetAction and implementing QWidgetAction::createWidget() instead.

Related

PyQT layouts: why does QVBoxLayout stack the buttons instead of creating the layout? [duplicate]

I'm making an application in PyQt4 and this is my code so far:
import sys
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUi()
def initUi(self):
self.setWindowTitle('Main Menu')
self.setFixedSize(1200, 625)
self.firstWidgets()
self.show()
def firstWidgets(self):
self.vbox1 = QtGui.QVBoxLayout()
self.task1 = QtGui.QLabel('Check 1', self)
self.task1CB = QtGui.QCheckBox(self)
self.hbox1 = QtGui.QHBoxLayout()
self.hbox1.addWidget(self.task1)
self.hbox1.addWidget(self.task1CB)
self.vbox1.addLayout(self.hbox1)
self.setLayout(self.vbox1)
def main():
application = QtGui.QApplication(sys.argv)
gui = MainWindow()
sys.exit(application.exec_())
if __name__=='__main__':
main()
My problem is in MainWindow.firstWidgets(). I try to set a layout but I get an error even though that's my first time using .setLayout for that form, which confuses me.
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "",
which already has a layout
You can't set a QLayout directly on the QMainWindow. You need to create a QWidget and set it as the central widget on the QMainWindow and assign the QLayout to that.
wid = QtGui.QWidget(self)
self.setCentralWidget(wid)
layout = QtGui.QVBoxLayout()
wid.setLayout(layout)
NOTE: This is for Qt4 -- see the other answer on this question for the Qt5 updated code.
Just an update to Brenden Abel's answer:
QWidget and QVBoxLayout (for Python3, PyQt5) are now contained in the PyQt5.QtWidgets module and not the PyQt5.QtGui module.
So updated code:
wid = QtWidgets.QWidget(self)
self.setCentralWidget(wid)
layout = QtWidgets.QVBoxLayout()
wid.setLayout(layout)
This is an example using PyQt5
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('My App')
# Cannot set QxxLayout directly on the QMainWindow
# Need to create a QWidget and set it as the central widget
widget = QWidget()
layout = QVBoxLayout()
b1 = QPushButton('Red' ); b1.setStyleSheet("background-color: red;")
b2 = QPushButton('Blue' ); b2.setStyleSheet("background-color: blue;")
b3 = QPushButton('Yellow'); b3.setStyleSheet("background-color: yellow;")
layout.addWidget(b1)
layout.addWidget(b2)
layout.addWidget(b3)
widget.setLayout(layout)
self.setCentralWidget(widget)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

How can I position widgets inside a layout?

I'm having trouble with spacing widgets in a QVboxlayout. I have this code:
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
win_w, win_h = 250, 1
self.setGeometry((1920 - win_w) // 2, (1080 - win_h) // 2, win_w, win_h)
self.setWindowTitle('Test')
self.setFont(QtGui.QFont('Times', 12))
self.central_widget()
def central_widget(self):
widget = QtWidgets.QWidget()
grid = QtWidgets.QGridLayout()
group_box1 = QtWidgets.QGroupBox('Group Box')
v1 = QtWidgets.QVBoxLayout()
text_edit1 = QtWidgets.QTextEdit()
v1.addWidget(QtWidgets.QPushButton('Button'))
v1.addWidget(text_edit1)
group_box1.setLayout(v1)
grid.addWidget(group_box1, 0, 0)
widget.setLayout(grid)
self.setCentralWidget(widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
Running this brings up this window:
Adding this line v1.setSpacing(100) changes it to this:
Is there any way to make it add the spacing horizontally? Like this:
Use the alignment keyword argument for addWidget():
v1.addWidget(QtWidgets.QPushButton('Button'), alignment=QtCore.Qt.AlignRight)
As already suggested, you should carefully read the documentation about layout managers, including all the listed QLayout subclasses and all their methods. You can do some experiments on your own with them also in Designer, so that you can better understand how they work by directly seeing the results.

PyQt5 Layouts not moving button [duplicate]

I'm making an application in PyQt4 and this is my code so far:
import sys
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUi()
def initUi(self):
self.setWindowTitle('Main Menu')
self.setFixedSize(1200, 625)
self.firstWidgets()
self.show()
def firstWidgets(self):
self.vbox1 = QtGui.QVBoxLayout()
self.task1 = QtGui.QLabel('Check 1', self)
self.task1CB = QtGui.QCheckBox(self)
self.hbox1 = QtGui.QHBoxLayout()
self.hbox1.addWidget(self.task1)
self.hbox1.addWidget(self.task1CB)
self.vbox1.addLayout(self.hbox1)
self.setLayout(self.vbox1)
def main():
application = QtGui.QApplication(sys.argv)
gui = MainWindow()
sys.exit(application.exec_())
if __name__=='__main__':
main()
My problem is in MainWindow.firstWidgets(). I try to set a layout but I get an error even though that's my first time using .setLayout for that form, which confuses me.
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "",
which already has a layout
You can't set a QLayout directly on the QMainWindow. You need to create a QWidget and set it as the central widget on the QMainWindow and assign the QLayout to that.
wid = QtGui.QWidget(self)
self.setCentralWidget(wid)
layout = QtGui.QVBoxLayout()
wid.setLayout(layout)
NOTE: This is for Qt4 -- see the other answer on this question for the Qt5 updated code.
Just an update to Brenden Abel's answer:
QWidget and QVBoxLayout (for Python3, PyQt5) are now contained in the PyQt5.QtWidgets module and not the PyQt5.QtGui module.
So updated code:
wid = QtWidgets.QWidget(self)
self.setCentralWidget(wid)
layout = QtWidgets.QVBoxLayout()
wid.setLayout(layout)
This is an example using PyQt5
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('My App')
# Cannot set QxxLayout directly on the QMainWindow
# Need to create a QWidget and set it as the central widget
widget = QWidget()
layout = QVBoxLayout()
b1 = QPushButton('Red' ); b1.setStyleSheet("background-color: red;")
b2 = QPushButton('Blue' ); b2.setStyleSheet("background-color: blue;")
b3 = QPushButton('Yellow'); b3.setStyleSheet("background-color: yellow;")
layout.addWidget(b1)
layout.addWidget(b2)
layout.addWidget(b3)
widget.setLayout(layout)
self.setCentralWidget(widget)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Qt Multiple GraphicsEffects

Is there a way in Qt5 to apply a QGraphicsEffect to a widget, even when one of its parent widgets already has a QGraphicsEffect applied to it?
When i try the following:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class ParentWidget(QWidget):
def __init__(self,parent):
super().__init__(parent)
effect = QGraphicsBlurEffect(self)
self.setGraphicsEffect(effect)
effect.setBlurRadius(0)
class ChildWidget(ParentWidget):
def __init__(self,parent):
super().__init__(parent)
self.layout = QGridLayout(self)
widget = QWidget()
widget.setObjectName('reviewControlArea')
effect = QGraphicsOpacityEffect(widget)
widget.setGraphicsEffect(effect)
self.layout.addWidget(widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
MainWindow = QMainWindow()
cw = ChildWidget(MainWindow)
MainWindow.setCentralWidget(cw)
MainWindow.show()
sys.exit(app.exec_())
The stdout says:
QPainter::begin: A paint device can only be painted by one painter at a time.

How to center text in QComboBox?

I've tried using QComboBox's model() with no apparent success. I wonder if it would be possible to align a text at the center of QCombobox. Aside from text alignment it seems the item's font is not effected by changing its PointSize....
combo=QtGui.QComboBox()
comboModel=combo.model()
for name in ['one','two','three']:
item = QtGui.QStandardItem(name)
itemFont = item.font()
itemFont.setPointSize(8)
item.setFont(itemFont)
# item.setAlignment(QtCore.Qt.AlignCenter)
comboModel.appendRow(item)
You can use setAlignment method:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QVBoxLayout(self)
self.combo = QtGui.QComboBox()
self.combo.setEditable(True)
self.combo.lineEdit().setAlignment(QtCore.Qt.AlignCenter)
self.combo.addItems('One Two Three Four Five'.split())
layout.addWidget(self.combo)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

Categories