pyqt expand grid in scroll area - python

I have a grid area in a scroll area within a dialog
class IndicSelectWindow(QDialog):
def __init__(self, path, parent=None):
super(IndicSelectWindow, self).__init__(parent)
self.resize(500, 400)
self.scroll_area = QScrollArea(self)
self.scroll_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.grid_layout = QGridLayout(self.scroll_area)
self.exec_()
How can I make the grid cover the full area of the scroll_area. it does not have a method setSizePolicy. How can I make this work?

You must add the QGridLayout to the QWidget that is added to the QScrollArea
import sys
from PyQt5 import QtWidgets
class IndicSelectWindow(QtWidgets.QDialog):
def __init__(self, parent=None):
super(IndicSelectWindow, self).__init__(parent=parent)
self.resize(500, 400)
self.layout = QtWidgets.QHBoxLayout(self)
self.scrollArea = QtWidgets.QScrollArea(self)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.gridLayout = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.layout.addWidget(self.scrollArea)
for i in range(100):
for j in range(100):
self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = IndicSelectWindow()
w.show()
sys.exit(app.exec_())

Related

Make QGroupBox selectable and clickable

I have the following toy interface:
from PyQt5 import QtWidgets, QtGui, QtCore
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
w = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
w.setLayout(layout)
self.setCentralWidget(w)
my_tree = QtWidgets.QTreeWidget()
layout.addWidget(my_tree)
alpha = QtWidgets.QTreeWidgetItem(my_tree, ['Alpha'])
beta = QtWidgets.QTreeWidgetItem(my_tree, ['Beta'])
alpha.addChild(QtWidgets.QTreeWidgetItem(['one']))
alpha.addChild(QtWidgets.QTreeWidgetItem(['two']))
beta.addChild(QtWidgets.QTreeWidgetItem(['first']))
beta.addChild(QtWidgets.QTreeWidgetItem(['second']))
my_tree.expandAll()
alpha.child(0).setSelected(True)
scroll = QtWidgets.QScrollArea()
layout.addWidget(scroll)
scrollLayout = QtWidgets.QVBoxLayout()
scrollW = QtWidgets.QWidget()
scroll.setWidget(scrollW)
scrollW.setLayout(scrollLayout)
scrollLayout.setAlignment(QtCore.Qt.AlignTop)
scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
scroll.setWidgetResizable(True)
for _ in range(5):
fooGroup = QtWidgets.QGroupBox()
fooLayout = QtWidgets.QVBoxLayout()
fooGroup.setLayout(fooLayout)
fooItem1 = QtWidgets.QLabel("fooItem1")
fooItem2 = QtWidgets.QLabel("fooItem2")
fooItem3 = QtWidgets.QLabel("fooItem3")
fooLayout.addWidget(fooItem1)
fooLayout.addWidget(fooItem2)
fooLayout.addWidget(fooItem3)
scrollLayout.addWidget(fooGroup)
self.show()
app = QtWidgets.QApplication([])
window = MainWindow()
app.exec_()
How can I make each group in the scroll area selectable and clickable by the user?
I have so far tried to add the following code in the loop:
def onFooGroupClick():
print("Group")
fooGroup.clicked.connect(onFooGroupClick)
and (as per this post):
def onFooGroupClick():
print("Group")
def f():
return onFooGroupClick()
fooGroup.mousePressEvent = f()
However, all my efforts have been unsuccessful and I cannot seem to be able to make it work.
Create a class that inherits from QGroupBox.
Define the clicked signal in it and override the mousePressEvent method.
from PyQt5 import QtWidgets, QtGui, QtCore
class GroupBox(QtWidgets.QGroupBox): # +++ !!!
clicked = QtCore.pyqtSignal(str, object) # +++
def __init__(self, title):
super(GroupBox, self).__init__()
self.title = title
self.setTitle(self.title)
def mousePressEvent(self, event):
child = self.childAt(event.pos())
if not child:
child = self
self.clicked.emit(self.title, child) # +++
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
w = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
w.setLayout(layout)
self.setCentralWidget(w)
my_tree = QtWidgets.QTreeWidget()
layout.addWidget(my_tree)
alpha = QtWidgets.QTreeWidgetItem(my_tree, ['Alpha'])
beta = QtWidgets.QTreeWidgetItem(my_tree, ['Beta'])
alpha.addChild(QtWidgets.QTreeWidgetItem(['one']))
alpha.addChild(QtWidgets.QTreeWidgetItem(['two']))
beta.addChild(QtWidgets.QTreeWidgetItem(['first']))
beta.addChild(QtWidgets.QTreeWidgetItem(['second']))
my_tree.expandAll()
alpha.child(0).setSelected(True)
scroll = QtWidgets.QScrollArea()
layout.addWidget(scroll)
scrollLayout = QtWidgets.QVBoxLayout()
scrollW = QtWidgets.QWidget()
scroll.setWidget(scrollW)
scrollW.setLayout(scrollLayout)
scrollLayout.setAlignment(QtCore.Qt.AlignTop)
scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
scroll.setWidgetResizable(True)
for _ in range(5):
fooGroup = GroupBox(f'GroupBox_{_}') # - QtWidgets.QGroupBox()
fooGroup.setObjectName(f'fooGroup {_}')
fooGroup.clicked.connect(self.onFooGroupClick) # +++
fooLayout = QtWidgets.QVBoxLayout()
fooGroup.setLayout(fooLayout)
fooItem1 = QtWidgets.QLabel("fooItem1", objectName="fooItem1")
fooItem1.setStyleSheet('background: #44ffff')
fooItem2 = QtWidgets.QLabel("fooItem2", objectName="fooItem2")
fooItem2.setStyleSheet('background: #ffff56;')
fooItem3 = QtWidgets.QLabel("fooItem3", objectName="fooItem3")
fooItem3.setStyleSheet('background: #ff42ff;')
fooLayout.addWidget(fooItem1)
fooLayout.addWidget(fooItem2)
fooLayout.addWidget(fooItem3)
scrollLayout.addWidget(fooGroup)
def onFooGroupClick(self, title, obj): # +++
print(f"Group: {title}; objectName=`{obj.objectName()}`")
if __name__ == '__main__':
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
app.exec_()

