PYQT5 QMainWindow setCentralWidget consisting of multiple box layouts - python

For a project in programming class we need to develop an application and have to use PYQT5 for the GUI.
I have a class based on QMainWindow. There are some lines of code I don't quite understand. Below is the initialization:
# Snippet 1
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
# self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setWindowTitle("Main Window")
Then, the following variables/GUI elements are defined:
# Snippet 2
self.main_widget = QtWidgets.QWidget(self)
l = QtWidgets.QVBoxLayout(self.main_widget)
sc = MyStaticMplCanvas(width=5, height=4, dpi=100) # just some graph
dc = MyDynamicMplCanvas(width=5, height=4, dpi=100) # another graph
l.addWidget(sc)
l.addWidget(dc)
Then, I tried to add a horizontal box layout with the following content:
# Snippet 3
x = QtWidgets.QHBoxLayout(self.main_widget) # new
b1 = QtWidgets.QPushButton("Test1") # new
b2 = QtWidgets.QPushButton("Test2") # new
x.addWidget(p1) # new
x.addWidget(p2) # new
Lastly, the central widget is generated:
# Snippet 4
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
The program itself produces no error and works properly. But only the two graphs in snippet 2 are displayed in the window. If you delete
self.main_widget
from
l = QtWidgets.QVBoxLayout(self.main_widget)
and leave the parenthesis empty, only the buttons in snippet 3 are displayed.
What is the meaning behind the following assignment?
self.main_widget = QtWidgets.QWidget(self)
Are you able to combine the vertical and horizontal box layout into a single one and therefore display the two buttons as well as the two graphs as the central widget?
This was my original plan and I tried some things with the addLayout() and setLayout() options and wanted to add these layouts to the setCentralWidget() but was not successful.
Do you have an idea on how to display a combination of multliple box layouts as the central widget in a class based on QMainWindow?
Thank you very much. :)

You can nest layouts using addLayout() on a layout; the inner layout then becomes a child of the layout it is inserted into.
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setWindowTitle("Main Window")
self.main_widget = QtWidgets.QWidget(self)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
l = QtWidgets.QVBoxLayout(self.main_widget)
sc = MyStaticMplCanvas(width=5, height=4, dpi=100) # just some graph
dc = MyDynamicMplCanvas(width=5, height=4, dpi=100) # another graph
l.addWidget(sc)
l.addWidget(dc)
# Snippet 3
x = QtWidgets.QHBoxLayout() # self.main_widget) # new
b1 = QtWidgets.QPushButton("Test1") # new
b2 = QtWidgets.QPushButton("Test2") # new
x.addWidget(b1) # new + b1
x.addWidget(b2) # new + b2
l.addLayout(x) # <----
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = ApplicationWindow()
MainWindow.show()
sys.exit(app.exec_())

Related

Position two QTreeView in QHBoxLayout

