I want to display in a QWidget windows 2 buttons and 2 label where the 2 buttons as on the same horizontal layout. and each button will have under it the label.
For this i use to library :
QHBoxLayout
QVBoxLayout
When i run the script it doesn't display all the created widgets.
it display 1 button and 1 label.
code:
import sys
from PyQt5 import QtWidgets
def basicWindow():
app = QtWidgets.QApplication(sys.argv)
windowExample = QtWidgets.QWidget()
buttonA = QtWidgets.QPushButton('Click!')
labelA = QtWidgets.QLabel('Label Example')
buttonb = QtWidgets.QPushButton('Click 2!')
labelb = QtWidgets.QLabel('Label Example 2')
v_box_H = QtWidgets.QHBoxLayout()
# v_box_H2 = QtWidgets.QHBoxLayout()
v_box = QtWidgets.QVBoxLayout()
v_box.addWidget(buttonA)
v_box.addWidget(labelA)
v_box2 = QtWidgets.QVBoxLayout()
v_box2.addWidget(buttonb)
v_box2.addWidget(labelb)
v_box_H.addLayout(v_box)
windowExample.setLayout(v_box)
windowExample.setLayout(v_box2)
windowExample.setWindowTitle('PyQt5 Lesson 4')
windowExample.show()
sys.exit(app.exec_())
basicWindow()
If you run the application from terminal / CMD you get the error:
QWidget::setLayout: Attempting to set QLayout "" on QWidget "", when the QLayout already has a parent
Try it:
import sys
from PyQt5 import QtWidgets
def basicWindow():
app = QtWidgets.QApplication(sys.argv)
windowExample = QtWidgets.QWidget()
buttonA = QtWidgets.QPushButton('Click!')
labelA = QtWidgets.QLabel('Label Example')
buttonb = QtWidgets.QPushButton('Click 2!')
labelb = QtWidgets.QLabel('Label Example 2')
v_box_H = QtWidgets.QHBoxLayout(windowExample) # + windowExample
# v_box_H2 = QtWidgets.QHBoxLayout()
v_box = QtWidgets.QVBoxLayout()
v_box.addWidget(buttonA)
v_box.addWidget(labelA)
v_box2 = QtWidgets.QVBoxLayout()
v_box2.addWidget(buttonb)
v_box2.addWidget(labelb)
v_box_H.addLayout(v_box)
v_box_H.addLayout(v_box2) # +++
# windowExample.setLayout(v_box) # -
# windowExample.setLayout(v_box2) # -
windowExample.setWindowTitle('PyQt5 Lesson 4')
windowExample.show()
sys.exit(app.exec_())
basicWindow()
Related
I wanted to create a scrollbar(pyqt5) into tab, base on example in link below I did some changes to fit my need but the scrollbar didn't show on tab and my charts become smaller.
example PyQt4 - how to add scrollbar into tabbed windows of fixed size?
import file https://filebin.net/u3m7m3x2k74wlm6l
import sys
import os
import pandas as pd
from PyQt5.QtWidgets import ( QApplication, QWidget,QHBoxLayout,QVBoxLayout,QPushButton,QTabWidget,QMainWindow,QGridLayout,QSizePolicy\
,QScrollArea,QGroupBox)
from PyQt5.QtGui import *
from PyQt5.QtCore import *
#import html
import plotly.offline as po
import plotly.express as px
import plotly.graph_objs as go
from PyQt5.QtWebEngineWidgets import *
class Win(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100,100, 1280,900)
self.GuiApp=App()
self.setCentralWidget(self.GuiApp)
self.show()
class Tab1(QWidget):
def __init__(self, parent=None):
super(Tab1, self).__init__(parent)
df = pd.read_csv(r'C:/Users/User/Desktop/Python-setup test/Plot122.csv')# need to download the file from https://filebin.net/u3m7m3x2k74wlm6l
data1 = px.line(df,x = 'Date', y ='AAPL.Open', color = 'Category')
fig4 = go.Figure(data1)
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
raw_html += '<body>'
raw_html += po.plot(fig4, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
#fig_view
fig_view1 = QWebEngineView()
fig_view2 = QWebEngineView()
fig_view3 = QWebEngineView()
fig_view4 = QWebEngineView()
fig_view1.setHtml(raw_html)
fig_view1.setFixedSize(700,600)
fig_view1.show()
fig_view2.setHtml(raw_html)
fig_view2.setFixedSize(700,600)
fig_view2.show()
fig_view3.setHtml(raw_html)
fig_view3.setFixedSize(700,600)
fig_view3.show()
fig_view4.setHtml(raw_html)
fig_view4.setFixedSize(700,600)
fig_view4.show()
layoutC = QGridLayout()
layoutC.addWidget(fig_view1,0,0,1,1)
layoutC.addWidget(fig_view2,0,1,1,1)
layoutC.addWidget(fig_view3,1,0,1,1)
layoutC.addWidget(fig_view4,1,1,1,1)
self.setLayout(layoutC)
self.setSizePolicy(QSizePolicy.Maximum,QSizePolicy.Maximum)
class App(QWidget):
def __init__(self):
super().__init__()
self.layout = QGridLayout(self)
self.setLayout(self.layout)
#Button
BT1 = QPushButton('BT1',self)
self.layout.addWidget(BT1, 0,0,1,1)
##########################################TEST scrollbar in tab ################################################
tab1 = Tab1(self)
self.tabs = QTabWidget(self)
self.tabs.addTab(tab1, 'Page 1')
self.groupscrollbox = QGroupBox()
self.MVB = QVBoxLayout()
self.MVB.addWidget(self.tabs)
widgetTab = QWidget(self)
widgetTab.setLayout(QVBoxLayout())
widgetTab.layout().addWidget(self.groupscrollbox)
self.scroll = QScrollArea()
self.scroll.setWidget(widgetTab)
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setWidgetResizable(False)
self.scroll.setEnabled(True)
self.groupscrollbox.setLayout(self.MVB)
##########################################TEST scrollbar in tab ################################################
self.layout.addWidget(self.groupscrollbox, 0,2,13,1)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Win()
sys.exit(app.exec_())
I want to add scrollbar in the red box which the code between "TEST scrollbar in tab" to show all charts with "Date, It will be overlapped when maximize the window.
Below shows the Charts with "Date" below the charts
The solution is to put "tab1" is a QScrollArea, and that QScrollArea in the QTabWidget
class App(QWidget):
def __init__(self):
super().__init__()
bt1_button = QPushButton("BT1")
tab1 = Tab1()
scrollbar = QScrollArea(widgetResizable=True)
scrollbar.setWidget(tab1)
tabwidget = QTabWidget()
tabwidget.addTab(scrollbar, "Tab1")
layout = QGridLayout(self)
layout.addWidget(bt1_button, 0, 0)
layout.addWidget(tabwidget, 0, 1, 2, 1)
I would like to create tabs which target only a specific area within the GUI.
That is there should be an area of the GUI which is static and always present even when changing tab.
I have already created tabs as according to the following code:
import sys
from PyQt4 import QtGui
def main():
app = QtGui.QApplication(sys.argv)
tabs = QtGui.QTabWidget()
# Create tabs
tab1 = QtGui.QWidget()
tab2 = QtGui.QWidget()
tab3 = QtGui.QWidget()
tab4 = QtGui.QWidget()
# Resize width and height
tabs.resize(1000, 1000)
# Set layout of first tab
vBoxlayout = QtGui.QVBoxLayout()
pushButton1 = QtGui.QPushButton("Start")
pushButton2 = QtGui.QPushButton("Settings")
pushButton3 = QtGui.QPushButton("Stop")
vBoxlayout.addWidget(pushButton1)
vBoxlayout.addWidget(pushButton2)
vBoxlayout.addWidget(pushButton3)
tab1.setLayout(vBoxlayout)
# Add tabs
tabs.addTab(tab1,"Tab 1")
tabs.addTab(tab2,"Tab 2")
tabs.addTab(tab3,"Tab 3")
tabs.addTab(tab4,"Tab 4")
# Set title and show
tabs.setWindowTitle('PyQt QTabWidget # pythonspot.com')
tabs.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I think there is several solution to achieve this.
I will give an example.
First of all, you need to create a main window, where you will create a layout with 2 frames (I took gridlayout for this example). Once done, you can now set one layout per frame, and add widget as you want in those layout. It will populate the frame. So you can populate one frame with your tabs, and one which stay fix.
I did not take in consideration size of the widget, you can fit them as you want.
I just modified a little your example :
import sys
from PyQt4 import QtGui, QtCore
def main():
app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QWidget()
mainLayout = QtGui.QGridLayout(mainWindow)
frameLeft = QtGui.QFrame(mainWindow)
frameLeft.setFrameShape(QtGui.QFrame.StyledPanel)
frameLeft.setFrameShadow(QtGui.QFrame.Raised)
gridLayoutLeft = QtGui.QGridLayout(frameLeft)
mainLayout.addWidget(frameLeft, 0, 0, 1, 1, QtCore.Qt.AlignVCenter)
frameRigth = QtGui.QFrame(mainWindow)
frameRigth.setFrameShape(QtGui.QFrame.StyledPanel)
frameRigth.setFrameShadow(QtGui.QFrame.Raised)
gridLayoutRigth = QtGui.QGridLayout(frameRigth)
mainLayout.addWidget(frameRigth, 0, 1, 1, 1, QtCore.Qt.AlignVCenter)
tabs = QtGui.QTabWidget()
gridLayoutRigth.addWidget(tabs, 0, 0, 1, 1, QtCore.Qt.AlignVCenter)
button = QtGui.QPushButton('test')
gridLayoutLeft.addWidget(button, 0, 0, 1, 1, QtCore.Qt.AlignVCenter)
# Create tabs
tab1 = QtGui.QWidget()
tab2 = QtGui.QWidget()
tab3 = QtGui.QWidget()
tab4 = QtGui.QWidget()
# Set layout of first tab
vBoxlayout = QtGui.QVBoxLayout()
pushButton1 = QtGui.QPushButton("Start")
pushButton2 = QtGui.QPushButton("Settings")
pushButton3 = QtGui.QPushButton("Stop")
vBoxlayout.addWidget(pushButton1)
vBoxlayout.addWidget(pushButton2)
vBoxlayout.addWidget(pushButton3)
tab1.setLayout(vBoxlayout)
# Add tabs
tabs.addTab(tab1, "Tab 1")
tabs.addTab(tab2, "Tab 2")
tabs.addTab(tab3, "Tab 3")
tabs.addTab(tab4, "Tab 4")
# Set title and show
mainWindow.setWindowTitle('PyQt QTabWidget # pythonspot.com')
mainWindow.resize(mainWindow.sizeHint())
mainWindow.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I hope this help !
The QComboBox currentIndexChanged Signal is not firing when a new item is selected from user. But it does fire when .setCurrentIndex is used within the code. (line 91 and 92).
I have a QTabWidget. In tab1 I have a Qvbox into which three Qhboxes are added. Each Qhbox is from the class Kaskade and contains two widgets, a QCombobox and a QstackedWidget. Depending of the current Index of the QCombobox the QstackWidget will either show a QLCD number or a Qspinbox.
If the user changes the QCombobox index in the GUI the currentIndexChanged Signal is not emitted, although the QCombobox shows the new item.
What am I missing? Any kind of help is appreciated.
This is my test code
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys
class Kaskade(QtGui.QWidget):
def __init__(self,sp,sp_min,sp_max, parent = None):
super(Kaskade, self).__init__(parent)
self._sp=sp
self._sp_min=sp_min
self._sp_max=sp_max
self.sp()
self.hbox_gen()
def mode_changed(self,i):
print "Mode has changed to", i
self.sp_stack.setCurrentIndex(i)
def sp(self):
self.sp_stack=QtGui.QStackedWidget(self)
self.sp1 = QtGui.QWidget()
self.sp2 = QtGui.QWidget()
self.sp1UI()
self.sp2UI()
self.sp_stack.addWidget(self.sp1)
self.sp_stack.addWidget(self.sp2)
def sp1UI(self):
self.sp1_layout=QtGui.QHBoxLayout()
self.sp1_lcd=QtGui.QLCDNumber(self)
self.sp1_layout.addWidget(self.sp1_lcd)
#self.sp1.connect(lcd_pv.display)
self.sp1.setLayout(self.sp1_layout)
def sp2UI(self):
self.sp2_layout=QtGui.QHBoxLayout()
self.sp2_spinBox=QtGui.QSpinBox()
self.sp2_spinBox.setRange(self._sp_min,self._sp_max)
self.sp2_spinBox.setValue(self._sp)
self.sp2_layout.addWidget(self.sp2_spinBox)
self.sp2.setLayout(self.sp2_layout)
def hbox_gen(self):
self.mode=QtGui.QComboBox(self)
self.mode.addItem("OFF")
self.mode.addItem("ON")
self.mode.currentIndexChanged.connect(self.mode_changed)
self.hbox = QtGui.QHBoxLayout()
self.hbox.addWidget(self.mode)
self.hbox.addWidget(self.sp_stack)
class tabdemo(QtGui.QTabWidget):
def __init__(self, parent = None):
super(tabdemo, self).__init__(parent)
self.tab1 = QtGui.QWidget()
self.tab2 = QtGui.QWidget()
self.tab3 = QtGui.QWidget()
self.addTab(self.tab1,"Tab 1")
self.addTab(self.tab2,"Tab 2")
self.addTab(self.tab3,"Tab 3")
self.tab1UI()
self.tab2UI()
self.tab3UI()
self.setWindowTitle("Heizung")
def tab1UI(self):
K1=Kaskade(28,5,40)
K2=Kaskade(30,5,40)
K3=Kaskade(35,5,40)
K1.mode.setCurrentIndex(1)
K3.mode.setCurrentIndex(1)
vbox = QtGui.QVBoxLayout()
vbox.addLayout(K1.hbox)
vbox.addLayout(K2.hbox)
vbox.addLayout(K3.hbox)
self.tab1.setLayout(vbox)
self.setTabText(1,"Tab1")
def tab2UI(self):
self.setTabText(1,"Tab2")
def tab3UI(self):
self.setTabText(2,"Tab3")
def main():
app = QtGui.QApplication(sys.argv)
ex = tabdemo()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You must add Kaskade to vbox in Tab 1, not the layout. In addition we must do self.hbox layout of Kaskade:
class Kaskade(QtGui.QWidget):
[...]
def hbox_gen(self):
[...]
self.hbox = QtGui.QHBoxLayout(self)
[...]
class tabdemo(QtGui.QTabWidget):
[...]
def tab1UI(self):
[...]
vbox = QtGui.QVBoxLayout()
vbox.addWidget(K1)
vbox.addWidget(K2)
vbox.addWidget(K3)
self.tab1.setLayout(vbox)
[...]
I want to create the GUI with this code. When i click Add New Object Button, it will show the pop up (I use QMainWindown) but i want to put the QLabel in here, it can not work
I dont know why.i hope everyone can give me more some advices. Thanks you
This is my code :
from PySide import QtCore, QtGui
import sys
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication([])
class Window(QtGui.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.mainLayout = QtGui.QGridLayout()
self.mainLayout.addWidget(self.First(), 0, 0, 2, 0)
self.setLayout(self.mainLayout)
self.setWindowTitle("Library")
self.resize(700,660)
#----------------------------------------FIRST COLUMN-------------------------------------
def First(self):
FirstFrame = QtGui.QFrame()
FirstFrame.setFixedSize(230,700)
# LABEL
renderer_lb = QtGui.QLabel("Renderer :")
folders_lb = QtGui.QLabel("Folder :")
#COMBOBOX
self.renderer_cbx = QtGui.QComboBox()
self.renderer_cbx.addItem("Vray")
self.renderer_cbx.addItem("Octane")
# LIST VIEW FOLDER
self.folders_lv = QtGui.QListView()
# BUTTON
addnewobject_btn = QtGui.QPushButton("Add New Objects")
newset_btn = QtGui.QPushButton("New Set")
# DEFINE THE FUNCTION FOR FIRST FRAME
Firstbox = QtGui.QGridLayout()
Firstbox.addWidget(renderer_lb,0,0)
Firstbox.addWidget(folders_lb,2,0,1,4)
Firstbox.addWidget(self.renderer_cbx,0,1,1,3)
Firstbox.addWidget(self.folders_lv,3,0,1,4)
Firstbox.addWidget(addnewobject_btn,4,0,1,2)
Firstbox.addWidget(newset_btn,4,3)
Firstbox.setColumnStretch(1, 1)
FirstFrame.setLayout(Firstbox)
addnewobject_btn.clicked.connect(self.addnewobject)
return FirstFrame
def addnewobject(self):
window = QtGui.QMainWindow(self)
window.setWindowTitle('Select folder of new objects')
window.setFixedSize(450,90)
window.show()
folder_lb = QtGui.QLabel("Folder : ")
browser = QtGui.QGridLayout()
browser.addWidget(folder_lb,0,0)
window.setLayout(browser)
if __name__ == '__main__':
window = Window()
sys.exit(window.exec_())
Just as you did in the First() function, you could create an homemade widget using QFrame. Then you can set a central widget for your new window.
from PySide import QtCore, QtGui
import sys
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication([])
class Window(QtGui.QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.mainLayout = QtGui.QGridLayout()
self.mainLayout.addWidget(self.First(), 0, 0, 2, 0)
self.setLayout(self.mainLayout)
self.setWindowTitle("Library")
self.resize(700,660)
self.show()
#----------------------------------------FIRST COLUMN-------------------------------------
def First(self):
FirstFrame = QtGui.QFrame()
FirstFrame.setFixedSize(230,700)
# LABEL
renderer_lb = QtGui.QLabel("Renderer :")
folders_lb = QtGui.QLabel("Folder :")
#COMBOBOX
self.renderer_cbx = QtGui.QComboBox()
self.renderer_cbx.addItem("Vray")
self.renderer_cbx.addItem("Octane")
# LIST VIEW FOLDER
self.folders_lv = QtGui.QListView()
# BUTTON
addnewobject_btn = QtGui.QPushButton("Add New Objects")
newset_btn = QtGui.QPushButton("New Set")
# DEFINE THE FUNCTION FOR FIRST FRAME
Firstbox = QtGui.QGridLayout()
Firstbox.addWidget(renderer_lb,0,0)
Firstbox.addWidget(folders_lb,2,0,1,4)
Firstbox.addWidget(self.renderer_cbx,0,1,1,3)
Firstbox.addWidget(self.folders_lv,3,0,1,4)
Firstbox.addWidget(addnewobject_btn,4,0,1,2)
Firstbox.addWidget(newset_btn,4,3)
Firstbox.setColumnStretch(1, 1)
FirstFrame.setLayout(Firstbox)
addnewobject_btn.clicked.connect(self.addnewobject)
return FirstFrame
def addnewobject(self):
secondFrame = QtGui.QFrame()
secondFrame.setFixedSize(230,700)
# LABEL
folders_lb = QtGui.QLabel("Folder :")
# DEFINE THE FUNCTION FOR FIRST FRAME
secondGridLayout = QtGui.QGridLayout()
secondGridLayout.addWidget(folders_lb,2,0,1,4)
secondGridLayout.setColumnStretch(1, 1)
secondFrame.setLayout(secondGridLayout)
window = QtGui.QMainWindow(self)
window.setWindowTitle('Select folder of new objects')
window.setFixedSize(600,700)
window.setCentralWidget(secondFrame) # Here is the main change: setLayout(QLayout) to setCentralWidget(QWidget)
window.show()
if __name__ == '__main__':
window = Window()
sys.exit(window.exec_())
Is this intended for Maya? If yes, I recommand you not to use modal windows as it will quickly fed up the users.
I am trying to add tab for 2 grid layout, but when I ran the code it seems like there is no tab.
I think
wid_inner.tab = QtGui.QTabWidget()
is not adding the tab correctly to the grid
import sys
from PySide import QtGui
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
# setting the outter widget and layout
wid = QtGui.QWidget()
grid = QtGui.QGridLayout()
wid.setLayout(grid)
# setting the inner widget and layout
grid_inner = QtGui.QGridLayout()
wid_inner = QtGui.QWidget()
wid_inner.setLayout(grid_inner)
# add the inner widget to the outer layout
grid.addWidget(wid_inner)
# add tab frame to widget
wid_inner.tab = QtGui.QTabWidget()
# create tab
new_tab = QtGui.QWidget()
grid_tab = QtGui.QGridLayout()
grid_tab.setSpacing(10)
new_tab.setLayout(grid_tab)
new_tab.tab_name_private = "test1"
wid_inner.tab.addTab(new_tab, "test1")
# create tab 2
new_tab2 = QtGui.QWidget()
new_tab2.setLayout(grid_tab)
wid_inner.tab.addTab(new_tab2, "test2")
wid.show()
sys.exit(app.exec_())
Any help would be appreciated thanks
You need to provide the parent to each inner widget, and the tab widget wid_inner.tab was not being added to any layout. This seems a little complicated to establish the layout... Have you considered using QtDesigner?
wid = QtGui.QWidget()
grid = QtGui.QGridLayout(wid)
wid.setLayout(grid)
# setting the inner widget and layout
grid_inner = QtGui.QGridLayout(wid)
wid_inner = QtGui.QWidget(wid)
wid_inner.setLayout(grid_inner)
# add the inner widget to the outer layout
grid.addWidget(wid_inner)
# add tab frame to widget
wid_inner.tab = QtGui.QTabWidget(wid_inner)
grid_inner.addWidget(wid_inner.tab)
# create tab
new_tab = QtGui.QWidget(wid_inner.tab)
grid_tab = QtGui.QGridLayout(new_tab)
grid_tab.setSpacing(10)
new_tab.setLayout(grid_tab)
new_tab.tab_name_private = "test1"
wid_inner.tab.addTab(new_tab, "test1")
# create tab 2
new_tab2 = QtGui.QWidget(wid_inner.tab)
new_tab2.setLayout(grid_tab)
wid_inner.tab.addTab(new_tab2, "test2")
wid.show()
app.exec_()