Embed QGraphics in widget

I have a main widget inside a window who contains a lot of widgets. How can I insert a QGraphics view and a QGraphicsScene in that widget? I have not found a direct insertion method, so I am trying using a wrapper, in this case a box layout but it is not a good solution. The QGraphicsScene stands out from the layout limits.
Code:
class UiVentana(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setFixedSize(1500, 1015)
widget_central = QtWidgets.QWidget(self)
wrapper = QtWidgets.QHBoxLayout(widget_central)
scene = QtWidgets.QGraphicsScene(wrapper)
vista = QtWidgets.QGraphicsView(scene)
wrapper.addWidget(vista)
self.diedrico = Diedrico() # This is a class who draw things, not relevant
self.diedrico.setFixedSize(2000, 2000)
scene.addWidget(self.diedrico)
self.setCentralWidget(widget_central)
I would like to get this result:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QPen, QColor
import sys
class Diedrico(QWidget):
def __init__(self, parent):
super().__init__(parent)
def paintEvent(self, event):
qp = QPainter(self)
qp.setPen(QPen(QColor(Qt.black), 5))
qp.drawRect(500, 500, 1000, 1000)
class UiVentana(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(UiVentana, self).__init__(parent)
self.resize(520, 520)
self.widget_central = QtWidgets.QWidget(self)
scrol = QtWidgets.QScrollArea(self.widget_central)
scrol.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scrol.setGeometry(QtCore.QRect(30, 30, 500, 500))
scrol.setWidgetResizable(False)
contenido = QtWidgets.QWidget()
contenido.setGeometry(QtCore.QRect(0, 0, 2000, 2000))
scrol.setWidget(contenido)
self.Diedrico = Diedrico(contenido)
self.Diedrico.setGeometry(QtCore.QRect(0, 0, 2000, 2000))
self.setCentralWidget(self.widget_central)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ui = UiVentana()
ui.show()
sys.exit(app.exec_())
But using QGraphics instead of a scroll area
The QGraphicsProxyWidget that is created using the widget takes into account the minimum size of the widget to set the boundingRect, and the QGraphicsScene uses the boundingRect to set the initial scene rect.
from PyQt5 import QtCore, QtGui, QtWidgets
class Diedrico(QtWidgets.QWidget):
def paintEvent(self, event):
qp = QtGui.QPainter(self)
pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.black), 5)
qp.setPen(pen)
qp.drawRect(500, 500, 1000, 1000)
def minimumSizeHint(self):
return QtCore.QSize(2000, 2000)
class UiVentana(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(UiVentana, self).__init__(parent)
self.resize(520, 520)
widget_central = QtWidgets.QWidget()
self.setCentralWidget(widget_central)
lay = QtWidgets.QVBoxLayout(widget_central)
scene = QtWidgets.QGraphicsScene(self)
view = QtWidgets.QGraphicsView(scene)
diedrico = Diedrico()
scene.addWidget(diedrico)
lay.addWidget(view)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ui = UiVentana()
ui.show()
sys.exit(app.exec_())

How can i add push button to each and every item of the list view

Here is my sample code,i want to add a push button to each and every row of the list view.I am not found any method to set the widget to model.Can any one please help me how to add widget for each and every row of the list view.Thank you in advance.
Given below is my code:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyCustomWidget(QWidget):
def __init__(self,parent=None):
super(MyCustomWidget, self).__init__(parent)
self.row = QHBoxLayout()
self.row.addWidget(QPushButton("add"))
self.setLayout(self.row)
class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent=parent)
vLayout = QtGui.QVBoxLayout(self)
hLayout = QtGui.QHBoxLayout()
self.lineEdit = QtGui.QLineEdit()
hLayout.addWidget(self.lineEdit)
self.filter = QtGui.QPushButton("filter", self)
hLayout.addWidget(self.filter)
self.list = QtGui.QListView(self)
vLayout.addLayout(hLayout)
vLayout.addWidget(self.list)
self.model = QtGui.QStandardItemModel(self.list)
codes = [
'windows',
'windows xp',
'windows7',
'hai',
'habit',
'hack',
'good'
]
self.list.setModel(self.model)
for code in codes:
item = QtGui.QStandardItem(code)
self.model.appendRow(item)
self.list.setIndexWidget(item.index(), QtGui.QPushButton("button"))
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
You have to create a custom widget where you must set the button on the right side with a layout.
import sys
from PyQt4 import QtCore, QtGui
class CustomWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(CustomWidget, self).__init__(parent)
self.button = QtGui.QPushButton("button")
lay = QtGui.QHBoxLayout(self)
lay.addWidget(self.button, alignment=QtCore.Qt.AlignRight)
lay.setContentsMargins(0, 0, 0, 0)
class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent=parent)
vLayout = QtGui.QVBoxLayout(self)
hLayout = QtGui.QHBoxLayout()
self.lineEdit = QtGui.QLineEdit()
hLayout.addWidget(self.lineEdit)
self.filter = QtGui.QPushButton("filter", self)
hLayout.addWidget(self.filter)
self.list = QtGui.QListView(self)
vLayout.addLayout(hLayout)
vLayout.addWidget(self.list)
self.model = QtGui.QStandardItemModel(self.list)
codes = [
'windows',
'windows xp',
'windows7',
'hai',
'habit',
'hack',
'good'
]
self.list.setModel(self.model)
for code in codes:
item = QtGui.QStandardItem(code)
self.model.appendRow(item)
self.list.setIndexWidget(item.index(), CustomWidget())
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())