i want to display two QTreeViews inside one window and i cant figure out why my testing code doesn't show the red widget (future 2nd TreeView). Any ideas why it doesn't appear?
I am new to PyQt5 and ive followed a tutorial on youtube and a written here. Before i started this question ive searched on stackoverflow, but i didn't find a topic which had this issue.
StandardItem is a subclass of QStandardItem and Color is a subclass of QWidget. Im not defining any layouts inside both classes (just setting default settings for QStandardItems and adding color to see my layout).
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("JSON View")
self.resize(700, 700)
treeView = QTreeView(self)
treeView.setHeaderHidden(True) # To hide first column
treeModel = QStandardItemModel()
rootNode = treeModel.invisibleRootItem()
# Data
america = StandardItem('America', 16, set_bold=True)
california = StandardItem('California', 14)
america.appendRow(california)
oakland = StandardItem('Oakland', 12)
california.appendRow(oakland)
rootNode.appendRow(america)
treeView.setModel(treeModel)
treeView.expandAll()
treeView.doubleClicked.connect(self.getValue)
# Layout
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(20)
layout.addWidget(Color('red'))
layout.addWidget(Color('yellow'))
layout.addWidget(treeView)
treeView.setVisible(True)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
So after reading more documentation (QTreeView, QGroupBox, QVBoxLayout) on this topic ive found that i had to use an additional layout inside where i can combine two more layouts for each tree view. Afterwards i would use a dummy-widget as central widget. I posted the code below if anyone has the same problem:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("JSON View")
# Retrieve geometry of window
windowGeometry = self.frameGeometry()
# Get center of the screen
centerScreen = QDesktopWidget().availableGeometry().center()
# Move window to the center
windowGeometry.moveCenter(centerScreen)
self.move(windowGeometry.topLeft())
treeViewLeft = QTreeView(self)
treeViewLeft.setHeaderHidden(True) # To hide first column
treeViewRight = QTreeView(self)
treeViewRight.setHeaderHidden(True)
groupBoxLeft = QGroupBox('1. Json tree view')
groupBoxRight = QGroupBox('2. Json tree view')
# TODO: Add Column headers for each tree view
treeModelLeft = QStandardItemModel(0, 7)
rootNodeLeft = treeModelLeft.invisibleRootItem() # Provides access to the model’s top-level items through the QStandardItem API
treeModelRight = QStandardItemModel()
rootNodeRight = treeModelRight.invisibleRootItem() # Provides access to the model’s top-level items through the QStandardItem API
# Data (left)
america = StandardItem('America', 16, set_bold=True)
california = StandardItem('California', 14)
america.appendRow(california)
oakland = StandardItem('Oakland', 12)
california.appendRow(oakland)
rootNodeLeft.appendRow(america)
treeViewLeft.setModel(treeModelLeft)
treeViewLeft.expandAll()
treeViewLeft.doubleClicked.connect(self.getValue)
treeViewLeft.setVisible(True)
# Data (right)
america = StandardItem('America', 16, set_bold=True)
california = StandardItem('California', 14)
america.appendRow(california)
oakland = StandardItem('Oakland', 12)
california.appendRow(oakland)
rootNodeRight.appendRow(america)
treeViewRight.setModel(treeModelRight)
treeViewRight.expandAll()
treeViewRight.doubleClicked.connect(self.getValue)
treeViewRight.setVisible(True)
# Layout
hbox = QVBoxLayout()
hbox.addWidget(treeViewLeft)
groupBoxLeft.setLayout(hbox)
hbox2 = QVBoxLayout()
hbox2.addWidget(treeViewRight)
groupBoxRight.setLayout(hbox2)
mainLayout = QHBoxLayout()
mainLayout.addWidget(groupBoxLeft)
mainLayout.addWidget(groupBoxRight)
widget = QWidget() # Dummy
widget.setLayout(mainLayout)
self.setCentralWidget(widget) # Must-have
def getValue(self, val):
print(val.data())
print(val.row())
print(val.column())
The following code-examples helped aswell:
pythonguis and pythonspot
Cheers!

How can I pass variables back and forth between two classes in PyQt5?

