I wrote the following code in order to do some calculations. I want to add a Widget like the small picture such that when I click on pushbutton I can browse a CSV file and that path is shown in a LineEdite. I need to have this Widger in the Experiment Info QGroupBox below the checkBox. But I do not know how to add all these 3 Widget in one row in this group box.
import sys
from PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplication
from PyQt5 import QtGui, QtCore
from PyQt5 import QtWidgets
class Application(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
menubar = self.menuBar()
fileMenu = menubar.addMenu('File')
run = menubar.addMenu('Run')
exit = menubar.addMenu('Exit')
impMenu = QMenu('Import', self)
impAct = QAction('Import mail', self)
impMenu.addAction(impAct)
newAct = QAction('New', self)
fileMenu.addAction(newAct)
fileMenu.addMenu(impMenu)
# ------------- Layout ---------------------------
wid =QtWidgets.QWidget(self)
self.setCentralWidget(wid)
mainLayout = QtWidgets.QVBoxLayout()
config_box = QtWidgets.QGroupBox("Configuration")
info_box = QtWidgets.QGroupBox("Info Box")
# ------------- Config Box Layut -----------------
Config_Box_Layout = QtWidgets.QGridLayout()
case_box = QtWidgets.QGroupBox("case")
operations_box = QtWidgets.QGroupBox("Operations")
Config_Box_Layout.addWidget(case_box, 0, 0)
Config_Box_Layout.addWidget(operations_box, 0, 1)
# ----------- Operations-----------------------
operation_layout = QtWidgets.QVBoxLayout()
op1 = QtWidgets.QCheckBox('Add')
op2= QtWidgets.QCheckBox('Multiplication')
operation_layout.addWidget(op1)
operation_layout.addWidget(op2)
# ----------- cases -----------------------
case_layout = QtWidgets.QVBoxLayout()
_1 = QtWidgets.QRadioButton("1")
_2 = QtWidgets.QRadioButton("2")
_3 = QtWidgets.QRadioButton("3")
case_layout.addWidget(_1)
case_layout.addWidget(_2)
case_layout.addWidget(_3)
# --------- Info Box LayOut -----------------------
Info_box_layout = QtWidgets.QVBoxLayout()
exp_input_grou = QtWidgets.QGroupBox('Experiment Info')
exp_input_layout = QtWidgets.QVBoxLayout()
version_input = QtWidgets.QComboBox()
version_input.addItem("Algo Version")
version_input.addItem("V53")
version_input.addItem("V52")
version_input.addItem("V4")
version_input.addItem("V3")
nested_folder = QtWidgets.QCheckBox('Nested Data Path')
dialog_file = QtWidgets.QFileDialog()
pushB_ = QtWidgets.QPushButton('Browse')
exp_input_layout.addWidget(version_input)
exp_input_layout.addWidget(nested_folder)
exp_input_layout.addWidget(pushB_)
exp_input_layout.addWidget(dialog_file)
exp_report = QtWidgets.QTextEdit()
progres_bar = QtWidgets.QProgressBar()
Info_box_layout.addWidget(exp_input_grou)
Info_box_layout.addWidget(exp_report)
Info_box_layout.addWidget(progres_bar)
gt_path = QtWidgets.QLineEdit()
gt_path.setFixedWidth(100)
# -------- Adding Layouts ------------------------
mainLayout.addWidget(config_box)
config_box.setLayout(Config_Box_Layout)
case_box.setLayout(case_layout)
operations_box.setLayout(operation_layout)
info_box.setLayout(Info_box_layout)
exp_input_grou.setLayout(exp_input_layout)
mainLayout.addWidget(info_box)
wid.setLayout(mainLayout)
self.setGeometry(300, 300, 300, 700)
self.setWindowTitle('Example')
app_icon = QtGui.QIcon()
app_icon.addFile('pic.jpg', QtCore.QSize(256, 256))
self.setWindowIcon(app_icon)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Application()
sys.exit(app.exec_())
If you want to add widgets horizontally in a vertical layout, you have to add an horizontal layout to it. This technique is generally referred to as "nested layouts".
Then, you don't have to create a file dialog instance within the init (otherwise it will be probably shown along with the main window), and you don't have to use the QFileDialog() constructor for your needs, since QDialog already provides static methods that easily allow you to open a standard dialog and get the selected file(s) or directory.
class Application(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# ...
# --------- Info Box LayOut -----------------------
Info_box_layout = QtWidgets.QVBoxLayout()
exp_input_grou = QtWidgets.QGroupBox('Experiment Info')
exp_input_layout = QtWidgets.QVBoxLayout()
version_input = QtWidgets.QComboBox()
version_input.addItem("Algo Version")
version_input.addItem("V53")
version_input.addItem("V52")
version_input.addItem("V4")
version_input.addItem("V3")
nested_folder = QtWidgets.QCheckBox('Nested Data Path')
# This should not be here!!!
# dialog_file = QtWidgets.QFileDialog()
exp_input_layout.addWidget(version_input)
exp_input_layout.addWidget(nested_folder)
browse_layout = QtWidgets.QHBoxLayout()
exp_input_layout.addLayout(browse_layout)
self.gt_path = QtWidgets.QLineEdit()
pushB_ = QtWidgets.QPushButton('Browse')
pushB_.clicked.connect(self.browse_path)
browse_layout.addWidget(self.gt_path)
browse_layout.addWidget(pushB_)
# ...
def browse_path(self):
path, filter = QtWidgets.QFileDialog.getOpenFileName(self, 'Select file',
'', 'CSV files (*.csv);;All files (*)')
if path:
self.gt_path.setText(path)
QGridLayout is also a valid alternative, but it doesn't work fine with everything, as its sizes are always dependent on the size of widgets each row or column contains. Your case is very simple, so it can be used without problems:
def initUI(self):
# ...
# --------- Info Box LayOut -----------------------
Info_box_layout = QtWidgets.QVBoxLayout()
exp_input_grou = QtWidgets.QGroupBox('Experiment Info')
exp_input_layout = QtWidgets.QGridLayout()
version_input = QtWidgets.QComboBox()
version_input.addItem("Algo Version")
version_input.addItem("V53")
version_input.addItem("V52")
version_input.addItem("V4")
version_input.addItem("V3")
nested_folder = QtWidgets.QCheckBox('Nested Data Path')
self.gt_path = QtWidgets.QLineEdit()
pushB_ = QtWidgets.QPushButton('Browse')
pushB_.clicked.connect(self.browse_path)
# add the combobox to the first row, first column, but set its column
# span to 2, meaning that it occupies two "columns"
exp_input_layout.addWidget(version_input, 0, 0, 1, 2)
# the same for the checkbox, but on the second row
exp_input_layout.addWidget(nested_folder, 1, 0, 1, 2)
# add the line edit, third row, first column; if you don't specify the
# span, the widget will only occupy one "cell" of the grid layout
exp_input_layout.addWidget(self.gt_path, 2, 0)
# and the button, same row, second column
exp_input_layout.addWidget(pushB_, 2, 1)
# ...
The below code will do what you want, you just need to implement it into your code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(387, 224)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setReadOnly(True)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.open_file)
self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.gridLayout.addWidget(self.pushButton, 0, 2, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 387, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Select output file"))
self.pushButton.setText(_translate("MainWindow", "..."))
def open_file(self):
self.file_name = QtWidgets.QFileDialog.getOpenFileName(None, "Open", "", "CSV Files (*.csv)")
if self.file_name[0] != '':
self.lineEdit.setText(self.file_name[0])
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Output:
Related
I am creating a program that has the function that a checkbox is deleted when it toggled. But when I click the delete button it is not deleted from my scroll area.
I have tried some solutions, but I still have problems on it. An the below code is the best condition I managed until now.
# -*- coding: utf-8 -*-
import sys
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(300, 495)
MainWindow.setMaximumSize(QtCore.QSize(300, 16777215))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.frame_3 = QtWidgets.QFrame(self.centralwidget)
self.frame_3.setMaximumSize(QtCore.QSize(500, 50))
self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_3.setObjectName("frame_3")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label = QtWidgets.QLabel(self.frame_3)
self.label.setObjectName("label")
self.horizontalLayout_2.addWidget(self.label)
self.verticalLayout.addWidget(self.frame_3)
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.scrollArea = QtWidgets.QScrollArea(self.frame)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 260, 357))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.frame_4 = QtWidgets.QFrame(self.scrollAreaWidgetContents)
self.frame_4.setFrameShape(QtWidgets.QFrame.NoFrame)
self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_4.setObjectName("frame_4")
self.verticalLayout_3.addWidget(self.frame_4)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.verticalLayout_2.addWidget(self.scrollArea)
self.verticalLayout.addWidget(self.frame)
self.frame_2 = QtWidgets.QFrame(self.centralwidget)
self.frame_2.setMaximumSize(QtCore.QSize(500, 50))
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_2)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(self.frame_2)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.pushButton_2 = QtWidgets.QPushButton(self.frame_2)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.verticalLayout.addWidget(self.frame_2)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "MainWindow", None, -1))
self.label.setText(QtWidgets.QApplication.translate("MainWindow", "Chose Number", None, -1))
self.pushButton.setText(QtWidgets.QApplication.translate("MainWindow", "add", None, -1))
self.pushButton_2.setText(QtWidgets.QApplication.translate("MainWindow", "remove", None, -1))
class Remove_checkBox(QtWidgets.QMainWindow,
Ui_MainWindow):
def __init__(self,n):
super(Remove_checkBox, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.checkBox = []
self.fill_comboBox(n)
#Signals
self.ui.pushButton.clicked.connect(lambda: self.add_param())
self.ui.pushButton_2.clicked.connect(lambda: self.remove_param())
def fill_comboBox(self,n):
self.comboBox = QtWidgets.QComboBox(self.ui.frame_3)
self.comboBox.addItem("")
self.comboBox.setItemText(0, QtWidgets.QApplication.translate("MainWindow", "", None, -1))
self.ui.horizontalLayout_2.addWidget(self.comboBox)
for i in range(n):
self.comboBox.addItem("")
self.comboBox.setItemText(i+1, QtWidgets.QApplication.translate("MainWindow", str(i), None, -1))
def add_param(self):
num = self.comboBox.currentText()
self.checkBox.append(QtWidgets.QCheckBox(self.ui.scrollAreaWidgetContents))
self.ui.verticalLayout_3.addWidget(self.checkBox[-1])
self.checkBox[-1].setText(QtWidgets.QApplication.translate("MainWindow", num, None, -1))
self.ui.verticalLayout_3.removeWidget(self.ui.frame_4)
self.ui.verticalLayout_3.addWidget(self.ui.frame_4)
def remove_param(self):
for i in range(len(self.checkBox)):
if self.checkBox[i].isChecked():
self.ui.verticalLayout_3.removeWidget(self.checkBox[i])
self.ui.verticalLayout_3.removeWidget(self.ui.frame_4)
self.ui.verticalLayout_3.addWidget(self.ui.frame_4)
if __name__ == "__main__":
n=10
app = QtWidgets.QApplication.instance()
if app == None:
app = QtWidgets.QApplication([])
myApp = Remove_checkBox(n)
myApp.show()
sys.exit(app.exec_())
It took me a while to find a solution that worked with my issue, but I finally arrived to the solution below presented, based on: What is best way to remove items from layout in pyqt
def remove_element(self, support_layout, element_to_remove, control_list_name):
"""
This function aims to remove selected elements that are contained in a
widget.
Parameters
----------
support_layout : QtWigget Layout
Layout that supports the object that will be removed
element_to_remove : list with QtWidget
A list with Qtwidget items that ones whant to remove.
control_list_name : list with strings
A list with Qtwidget added items string name
Returns
-------
None.
"""
for i in reversed(range(support_layout.count()-1)):
if element_to_remove[i].isChecked():
# Remove checkbox from frame
item = support_layout.takeAt(i)
widget = item.widget()
widget.deleteLater()
# Remove list selected items
control_list_name.remove(element_to_remove[i].text())
element_to_remove.remove(element_to_remove[i])
With this function my problem was solved I am able to follow my project.
I wrote a script that automatically creates a QT "object" made up of a category label, a combobox_1 with possible attributes, a push button and a combobox_2 to list all values available for the attribute selected. the script creates as many of these "objects" as necessary.
For each "object" the push button created is meant to grab the selected attribute in combobox_1 and use this information to retrieve relevant values from the database and populate combobx_2
Now the problem I have is that I can't figure out how to reference the comboboxes once they have been created. For the buttons, I use the serve function which listen to any button for a click so that's fine, but how can I reference combobox that have been created with a function. Although they all have different setObjectName, there doesn't seem to be a way of referencing that attribute so when I click on any button they all return the value of the last object's combobox instead of the value of its related comboxbox to which they are attached.
here is the Frontend script:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(709, 357)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.gridLayout_4 = QtWidgets.QGridLayout()
self.gridLayout_4.setObjectName("gridLayout_4")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_4.addItem(spacerItem, 1, 1, 1, 1)
self.VLayout_0 = QtWidgets.QVBoxLayout()
self.VLayout_0.setObjectName("VLayout_0")
self.HLayout_0 = QtWidgets.QHBoxLayout()
self.HLayout_0.setObjectName("HLayout_0")
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
self.HLayout_0.addItem(spacerItem1)
self.CB_L0 = QtWidgets.QComboBox(self.centralwidget)
self.CB_L0.setObjectName("CB_L0")
self.HLayout_0.addWidget(self.CB_L0)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
self.pushButton.setMaximumSize(QtCore.QSize(40, 16777215))
self.pushButton.setObjectName("pushButton")
self.HLayout_0.addWidget(self.pushButton)
spacerItem2 = QtWidgets.QSpacerItem(50, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
self.HLayout_0.addItem(spacerItem2)
self.VLayout_0.addLayout(self.HLayout_0)
spacerItem3 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
self.VLayout_0.addItem(spacerItem3)
self.gridLayout_4.addLayout(self.VLayout_0, 1, 0, 1, 1)
self.PB_create_cb = QtWidgets.QPushButton(self.centralwidget)
self.PB_create_cb.setObjectName("PB_create_cb")
self.gridLayout_4.addWidget(self.PB_create_cb, 0, 1, 1, 1)
self.gridLayout.addLayout(self.gridLayout_4, 0, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 709, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "search"))
self.PB_create_cb.setText(_translate("MainWindow", "Create dropdown"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
and here is the backend example (which creates two "objects"):
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QAction, QTableWidget, QTableWidgetItem, QVBoxLayout, QMessageBox, QDialog, QLineEdit, QPushButton, QMenu, QSizePolicy, QLabel,QTreeWidget,QTreeWidgetItem
from PyQt5.QtWidgets import (QApplication, QWidget, QToolTip, QPushButton, QMessageBox)
import sys
from test3 import *
class Run_script(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Run_script, self).__init__(parent)
self.setupUi(self)
print("Run script initizalised")
self.PB_create_cb.clicked.connect(self.click_select)
def create_V_0_object(self,List_attributes):
V_list = []
for i,x in enumerate(List_attributes):
for k,v in x.items():
if type(v) == dict:
for k1,v1 in v.items():
if type(v) == dict:
self.HLayout_1 = QtWidgets.QHBoxLayout()
self.HLayout_1.setObjectName("H_layout_1")
self.VLayout_0 = QtWidgets.QVBoxLayout()
self.VLayout_0.setObjectName("V_L2"+k+str(i))
self.Attr_label = QtWidgets.QLabel(self.centralwidget)
self.Attr_label.setObjectName(k)
self.Attr_label.setText(k)
self.VLayout_0.addWidget(self.Attr_label)
self.attr_list = []
for k1,v1 in v.items():
self.attr_list.append(k1)
print("K1 is "+str(k1))
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setObjectName("CB_"+k)
self.comboBox.addItems(self.attr_list)
self.comboBox.setToolTip("CB_"+k)
self.VLayout_0.addWidget(self.comboBox)
self.comboBox1 = QtWidgets.QComboBox(self.centralwidget)
self.comboBox1.setObjectName("CB_l2_"+k)
self.comboBox1.setToolTip("CB_l2_"+k)
self.VLayout_0.addWidget(self.comboBox1)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
self.pushButton.setMaximumSize(QtCore.QSize(40, 16777215))
PB_name = "PB_"+str(k)
self.pushButton.setObjectName(PB_name)
self.pushButton.setToolTip("Search " + str(PB_name))
self.pushButton.setText(PB_name)
self.pushButton.clicked.connect(self.buttonClicked)
self.HLayout_1.addLayout(self.VLayout_0)
self.HLayout_1.addWidget(self.pushButton)
else:
pass
V_list.append(self.HLayout_1)
return V_list
def buttonClicked(self):
sender = self.sender()
cat_l_0 = sender.text()
for i in range(self.VLayout_0.count()):
name = self.VLayout_0.itemAt(i).widget().objectName()
print("this is:",name)
def click_select(self):
self.selection = [{"Category1":{"Attr1": "test1","Attr2":"test2"}},{"Category2":{"Attr1":"test3","Attr2":"test4"}}]
self.v = self.create_V_0_object(self.selection)
self.create_horizontal_display(self.v)
def deleteItemsOfLayout(self,layout):
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.setParent(None)
else:
self.deleteItemsOfLayout(item.layout())
def create_horizontal_display(self,vertical_layout_list):
self.deleteItemsOfLayout(self.HLayout_0)
for i,x in enumerate(vertical_layout_list):
self.HLayout_0.addLayout(x)
if __name__ == '__main__':
app = QApplication(sys.argv)
prog = Run_script()
prog.show()
sys.exit(app.exec_())
to create the objects just press the "create dropdown" button
You have many bad practices:
The variables that are created in a loop are generally not going to be a member of the class because they are temporary variables, so do not use them as they will be overwritten, therefore when accessing self.VLayout_0 you will always get the last element.
Another bad habit is that everything you want to do in one place, as you say the "object" s are similar except for the data so you should create a class that builds it, as they say: divide and conquer.
You have other errors but they are minor, correcting the above you have the following:
from PyQt5 import QtCore, QtGui, QtWidgets
from test3 import Ui_MainWindow
class Widget(QtWidgets.QWidget):
clicked = QtCore.pyqtSignal()
def __init__(self, text, values, parent=None):
super(Widget, self).__init__(parent)
hlay = QtWidgets.QHBoxLayout(self)
vlay = QtWidgets.QVBoxLayout()
self.label = QtWidgets.QLabel(text)
self.combobox_1 = QtWidgets.QComboBox()
self.combobox_1.addItems(values.keys())
self.combobox_2 = QtWidgets.QComboBox()
vlay.addWidget(self.label)
vlay.addWidget(self.combobox_1)
vlay.addWidget(self.combobox_2)
hlay.addLayout(vlay)
self.button = QtWidgets.QPushButton(text)
self.button.clicked.connect(self.clicked)
hlay.addWidget(self.button)
self.setFixedSize(self.sizeHint())
class Run_script(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Run_script, self).__init__(parent)
self.setupUi(self)
print("Run script initizalised")
self.PB_create_cb.clicked.connect(self.click_select)
def create_V_0_object(self, attributes):
v_list = []
for x in attributes:
for key, value in x.items():
w = Widget(key, value)
w.clicked.connect(self.buttonClicked)
v_list.append(w)
return v_list
def buttonClicked(self):
w = self.sender()
print(w.combobox_1.currentText())
print(w.combobox_2.currentText())
print(w.label.text())
print(w.button.text())
def click_select(self):
selection = [{"Category1":{"Attr1": "test1","Attr2":"test2"}},{"Category2":{"Attr1": "test3", "Attr2": "test4"}}]
v = self.create_V_0_object(selection)
self.create_horizontal_display(v)
def deleteItemsOfLayout(self,layout):
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.setParent(None)
else:
self.deleteItemsOfLayout(item.layout())
def create_horizontal_display(self, vertical_layout_list):
self.deleteItemsOfLayout(self.HLayout_0)
for i, x in enumerate(vertical_layout_list):
self.HLayout_0.addWidget(x)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
prog = Run_script()
prog.show()
sys.exit(app.exec_())
For example When I open the app to show me one form, when I click the button show second form that will contain the data entry fields
Home
Second form
There are several ways to achieve what you want. Easiest (not cleanest) is to group the widgets in your "forms" into containers (QFrame, QGroupbox, etc) and connect the triggered signal from your actions into suitable slots that hide/show these containers. Below you can see an example (PySide) of this, on which I'm using two QFrames in order to separate your "forms". The layout behaviour can be modified easily.
The form file (compiled from the designer's ui file):
# Form implementation generated from reading ui file 'example.ui'
#
# Created: Tue Apr 10 13:18:07 2018
# by: pyside-uic 0.2.15 running on PySide 1.2.4
#
# WARNING! All changes made in this file will be lost!
from PySide import QtCore, QtGui
class Ui_Example(object):
def setupUi(self, Example):
Example.setObjectName("Example")
Example.resize(800, 770)
self.centralwidget = QtGui.QWidget(Example)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtGui.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.fr_one = QtGui.QFrame(self.centralwidget)
self.fr_one.setFrameShape(QtGui.QFrame.StyledPanel)
self.fr_one.setFrameShadow(QtGui.QFrame.Raised)
self.fr_one.setObjectName("fr_one")
self.verticalLayout_2 = QtGui.QVBoxLayout(self.fr_one)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.bt_quit = QtGui.QPushButton(self.fr_one)
self.bt_quit.setObjectName("bt_quit")
self.verticalLayout_2.addWidget(self.bt_quit)
self.cb_selection = QtGui.QComboBox(self.fr_one)
self.cb_selection.setObjectName("cb_selection")
self.verticalLayout_2.addWidget(self.cb_selection)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem)
self.gridLayout.addWidget(self.fr_one, 0, 0, 1, 1)
self.fr_two = QtGui.QFrame(self.centralwidget)
self.fr_two.setFrameShape(QtGui.QFrame.StyledPanel)
self.fr_two.setFrameShadow(QtGui.QFrame.Raised)
self.fr_two.setObjectName("fr_two")
self.verticalLayout_5 = QtGui.QVBoxLayout(self.fr_two)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtGui.QLabel(self.fr_two)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.le_fname = QtGui.QLineEdit(self.fr_two)
self.le_fname.setObjectName("le_fname")
self.verticalLayout.addWidget(self.le_fname)
self.verticalLayout_5.addLayout(self.verticalLayout)
self.verticalLayout_3 = QtGui.QVBoxLayout()
self.verticalLayout_3.setSpacing(0)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.label_2 = QtGui.QLabel(self.fr_two)
self.label_2.setObjectName("label_2")
self.verticalLayout_3.addWidget(self.label_2)
self.le_sname = QtGui.QLineEdit(self.fr_two)
self.le_sname.setObjectName("le_sname")
self.verticalLayout_3.addWidget(self.le_sname)
self.verticalLayout_5.addLayout(self.verticalLayout_3)
self.verticalLayout_4 = QtGui.QVBoxLayout()
self.verticalLayout_4.setSpacing(0)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.label_3 = QtGui.QLabel(self.fr_two)
self.label_3.setObjectName("label_3")
self.verticalLayout_4.addWidget(self.label_3)
self.le_address = QtGui.QLineEdit(self.fr_two)
self.le_address.setObjectName("le_address")
self.verticalLayout_4.addWidget(self.le_address)
self.verticalLayout_5.addLayout(self.verticalLayout_4)
spacerItem1 = QtGui.QSpacerItem(20, 267, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout_5.addItem(spacerItem1)
self.gridLayout.addWidget(self.fr_two, 0, 1, 1, 1)
Example.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(Example)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 47))
self.menubar.setObjectName("menubar")
Example.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(Example)
self.statusbar.setObjectName("statusbar")
Example.setStatusBar(self.statusbar)
self.toolBar = QtGui.QToolBar(Example)
self.toolBar.setObjectName("toolBar")
Example.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionAction1 = QtGui.QAction(Example)
self.actionAction1.setObjectName("actionAction1")
self.actionAction2 = QtGui.QAction(Example)
self.actionAction2.setObjectName("actionAction2")
self.toolBar.addAction(self.actionAction1)
self.toolBar.addAction(self.actionAction2)
self.retranslateUi(Example)
QtCore.QMetaObject.connectSlotsByName(Example)
def retranslateUi(self, Example):
Example.setWindowTitle(QtGui.QApplication.translate("Example", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.bt_quit.setText(QtGui.QApplication.translate("Example", "Quit", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Example", "First name", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("Example", "Second name", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("Example", "Address", None, QtGui.QApplication.UnicodeUTF8))
self.toolBar.setWindowTitle(QtGui.QApplication.translate("Example", "toolBar", None, QtGui.QApplication.UnicodeUTF8))
self.actionAction1.setText(QtGui.QApplication.translate("Example", "action1", None, QtGui.QApplication.UnicodeUTF8))
self.actionAction2.setText(QtGui.QApplication.translate("Example", "action2", None, QtGui.QApplication.UnicodeUTF8))
The main file:
from PySide import QtGui, QtCore
from _example import Ui_Example
class Example(QtGui.QMainWindow):
def __init__(self, parent = None):
super(Example, self).__init__(parent)
self.ui = Ui_Example()
self.ui.setupUi(self)
self.ui.fr_two.setVisible(False)
self.ui.cb_selection.addItem("motif")
# here are the connections of the corresponding actions on the QToolBar
self.ui.actionAction1.triggered.connect(self._changeView1)
self.ui.actionAction2.triggered.connect(self._changeView2)
def _changeView1(self):
# fr_one is the first frame (the one that contains the 'quit' button and the QCombobox)
# fr_two is the second frame (the one that contains the QLineEdits)
self.ui.fr_one.setVisible(True)
self.ui.fr_two.setVisible(False)
def _changeView2(self):
self.ui.fr_one.setVisible(False)
self.ui.fr_two.setVisible(True)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
I would like to put a cursor in a blank line edit box without having to click on it.
I looked through the Reference here
http://ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/PyQt-x11-gpl-4.7.2/doc/html/qlineedit.html#selectionStart
I tried calling
QLineEdit.home(True)
But this did not select the lineEdit so to say.
here is a watered down version of the code
from PyQt4 import QtCore, QtGui
import sys
import os
import os.path
class Ui_Form1(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setupUi(self)
def setupUi(self, Form):
#init stuff
Form.setObjectName("Form")
Form.resize(794, 538)
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setObjectName("gridLayout")
self.hLayout = QtGui.QHBoxLayout(Form)
self.hLayout.setObjectName("hLayout")
self.vLayout = QtGui.QVBoxLayout(Form)
self.vLayout.setObjectName("vLayout")
#label for information
self.gridLayout.addLayout(self.hLayout, 0, 0)
self.hLayout.addLayout(self.vLayout, 0)
self.label = QtGui.QLabel(Form)
self.label.setObjectName("label")
#label pixmap
self.label2 = QtGui.QLabel(Form)
self.label2.setObjectName("label")
#line edit
self.lineEdit = QtGui.QLineEdit(Form)
self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
self.gridLayout.addWidget(self.lineEdit, 3,0)
self.list = QtGui.QListWidget(self)
self.list.setObjectName("outlist")
self.list.setMinimumHeight(150)
self.vLayout.addWidget(self.list, 1)
self.hLayout.addWidget(self.label, 1)
self.vLayout.addWidget(self.label2, 0)
#self.hLayout.addWidget(self.label2, 0)
self.label2.setText('line edit')
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setText('Picture would go here')
self.label2.setText('line edit')
self.list.addItem('cursor will disappear when this is pressed')
#press enter to update pic
#self.lineEdit.returnPressed.connect(self.update_pic)
#####sh
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = Ui_Form1()
ex.show()
sys.exit(app.exec_())
self.lineEdit.setFocus(QtCore.Qt.StrongFocus)
In PyQt5:
self.lineEdit.setFocus()
Why i can't receive self.sender() output? My point is to identify which button is clicked (to start a download function) and then match the corresponding progress bar for a downloading indicator.
The error output is:
Traceback (most recent call last):
File "final.py", line 308, in buttonClicked
buttonHandle = self.sender()
AttributeError: 'Ui_MainWindow' object has no attribute 'sender'
thnx a lot.
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.setGeometry(600,300,727,455)
MainWindow.setMinimumSize(QtCore.QSize(727, 455))
#MainWindow.setMaximumSize(QtCore.QSize(727, 455))
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 727, 23))
self.menubar.setObjectName(_fromUtf8("menubar"))
self.menuFile = QtGui.QMenu(self.menubar)
self.menuFile.setObjectName(_fromUtf8("menuFile"))
self.menuAbout = QtGui.QMenu(self.menubar)
self.menuAbout.setObjectName(_fromUtf8("menuAbout"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.actionExit = QtGui.QAction(MainWindow)
self.actionExit.setObjectName(_fromUtf8("actionExit"))
self.actionPythAri = QtGui.QAction(MainWindow)
self.actionPythAri.setObjectName(_fromUtf8("actionPythAri"))
self.menuFile.addAction(self.actionExit)
self.menuAbout.addAction(self.actionPythAri)
self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuAbout.menuAction())
# scrollArea
self.mainLayout = QtGui.QVBoxLayout()
self.scrollArea = QtGui.QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollAreaLayout = QtGui.QVBoxLayout()
#groupBoxes
self.groupBoxes = QtGui.QWidget()
self.groupBoxesLayout = QtGui.QVBoxLayout()
self.groupBoxes.setLayout(self.groupBoxesLayout)
self.groupBoxesLayout.setContentsMargins(5,5,5,5)
for i in range(3):
groupBox = QtGui.QGroupBox(_fromUtf8('Issue #%d' %i))
groupLayout = QtGui.QVBoxLayout()
#groupEllements
self.groupBoxUpWidget = QtGui.QWidget()
self.groupBoxUpLayout = QtGui.QHBoxLayout()
self.groupBoxDownWidget = QtGui.QWidget()
self.groupBoxDownLayout = QtGui.QHBoxLayout()
self.groupBoxUpWidget.setLayout(self.groupBoxUpLayout)
self.groupBoxDownWidget.setLayout(self.groupBoxDownLayout)
#mainwidget-temp
self.groupBoxMainWidget = QtGui.QWidget()
self.groupBoxMainLayout = QtGui.QVBoxLayout()
self.groupBoxMainWidget.setLayout(self.groupBoxMainLayout)
# ISSUE THUMB
self.issueThumb(self.groupBoxUpLayout)
#SETTING MAIN LAYOUT FOR EVERY GROUPBOX
groupBox.setLayout(groupLayout)
# text box
#self.txtLayout = QtGui.QHBoxLayout()
txt = QtGui.QLabel()
txt.setMaximumWidth(500)
txt.setText(_fromUtf8('Issue Description'))
#self.txtLayout.addWidget(self.txt)
#self.txt.setLayout(self.txtLayout)
#progressBars
progressBar = QtGui.QProgressBar()
progressBar.setMaximumWidth(500)
# controls
readBtn = QtGui.QPushButton(_fromUtf8('Read it!'),groupBox)
readBtn.setMaximumWidth(100)
#readBtn.setText()
readBtn.clicked.connect(self.buttonClicked)
# ADD EVERY WIDGET TO THE APPROPRIATE LAYOUT
self.groupBoxUpLayout.addWidget(txt)
self.groupBoxDownLayout.addWidget(readBtn)
self.groupBoxDownLayout.addWidget(progressBar)
# ADD PARENT WIDGETS TO MAIN GROUPBOX LAYOUT
groupLayout.addWidget(self.groupBoxUpWidget)
groupLayout.addWidget(self.groupBoxDownWidget)
groupLayout.addWidget(self.groupBoxMainWidget)
#ADD EVERY GROUPBOX TO A MAIN LAYOUT
self.groupBoxesLayout.addWidget(groupBox)
#self.scrollArea.setLayout(self.scrollAreaLayout)
self.scrollArea.setWidget(self.groupBoxes)
self.mainLayout.addWidget(self.scrollArea)
self.centralwidget.setLayout(self.mainLayout)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
authenticatedUser = False
authenticatedUser = self.authenticateDialog()
print authenticatedUser
if authenticatedUser == False:
sys.exit(0)
def buttonClicked(self):
buttonHandle = self.sender()
print buttonHandle
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui2 = Ui_MainWindow()
ui2.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
def buttonClicked(self):
buttonHandle = self.sender()
print buttonHandle
self here would be the Ui_MainWindow which is not a QT object, you probably want to check .sender of MainWindow. so set a class variable of UI_MainWindow to the MainWindow object and check sender of that object.
def setupUi(self, MainWindow):
self.MainWindow = MainWindow
....
def buttonClicked(self):
buttonHandle = self.MainWindow.sender()
print buttonHandle