show groupbox inside window (not in new window) PyQt5

My code show GroupBox in new window. how to return it to inside main windoow?
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QMainWindow, QtWidgets.QDialog):
def __init__(self):
super(Window, self).__init__()
V = app.desktop().screenGeometry()
h = V.height()
w = V.width()
x = 1000
y = 600
self.setGeometry(h/4, w/20, x, y)
self.setFixedSize(x, y)
self.setWindowTitle('Main Window')
self.home()
def home(self):
Window.tools_in_home(self)
self.show()
def tools_in_home(self):
self.groupBox = QtWidgets.QGroupBox('GroupBox')
self.groupBox.move(150, 50)
self.groupBox.resize(800, 400)
hBoxLayout = QtWidgets.QHBoxLayout()
button1 = QtWidgets.QPushButton('Test', self)
hBoxLayout.addWidget(button1)
self.groupBox.setLayout(hBoxLayout)
vBox = QtWidgets.QVBoxLayout()
vBox.addWidget(self.groupBox)
self.setLayout(vBox)
self.groupBox.show()
def run():
global app
app = QtWidgets.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()
Try it:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Window(QtWidgets.QMainWindow): #, QtWidgets.QDialog):
def __init__(self):
super(Window, self).__init__()
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
centralWidget = QtWidgets.QWidget()
self.setCentralWidget(centralWidget)
self.grid = QtWidgets.QGridLayout(centralWidget)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
V = QtWidgets.QApplication.desktop().screenGeometry()
h = V.height()
w = V.width()
x = 1000
y = 600
self.setGeometry(h/4, w/20, x, y)
self.setFixedSize(x, y)
self.setWindowTitle('Main Window')
self.home()
def home(self):
# Window.tools_in_home(self)
self.tools_in_home()
self.show()
def tools_in_home(self):
self.groupBox = QtWidgets.QGroupBox('GroupBox')
self.groupBox.move(150, 50)
self.groupBox.resize(800, 400)
hBoxLayout = QtWidgets.QHBoxLayout()
button1 = QtWidgets.QPushButton('Test', self)
hBoxLayout.addWidget(button1)
self.groupBox.setLayout(hBoxLayout)
# vBox = QtWidgets.QVBoxLayout()
# vBox.addWidget(self.groupBox)
self.grid.addWidget(self.groupBox) # +++
# self.setLayout(vBox)
# self.groupBox.show()
def run():
# global app
app = QtWidgets.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()