I am developing a GUI that imports and plots data (csv file). Data are initially imported in the TabWidget() class using getfile() and on_pushButtonLoad_clicked() and passed to the FirstTab() class, where MRChart() is plotted in the infrastructure() widget. To achieve this, I created the firstTab instance in TabWidget() (apologies if my terminology is incorrect here).
The end goal is to update the plot based on the numerical range selected on a rangeslider. Firstly, I want to pass the value of slider1 to FirstTab() and I should be able to manage from there. To do this, I have attempted to create the tabwidget instance in FirstTab(). However, I get the following: "RecursionError: maximum recursion depth exceeded". I presume this is due to each class having an instance of itself contained in the other.
Any help appreciated.
Code:
class TabWidget(QDialog):
def __init__(self, data):
super(TabWidget, self).__init__()
self.data = data
self.firstTab = FirstTab(self.data)
self.showMaximized()
# create Header
FilterLayout = QHBoxLayout()
FilterLayout.addWidget(self.createHeader1a(), 1)
FilterLayout.addWidget(self.createHeader2a(), 4)
# create Tab
tabwidget = QTabWidget()
tabwidget.addTab(self.firstTab, "Tab 1")
vbox = QVBoxLayout()
vbox.addLayout(FilterLayout)
vbox.addWidget(tabwidget)
self.setLayout(vbox)
def createHeader1a(self): #Import
HeaderBox = QGroupBox("Import Data")
inputfilebtn = QPushButton("Import")
inputfilebtn.clicked.connect(self.on_pushButtonLoad_clicked)
# importrow1
importrow1layout = QHBoxLayout()
importrow1layout.addWidget(inputfilebtn)
HeaderLayout = QVBoxLayout()
HeaderLayout.addLayout(importrow1layout)
HeaderBox.setLayout(HeaderLayout)
HeaderBox.setFlat(True)
return HeaderBox
def createHeader2a(self): #Filter
HeaderBox = QGroupBox("Filter Data")
rightlayout = QHBoxLayout()
# range slider bar to filter column data for plotting
label4 = QLabel(self)
label4.setText("Filter range:")
rightlayout.addWidget(label4)
self.slider1 = QLabeledRangeSlider(Qt.Horizontal)
self.slider1.setRange(5, 500)
self.slider1.setValue((150, 300))
rightlayout.addWidget(self.slider1)
HeaderBox.setLayout(rightlayout)
HeaderBox.setFlat(True) #
return HeaderBox
#import and return file
def getfile(self):
option = QFileDialog.Options()
fname = QFileDialog.getOpenFileName(self, 'Open file',
'c:\\', "CSV files (*.csv)", options=option)
return pd.read_csv(fname[0])
#QtCore.pyqtSlot()
def on_pushButtonLoad_clicked(self):
importedfile = self.getfile()
if importedfile is None:
return
self.firstTab.MRChart(importedfile)
global database
database = importedfile
def getslider1value(self):
return self.slider1.value
class FirstTab(QWidget):
def __init__(self, data):
super(FirstTab, self).__init__()
self.data = data
self.tabwidget = TabWidget(self.data)# issue here. Attempting to # access TabWidget class
# Grid layout of entire tab
layout = QGridLayout()
layout.addWidget(self.infrastructure(self.data), 3, 0)
layout.setRowStretch(4, 3)
layout.setColumnStretch(0, 1)
self.setLayout(layout)
def MRChart(self, importedfile): # pie chart
if self.radioButton1.isChecked():
fig = go.Pie(labels=importedfile[self.radioButton1.label])
elif self.radioButton2.isChecked():
fig = go.Pie(labels=importedfile[self.radioButton2.label])
layout = go.Layout(autosize=True, legend=dict(orientation="h", xanchor='center', x=0.5))
fig = go.Figure(data=fig, layout=layout)
fig.update_layout(margin=dict(t=0, b=0, l=0, r=0))
self.browser.setHtml(fig.to_html(include_plotlyjs='cdn'))
def infrastructure(self, importedfile):
groupBox = QGroupBox("Plot")
self.browser = QtWebEngineWidgets.QWebEngineView(self)
right = QVBoxLayout()
# Change/update plot (MRChart) depending on what Radio button is selected
self.radioButton1 = QRadioButton("Label 1")
self.radioButton1.label = "Column_label_1"
self.radioButton1.toggled.connect(lambda: self.MRChart(database))
right.addWidget(self.radioButton1)
self.radioButton2 = QRadioButton("Label 2")
self.radioButton2.setChecked(True)
self.radioButton2.label = "Column_label_2"
self.radioButton2.toggled.connect(lambda: self.MRChart(database))
right.addWidget(self.radioButton2)
middleright = QHBoxLayout()
middleright.addWidget(self.browser)
middleright.addLayout(right)
groupBox.setLayout(middleright)
groupBox.setFlat(True)
print(self.tabwidget.getslider1value())# attempting to print slider value here
return groupBox
if __name__ == "__main__":
app = QApplication(sys.argv)
tabwidget = TabWidget(data=None)
tabwidget.show()
app.exec()
The recursion error is clear: TabWidget tries to create FirstTab, but there you're trying to create another TabWidget, which will create a further FirstTab and so on.
If you want to keep reference between objects, you must pass references, not create new instances (see the note below).
Also, since FirstTab calls infrastructure in the __init__, at that point the slider in the parent widget has not been created yet.
You must move the creation of FirstTab after the slider is created, and pass the reference in the constructor.
class TabWidget(QDialog):
def __init__(self, data):
super(TabWidget, self).__init__()
self.data = data
self.showMaximized()
# create Header
FilterLayout = QHBoxLayout()
FilterLayout.addWidget(self.createHeader1a(), 1)
FilterLayout.addWidget(self.createHeader2a(), 4)
self.firstTab = FirstTab(self) # <- pass the reference of the parent
# ...
class FirstTab(QWidget):
def __init__(self, tabwidget):
super(FirstTab, self).__init__()
self.tabwidget = tabwidget
self.data = tabwidget.data
# ...
Note that this is the same problem you had in your previous question. I strongly suggest you to review the basics of classes and instances and OOP in general, as knowledge and comprehension of those aspects cannot be ignored.

Strange grafical artifacts while re-inserting widgets into gridlayout [duplicate]

I have a QVBox layout that houses a QVBox layout and a QHBox layout. I use the other QVBox layout to hold dynamically created GUI objects and the QHBox layout to hold the buttons that add/remove those objects. Everything works correctly if I position the QHBox on top of the QVBox, but when I try to position the QHBox beneath the QVBox the objects aren't removed correctly but stay there "lingering" on top of the QHBox. I'll upload pictures to demonstrate the problem. First picture is before taking action, second is after creating a new object and third is after deleting the object
Here is the code that creates and deletes the new objects
def addClient(self):
if (len(self.clients) < 5):
client = clientComponent(self)
self.clients.append(client)
index = len(self.clients)-1
self.vLayout3.addWidget(self.clients[index])
client.setIndex(index)
self.clients[index].startButton.clicked.connect(partial(self.threadcontrol, '2', client.getIndex()))
self.clients[index].stopButton.clicked.connect(partial(self.clientstop, '0', client.getIndex()))
def deleteClient(self):
if (len(self.clients) > 1):
self.vLayout3.removeWidget(self.clients.pop())
This is where I complete the layout
def initializeUi(self):
self.mainWidget = QWidget(self)
self.setCentralWidget(self.mainWidget)
self.mainLayout = QVBoxLayout(self.mainWidget)
self.hLayout1 = QHBoxLayout()
self.hLayout2 = QHBoxLayout()
self.vLayout1 = QVBoxLayout()
self.vLayout2 = QVBoxLayout()
self.vLayout3 = QVBoxLayout()
self.addServer()
self.addClient()
self.serverBox = QGroupBox('Server')
self.clientBox = QGroupBox('Client')
self.traffic1 = QLabel('0.0Mb/s', self)
self.traffic1.setAlignment(Qt.AlignRight)
self.traffic2 = QLabel('0.0Mb/s', self)
self.traffic2.setAlignment(Qt.AlignCenter)
self.traffic3 = QLabel('0.0Mb/s', self)
self.traffic3.setAlignment(Qt.AlignLeft)
self.newClientButton = QPushButton('+', self)
self.deleteClientButton = QPushButton('-', self)
self.hLayout1.addWidget(self.traffic1)
self.hLayout1.addWidget(self.traffic2)
self.hLayout1.addWidget(self.traffic3)
self.hLayout2.addWidget(self.newClientButton)
self.hLayout2.addWidget(self.deleteClientButton)
self.vLayout2.addLayout(self.vLayout3)
self.vLayout2.addLayout(self.hLayout2)
self.mainLayout.addWidget(self.plot)
self.mainLayout.addLayout(self.hLayout1)
self.serverBox.setLayout(self.vLayout1)
self.mainLayout.addWidget(self.serverBox)
self.clientBox.setLayout(self.vLayout2)
self.mainLayout.addWidget(self.clientBox)
This is happening because your main window remains the parent of the client widgets after you remove them from the layout. You will see similar behaviour if you assign a widget a parent widget without adding it to any layout.
Removing the parent should resolve the issue.
def deleteClient(self):
if (len(self.clients) > 1):
client = self.clients.pop()
self.vLayout3.removeWidget(client)
client.setParent(None)
You may also need to make a call to adjustSize to resize the window to fit the remaining widgets
When you delete a widget from layout it still remains in parent widget's
object tree, so it gets displayed outside of any layout.
To remove a widget from the object tree call widget.setParent(None).
widget.deleteLater() also works.
Here is my MCVE(Qt4, Py2.7):
from PyQt4.QtGui import (QApplication, QWidget, QPushButton,
QVBoxLayout, QHBoxLayout)
app=QApplication([])
self = QWidget()
main_layout = QVBoxLayout(self)
clients = []
l2 = QHBoxLayout()
main_layout.addLayout(l2)
b_add = QPushButton('add', self)
l2.addWidget(b_add)
def addClient():
b = QPushButton(str(len(clients)), self)
clients.append(b)
main_layout.addWidget(b)
b_add.clicked.connect(addClient)
b_rm = QPushButton('rm', self)
l2.addWidget(b_rm)
def deleteClient():
b = clients.pop()
main_layout.removeWidget(b)
# comment out two following lines to get the behavior you observe
b.setParent(None)
self.adjustSize()
b_rm.clicked.connect(deleteClient)
self.show()
app.exec_()
On my system I also have to call self.adjustSize() after deletion to resize the main window