How can I make a white box in PyQt?

I have a PyQt application that has a widget called Deck
class Deck(QtGui.QWidget):
def __init__(self, filename, parent):
super(Deck, self).__init__(parent)
self.setMinimumSize(100, 150)
self.setStyleSheet('background-color: white;')
label = QtGui.QLabel("deck", self)
label.show()
I expected the Deck widget to be all white, but it is only under the label, although it accepts clicks on its 100x150 area and adjusts its hbox:s size.
Edit:
The surrounding layout.
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
#import qt4reactor
#qt4reactor.install()
from deck import Deck
class Duel(QtGui.QWidget):
def __init__(self):
super(Duel, self).__init__()
topArea = QtGui.QHBoxLayout()
topArea.addStretch(1)
d = Deck(sys.argv[1], self)
d.show()
topArea.addWidget(d)
bottomArea = QtGui.QHBoxLayout()
d = Deck(sys.argv[2], self)
d.show()
bottomArea.addWidget(d)
bottomArea.addStretch(1)
vbox = QtGui.QVBoxLayout()
vbox.addLayout(topArea)
vbox.addStretch(1)
vbox.addLayout(bottomArea)
self.setLayout(vbox)
def main():
root = Duel()
root.show()
app.exec_()
if __name__ == '__main__':
main()

Categories