Stop widgets from overlapping each other and add space between them

I am using QHBoxLayout for layout. The breakdown is: pic.1 is what happens, pic.2 is what I want - widgets don't overlap and there is a gap between them. For pic.2, I created a Gap widget to stick between the existing widgets. But this is a cumbersome solution which implies extra maintenance (especially when I have more than two widgets to care for). Moreover, since B overlaps A, I think the newly added gap widget overlaps A as well, maybe according the fraction of its size. I am not so sure about this.
I tried using self.layout.addSpacing(10), but that doesn't work. The red widget shifts by 10 pixels from where it was before, not from the border of the widget on the left.
Note, too, that the contained widgets will all have some minimum width specification.
So, how can I add the space between two widgets like in pic.2?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Gap(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setMinimumWidth(10)
self.setMinimumHeight(1)
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
# Set layout
self.layout = QHBoxLayout()
self.setLayout(self.layout)
# Set palette
self.palette1 = QPalette()
self.palette1.setColor(QPalette.Window, Qt.red)
self.palette2 = QPalette()
self.palette2.setColor(QPalette.Window, Qt.blue)
self.palettebg = QPalette()
self.palettebg.setColor(QPalette.Window, Qt.green)
self.setAutoFillBackground(True)
self.setPalette(self.palettebg)
# Set labels
self.label1 = QLabel(self)
self.label1.setText("A")
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.adjustSize()
self.label1.setAutoFillBackground(True)
self.label1.setPalette(self.palette1)
self.label1.setMinimumSize(36, 36)
self.label2 = QLabel(self)
self.label2.setText("B")
self.label2.move(30, 0)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.adjustSize()
self.label2.setAutoFillBackground(True)
self.label2.setPalette(self.palette2)
self.label2.setMinimumSize(36, 36)
self.gap = Gap()
self.layout.addWidget(self.label1)
# self.layout.addWidget(self.gap)
# self.layout.addSpacing(10)
self.layout.addWidget(self.label2)
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5'
self.left = 10
self.top = 10
self.width = 200
self.height = 54
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.line = Line(self)
self.line.resize(74, 54)
self.line.move(50, 50)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
# CUSTOM
app.setFont(QFontDatabase().font("Monospace", "Regular", 14))
ex = App()
sys.exit(app.exec_())
EDIT clarification, as requested: (1) suppose the size of the parent widget is too small (and cannot be resized), (2) the parent widget has QHBoxLayout with widgets A and B added to it, (3) the parent widget being too small, QHBoxLayout aranges the child widgets A and B such that they overlap each other like in the first picture. (4) Such overlap is undesirable, instead the widgets just need to be placed one after another, with no overlap, and with gap between them, like in picture 2. I don't know how to do this with QHBoxLayout.
EDIT 2 Here is a visual explanation.
The green here is the parent widget - not resizable by assumption. Widget A is added:
Add widget B:
Now, widget B is on top of A. I don't want it. I want this instead:
The minimumSize of the child widgets does not influence the minimumSize of the parent widget, and the use of the layout does not influence the minimumSize of the widget either. The layouts set the minimumSizeHint and sizeHint using as information the minimumSize of the widgets that handle plus other features such as the size and sizing policy. So in the first instance you must set the minimumSize of the parent widget to be the minimumSizeHint of it.
On the other hand the layout has a spacing by default so it is advisable to set it to 0.
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
# Set layout
layout = QHBoxLayout(self, spacing=0)
layout.addWidget(self.label1)
layout.addSpacing(10)
layout.addWidget(self.label2)
self.setMinimumSize(self.minimumSizeHint())
# or
# layout = QHBoxLayout(self, spacing=10)
# layout.addWidget(self.label1)
# layout.addWidget(self.label2)
# self.setMinimumSize(self.minimumSizeHint())
Update:
The maximum size of the layout that can be handled is the size of the parent widget, so in its case it will compress not respecting the spaces, a solution is to set a widget that is the content, and in that to establish the layout, so the layout will stretch to the content widget with freedom.
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
content_widget = QWidget(self)
layout = QHBoxLayout(content_widget, spacing=10)
layout.addWidget(self.label1)
layout.addWidget(self.label2)
content_widget.setFixedSize(content_widget.minimumSizeHint())

scroll bar for long list of buttons

I have a problem desinging a window using PySide.
class MainForm(QWidget):
def __init__(self, parent=None):
super(MainForm, self).__init__()
# init window
self.hbox = QHBoxLayout(self)
self.scroll = QScrollArea(self)
self.table = QTableWidget(self)
self.leftspltr = QSplitter(QtCore.Qt.Vertical)
self.rightspltr = QSplitter(QtCore.Qt.Vertical)
self.scroll.setWidget(self.leftspltr)
self.rightspltr.addWidget(self.table)
self.hbox.addWidget(self.leftspltr)
self.hbox.addWidget(self.rightspltr)
self.setWindowTitle("...")
self.table.setColumnCount(3)
self.table.move(11,220)
self.table.verticalHeader().hide()
self.table.setHorizontalHeaderLabels(["Key","Full","HR"])
dic = dumpered_hash.dict_naming_values
os.popen("rm dumpered_hash dumpered_hash.py dumpered_hash.pyc")
xpos = 0
ypos = 0
for key, val1 in sorted(dic.iteritems()):
btn = QPushButton(key, self)
btn.clicked.connect(partial(self.fillTbl, val1, len(val1) + 1))
btn.setFixedSize(84,20)
self.leftspltr.addWidget(btn)
im trying to design a window that has some button (more than 30) placed virtically, so I want to have them in scroll bar that fits the window size, and a table at the right side that doesnt move while scrolling.
the code above gives me a tiny scroll bar that moves the button, bur they are out of the window size.
what wrong there ?
I think I understand what you are trying to do here. However, you are placing your buttons in a vertical splitter and then fixing their size. Instead, place the buttons in a vertical layout, and then place that and the table widget into a horizontal splitter.
class MainForm(QtGui.QWidget):
def __init__(self, parent=None):
super(MainForm, self).__init__()
# init window
self.hbox = QtGui.QHBoxLayout(self)
self.btnbox = QtGui.QVBoxLayout()
self.scroll = QtGui.QScrollArea(self)
self.table = QtGui.QTableWidget(self)
self.spltr = QtGui.QSplitter(QtCore.Qt.Horizontal)
self.setWindowTitle("...")
self.table.setColumnCount(3)
self.table.move(11,220)
self.table.verticalHeader().hide()
self.table.setHorizontalHeaderLabels(["Key","Full","HR"])
dic = {}
for i in range(30):
dic['foo '+str(i)] = [i]
for key, val1 in sorted(dic.iteritems()):
btn = QtGui.QPushButton(key, self)
self.btnbox.addWidget(btn)
# must place layout into a widget before adding to QScrollArea
holder = QtGui.QWidget()
holder.setLayout(self.btnbox)
self.scroll.setWidget(holder)
self.spltr.addWidget(self.scroll)
self.spltr.addWidget(self.table)
self.hbox.addWidget(self.spltr)
I would also like to note, that is it better to include the simplest piece of code necessary to reproduce your problem. I don't know what you are trying to achieve with the lines containing dumpered_hash, but it seems to be irrelevant, as well as a dubious use of a deprecated function, and makes it impossible to run your code without modification. Make it easier for people to help you!

Categories

Resources