I am a qt noob and I am trying to build an application that needs to display the following:
a list of e-mail (which I am displaying in column 1 of a grid layout
with a QListWidget1 left list)
a list of passwords (which I display in column 2 of grid layout in a QListWidget2 middle list)
Now, I would like to display a list of button (1 for every element of the list) which is supposed to copy the password in the QListWidget2.
Should I just loop in column 3 and add a push button for every row? Or is there a better way of doing this? Is there an object that could help me by laying out the buttons already in line with the elements of my list, so that I can connect them easily with the value of every entry in the list (for copying them later)?
My code is the following:
from PySide import QtCore, QtGui
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(311, 499)
self.gridLayoutWidget = QtGui.QWidget(Dialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 291, 371))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtGui.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
# self.dockWidget = QtGui.QDockWidget(self.gridLayoutWidget)
# self.dockWidget.setObjectName("dockWidget")
# self.dockWidgetContents = QtGui.QWidget()
# self.dockWidgetContents.setObjectName("dockWidgetContents")
# self.dockWidget.setWidget(self.dockWidgetContents)
# self.gridLayout.addWidget(self.dockWidget, 0, 0, 1, 1)
self.leftList = QtGui.QListWidget(self.gridLayoutWidget)
self.gridLayout.addWidget(self.leftList, 0, 0, 1, 1)
self.middleList = QtGui.QListWidget(self.gridLayoutWidget)
self.gridLayout.addWidget(self.middleList, 0, 1, 1, 1)
self.rightList = QtGui.QListWidget(self.gridLayoutWidget)
self.gridLayout.addWidget(self.rightList, 0, 2, 1, 1)
self.progressBar = QtGui.QProgressBar(Dialog)
self.progressBar.setGeometry(QtCore.QRect(10, 410, 231, 23))
self.progressBar.setInputMethodHints(QtCore.Qt.ImhNone)
self.progressBar.setMaximum(30)
self.progressBar.setProperty("value", 30)
self.progressBar.setInvertedAppearance(False)
self.progressBar.setTextDirection(QtGui.QProgressBar.TopToBottom)
self.progressBar.setObjectName("progressBar")
self.label = QtGui.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(240, 413, 51, 16))
self.label.setObjectName("label")
self.pushButton = QtGui.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(10, 440, 291, 51))
self.pushButton.setObjectName("pushButton")
self.line = QtGui.QFrame(Dialog)
self.line.setGeometry(QtCore.QRect(10, 390, 291, 20))
self.line.setFrameShape(QtGui.QFrame.HLine)
self.line.setFrameShadow(QtGui.QFrame.Sunken)
self.line.setObjectName("line")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.progressBar.setFormat(QtGui.QApplication.translate("Dialog", "%vs", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Dialog", "TimeOut", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Dialog", "Refresh", None, QtGui.QApplication.UnicodeUTF8))
If you want to add a button for each item in the list, you can use setItemWidget.
To get the buttons to align to the right, use a layout as in the demo script below:
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.list = QtGui.QListWidget(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.list)
def addListItem(self, text):
item = QtGui.QListWidgetItem(text)
self.list.addItem(item)
widget = QtGui.QWidget(self.list)
button = QtGui.QToolButton(widget)
layout = QtGui.QHBoxLayout(widget)
layout.setContentsMargins(0, 0, 0, 0)
layout.addStretch()
layout.addWidget(button)
self.list.setItemWidget(item, widget)
button.clicked[()].connect(
lambda: self.handleButtonClicked(item))
def handleButtonClicked(self, item):
print(item.text())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
for label in 'red blue green yellow purple'.split():
window.addListItem(label)
window.setGeometry(500, 300, 300, 200)
window.show()
sys.exit(app.exec_())
Related
I have made two GUIs in Pyqt5 & Qt Designer. The first GUI is to show the person name in a comboBox. The second GUI will be opend by clicking + button and then the user can write the name,age and job which i need later in other thing.
My Question is, how can i get the new name from the 2. GUI and set it in comboBox of the 1. GUI. I tried that in the below code but it doesn't work.
whole code:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(363, 165)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(30, 30, 68, 19))
self.label.setObjectName("label")
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setGeometry(QtCore.QRect(120, 30, 131, 25))
self.comboBox.setObjectName("comboBox")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(280, 30, 41, 34))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 363, 31))
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", "person"))
self.pushButton.setText(_translate("MainWindow", "+"))
def InputDialog1(self):
self.Dialog = QtWidgets.QDialog()
self.ui=Ui_Dialog()
self.ui.setupUi(self.Dialog)
self.Dialog.setWindowTitle('Add Infos')
self.Dialog.show()
class Person_data(object):
def __init__(self,parent=None):
self.Person_1 = {'-':[0,0]}
class MainWindow(QMainWindow, Ui_MainWindow,Person_data):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent=parent)
Person_data.__init__(self, parent=parent)
self.setupUi(self)
self.initMe()
def initMe(self):
self.pushButton.clicked.connect(self.InputDialog1)
Person_list={}
for i in self.Person_1.keys():
Person_list[i] = ''
Person_list_2 = list(Person_list)
print(Person_list_2)
self.comboBox.addItems(Person_list_2)
class Ui_Dialog(Person_data):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(344, 231)
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(170, 160, 112, 34))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(Dialog)
self.pushButton_2.setGeometry(QtCore.QRect(30, 160, 112, 34))
self.pushButton_2.setObjectName("pushButton_2")
self.gridLayoutWidget = QtWidgets.QWidget(Dialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(30, 20, 271, 121))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.lineEdit_2 = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.lineEdit_2.setObjectName("lineEdit_2")
self.gridLayout.addWidget(self.lineEdit_2, 1, 1, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
self.lineEdit_3 = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.lineEdit_3.setObjectName("lineEdit_3")
self.gridLayout.addWidget(self.lineEdit_3, 2, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
self.label = QtWidgets.QLabel(self.gridLayoutWidget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.pushButton.clicked.connect(self.okpress)
self.pushButton_2.clicked.connect(Dialog.close)
def okpress(self):
aa1=float(self.lineEdit_2.text());aa2=float(self.lineEdit_3.text())
self.Person_1[str(self.lineEdit.text())] = [aa1,aa2]
i = True
while i == True:
bb = MainWindow()
Person_list={}
for i in self.Person_1.keys():
Person_list[i] = ''
Person_list_2 = list(Person_list)
print(Person_list_2)
bb.comboBox.addItems(Person_list_2)
i=False #just to exit while
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "add"))
self.pushButton_2.setText(_translate("Dialog", "Cancel"))
self.label_2.setText(_translate("Dialog", "Age"))
self.label_3.setText(_translate("Dialog", "Job"))
self.label.setText(_translate("Dialog", "Name"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.setWindowTitle('Main Person Windows')
w.show()
sys.exit(app.exec_())
It is not recommended that you modify the code generated by Qt Designer, since you can have unexpected behaviors, in addition to messing up the code. The appropriate thing from my perspective is to create classes that inherit from the appropriate widgets and that use the design of QtDesigner, so my answer includes the restructuring of the code to make it more readable.
Analyzing in your code I see that you confuse the inheritance with the idea of sharing data, when it is inherited from a class it creates similar but not equal elements in each class, even though each object of those classes create similar objects among them but they are not the same , are not the same variables so they point to different memory space, in your case you think that as Ui_Dialog and MainWindow inherit from Person_data, then the variables Person_1 in both classes are the same, and in reality it is not.
Another problem that your code has is the validation, one must try that the user places appropriate values and must interact with certain elements when necessary, for example the conversion to float can cause problems if the text is empty or is not a number, also the add button should only be enabled if all fields are filled in properly, for this Qt provides classes such as QIntValidator.
QDialog is a class specialized in forms and we should try as much as possible to use exec_() since it returns if the form is accepted or not, but for this you must use the accept and reject methods when the buttons are appropriate.
Code:
class PersonDialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, *args, **kwargs):
QtWidgets.QDialog.__init__(self, *args, **kwargs)
self.setupUi(self)
self.pushButton.clicked.connect(self.accept)
self.pushButton_2.clicked.connect(self.reject)
self.lineEdit_3.setValidator(QtGui.QIntValidator(0, 100))
self.lineEdit.textChanged.connect(self.enableButtonAccept)
self.lineEdit_2.textChanged.connect(self.enableButtonAccept)
self.lineEdit_3.textChanged.connect(self.enableButtonAccept)
self.enableButtonAccept()
def enableButtonAccept(self):
if self.lineEdit.text() != "" and self.lineEdit_2.text() != "" and self.lineEdit_3.text() != "":
self.pushButton.setEnabled(True)
else:
self.pushButton.setEnabled(False)
def getPerson(self):
values = self.lineEdit.text(), self.lineEdit_2.text(), int(self.lineEdit_3.text())
self.lineEdit.clear()
self.lineEdit_2.clear()
self.lineEdit_3.clear()
return values
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
self.Person_1 = {}
self.initMe()
def initMe(self):
self.personDialog = PersonDialog(self)
self.pushButton.clicked.connect(self.InputDialog1)
def InputDialog1(self):
if self.personDialog.exec_() == PersonDialog.Accepted:
name, job, edad = self.personDialog.getPerson()
self.Person_1[name] = [job, edad]
self.comboBox.addItem(name)
I'm trying to create checkbox, frame, and grid layout objects and store them in their own list.
The output from Qt Designer looks like:
Essentially, I want to create Checkbox1, then create a frame and grid layout to store Checkbox2 and Checkbox3.
My approach was to first create an empty list to store the objects I'm creating:
checkboxList = []
Then to append it with a call to create the appropriate object checkboxList.append(CreateCheckBox(self.frame_main, self.gridLayout_main, 0, 'Checkbox 1') (for example)
This produces the output:
The frame I created isn't visible!
I'm guessing there are a few possible reasons for this:
I'm creating the classes incorrectly
I'm storing the objects I created incorrectly (i.e. init doesn't return anything so I'm not actually storing anything?)
I'm not adding my objects to the main frame properly so they're not showing up
Why isn't my class implementation working like the code from Qt Designer and what/how do I make the changes to get a similar output?
The code imported from Qt Designer looks like this:
from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(494, 210)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame_main = QtGui.QFrame(self.centralwidget)
self.frame_main.setGeometry(QtCore.QRect(20, 10, 435, 141))
self.frame_main.setFrameShape(QtGui.QFrame.StyledPanel)
self.frame_main.setFrameShadow(QtGui.QFrame.Raised)
self.frame_main.setObjectName("frame_main")
self.gridLayout_2 = QtGui.QGridLayout(self.frame_main)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setSpacing(0)
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout_main = QtGui.QGridLayout()
self.gridLayout_main.setSpacing(0)
self.gridLayout_main.setObjectName("gridLayout_main")
self.frame2 = QtGui.QFrame(self.frame_main)
self.frame2.setFrameShape(QtGui.QFrame.StyledPanel)
self.frame2.setFrameShadow(QtGui.QFrame.Raised)
self.frame2.setObjectName("frame2")
self.gridLayout_16 = QtGui.QGridLayout(self.frame2)
self.gridLayout_16.setContentsMargins(0, 0, 0, 0)
self.gridLayout_16.setObjectName("gridLayout_16")
self.gridLayout2 = QtGui.QGridLayout()
self.gridLayout2.setObjectName("gridLayout2")
spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
self.gridLayout2.addItem(spacerItem, 0, 0, 1, 1)
self.checkBox2 = QtGui.QCheckBox(self.frame2)
self.checkBox2.setObjectName("checkBox2")
self.gridLayout2.addWidget(self.checkBox2, 0, 1, 1, 1)
self.checkBox3 = QtGui.QCheckBox(self.frame2)
self.checkBox3.setObjectName("checkBox3")
self.gridLayout2.addWidget(self.checkBox3, 1, 1, 1, 1)
self.gridLayout_16.addLayout(self.gridLayout2, 0, 0, 1, 1)
self.gridLayout_main.addWidget(self.frame2, 1, 1, 1, 1)
self.checkBox1 = QtGui.QCheckBox(self.frame_main)
self.checkBox1.setObjectName("checkBox1")
self.gridLayout_main.addWidget(self.checkBox1, 0, 1, 1, 1)
spacerItem1 = QtGui.QSpacerItem(50, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
self.gridLayout_main.addItem(spacerItem1, 0, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout_main, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 494, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.checkBox2.setText(QtGui.QApplication.translate("MainWindow", "Checkbox2", None, QtGui.QApplication.UnicodeUTF8))
self.checkBox3.setText(QtGui.QApplication.translate("MainWindow", "Checkbox3", None, QtGui.QApplication.UnicodeUTF8))
self.checkBox1.setText(QtGui.QApplication.translate("MainWindow", "Checkbox1", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
And my code with classes looks like:
from PySide import QtCore, QtGui
class CreateCheckBox(QtGui.QCheckBox):
def __init__(self, frame, grid, gridLoc, name, parent=None):
#QtGui.QCheckBox.__init__(self, parent=parent) Is this the same as the super below?
super(CreateCheckBox, self).__init__(parent)
self.checkbox = QtGui.QCheckBox(frame)
grid.addWidget(self.checkbox, gridLoc, 2, 1, 1)
self.checkbox.setText(name)
class CreateFrame(QtGui.QFrame):
def __init__(self, parentFrame, parentGridLayout, gridLoc, parent=None):
#QtGui.QFrame.__init__(self, parent=parent) Is this the same as the super below?
super(CreateFrame, self).__init__(parent)
self.frame = QtGui.QFrame(parentFrame)
self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
self.frame.setFrameShadow(QtGui.QFrame.Raised)
parentGridLayout.addWidget(self.frame, gridLoc, 2, 1, 1)
class CreateGridLayout(QtGui.QGridLayout):
def __init__(self, parentFrame, parent=None):
super(CreateGridLayout, self).__init__(parent)
#QtGui.QGridLayout.__init__(self) # This line throws an error if I include parent=parent, why?..
self.gridLayoutSecondary = QtGui.QGridLayout(parentFrame)
self.gridLayoutSecondary.setContentsMargins(0, 0, 0, 0)
self.gridLayoutPrimary = QtGui.QGridLayout()
spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
self.gridLayoutPrimary.addItem(spacerItem, 0, 0, 1, 1)
self.gridLayoutSecondary.addLayout(self.gridLayoutPrimary, 0, 0, 1, 1)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(494, 210)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame_main = QtGui.QFrame(self.centralwidget)
self.frame_main.setGeometry(QtCore.QRect(20, 10, 435, 141))
self.frame_main.setFrameShape(QtGui.QFrame.StyledPanel)
self.frame_main.setFrameShadow(QtGui.QFrame.Raised)
self.frame_main.setObjectName("frame_main")
self.gridLayout_main = QtGui.QGridLayout()
self.gridLayout_main.setSpacing(0)
self.gridLayout_main.setObjectName("gridLayout_main")
spacerItem1 = QtGui.QSpacerItem(50, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
self.gridLayout_main.addItem(spacerItem1, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 494, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# List that contains new checkboxes
checkboxList = []
# List that contains new frames
frameList = []
# List than contains grid layouts for new frames
gridLayoutList = []
# Create 'checkBox1'
checkboxList.append(CreateCheckBox(self.frame_main, self.gridLayout_main, 0, 'Checkbox 1'))
# Create 'frame2'
frameList.append(CreateFrame(self.frame_main, self.gridLayout_main, 1))
# Create 'gridLayout2'
gridLayoutList.append(CreateGridLayout(frameList[0]))
# Create 'checkBox2'
checkboxList.append(CreateCheckBox(frameList[0], gridLayoutList[0], 0, 'Checkbox 2'))
# Create 'checkBox3'
checkboxList.append(CreateCheckBox(frameList[0], gridLayoutList[0], 1, 'Checkbox 3'))
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
El problema se soluciona maquetando correctamente tu aplicaciĆ³n, en la siguiente imagen se muestra el maquetado de QMainWindow, la imagen muestra que QMainWindow varias secciones.
In your case you should design the centralwidget,
Then, the answer can be implemented, observing that it is not necessary to use QGridLayout since it is used to distribute it as a matrix. I have created the addCheckbox function that adds the widget and stores it in the list.
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent=parent)
# add menubar
self.menubar = QtGui.QMenuBar(self)
self.menubar.setGeometry(QtCore.QRect(0, 0, 494, 21))
self.setMenuBar(self.menubar)
# add statusbar
self.statusbar = QtGui.QStatusBar(self)
self.setStatusBar(self.statusbar)
# set central widget
self.centralwidget = QtGui.QWidget(self)
self.setCentralWidget(self.centralwidget)
lay = QtGui.QVBoxLayout(self.centralwidget)
self.checkBox = QtGui.QCheckBox("checkbox1", self)
lay.addWidget(self.checkBox)
self.frame = QtGui.QFrame(self)
lay.addWidget(self.frame)
self.layout_of_frame = QtGui.QVBoxLayout(self.frame)
self.checkBoxList = []
self.addCheckbox("checkbox2")
self.addCheckbox("checkbox3")
self.addCheckbox("checkbox4")
self.addCheckbox("checkbox5")
def addCheckbox(self, text):
checkbox = QtGui.QCheckBox(text, self)
self.layout_of_frame.addWidget(checkbox)
self.checkBoxList.append(checkbox)
Screenshot:
I'm drawing a line between two widgets (two push buttons) into a graphics view with their positions as reference. But the line is drawn in a wrong place.
I tried using functions like mapToGlobal or mapToParent with different results, but it's still wrong. In the same class I have another method that draws lines with the mouse, and it works ok. I was taking it like a reference, but it seems that the events position has a different coordinate system. I don't know why this is happening.
The buttons and the graphics view are inside a Widget, which is also inside a window.
Here it is the class:
from PyQt4 import QtGui, QtCore
class WiringGraphicsView(QtGui.QGraphicsView):
def __init__(self, parent):
QtGui.QGraphicsView.__init__(self, parent)
self.setScene(QtGui.QGraphicsScene(self))
#self.setSceneRect(QtCore.QRectF(self.viewport().rect()))
def mousePressEvent(self, event):
self._start = event.pos()
def mouseReleaseEvent(self, event):
start = QtCore.QPointF(self.mapToScene(self._start))
end = QtCore.QPointF(self.mapToScene(event.pos()))
brush = QtGui.QBrush(QtGui.QColor(255, 0, 0) )
pen = QtGui.QPen(brush, 2)
line = QtGui.QGraphicsLineItem(QtCore.QLineF(start, end))
line.setPen(pen)
self.scene().addItem( line )
def paintWire(self, start_widget, end_widget):
start_position = QtCore.QPointF(self.mapToScene(start_widget.pos()))
end_position = QtCore.QPointF(self.mapToScene(end_widget.pos()))
brush = QtGui.QBrush(QtGui.QColor(255, 0, 0) )
pen = QtGui.QPen(brush, 2)
line = QtGui.QGraphicsLineItem(QtCore.QLineF(start_position, end_position))
line.setPen(pen)
self.scene().addItem( line )
UPDATE: At this point I've tried several things: Since the buttons were contained in a QWidget object, I take them out from there. I put them in a GroupBox instead. Also tried without containers. I don't get satisfactory results. Honestly I don't know how to do this properly considering that I'm using Qt designer and creating class files for "promoted" widgets (in this case is the GraphicsView) and set up some properties using the UpdateUi method in the main file
UPDATE 2: Here it is the file where the application is loaded:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import ui_wolfsonmixerwindow
class WolfsonMixerWindow(QMainWindow, ui_wolfsonmixerwindow.Ui_WolfsonMixerWindow):
def __init__(self, parent=None):
super(WolfsonMixerWindow, self).__init__(parent)
self.setupUi(self)
self.updateUi()
def updateUi(self):
#self.btn_AIF1RX1.setText("Hola")
menu_plugin = QMenu()
menu_unplug = QMenu()
menu_plugin.addAction('Action 1', self.plugin )
self.btn_AIF1RX1_2.setMenu(menu_plugin)
self.btn_AIF1TX1_5.setAllowDrag(False)
self.btn_AIF1TX1_5.setMenu(menu_unplug)
start = self.btn_AIF1RX1_2
end = self.btn_AIF1TX1_5
#self.graphicsView.scene().addWidget(self.btn_AIF1RX1_2)
#self.graphicsView.scene().addWidget(self.btn_AIF1TX1_5)
#self.graphicsView.setWidgets(start, end)
#HERE I CALL THE PAINTWIRE METHOD
self.graphicsView.paintWire(start, end)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
form = WolfsonMixerWindow()
form.show()
app.exec_()
And the uic file:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_wolfsonmixerwindow.ui'
#
# Created: Thu Feb 19 21:51:35 2015
# by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_WolfsonMixerWindow(object):
def setupUi(self, WolfsonMixerWindow):
WolfsonMixerWindow.setObjectName(_fromUtf8("WolfsonMixerWindow"))
WolfsonMixerWindow.resize(562, 480)
self.centralwidget = QtGui.QWidget(WolfsonMixerWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayoutWidget = QtGui.QWidget(self.centralwidget)
self.gridLayoutWidget.setGeometry(QtCore.QRect(200, 10, 241, 101))
self.gridLayoutWidget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget"))
self.gridLayout = QtGui.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setSizeConstraint(QtGui.QLayout.SetMaximumSize)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.QHBox_Playback = QtGui.QHBoxLayout()
self.QHBox_Playback.setObjectName(_fromUtf8("QHBox_Playback"))
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.label_2 = QtGui.QLabel(self.gridLayoutWidget)
self.label_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.verticalLayout.addWidget(self.label_2)
self.label = QtGui.QLabel(self.gridLayoutWidget)
self.label.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.btn_AIF1RX1 = DragButton(self.gridLayoutWidget)
self.btn_AIF1RX1.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX1.setMouseTracking(True)
self.btn_AIF1RX1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX1.setText(_fromUtf8(""))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/audio-input-line.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_AIF1RX1.setIcon(icon)
self.btn_AIF1RX1.setAutoDefault(False)
self.btn_AIF1RX1.setDefault(False)
self.btn_AIF1RX1.setFlat(True)
self.btn_AIF1RX1.setObjectName(_fromUtf8("btn_AIF1RX1"))
self.verticalLayout.addWidget(self.btn_AIF1RX1)
self.QHBox_Playback.addLayout(self.verticalLayout)
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.label_3 = QtGui.QLabel(self.gridLayoutWidget)
self.label_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.verticalLayout_2.addWidget(self.label_3)
self.label_4 = QtGui.QLabel(self.gridLayoutWidget)
self.label_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.verticalLayout_2.addWidget(self.label_4)
self.btn_AIF1RX2 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1RX2.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX2.setMouseTracking(True)
self.btn_AIF1RX2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX2.setText(_fromUtf8(""))
self.btn_AIF1RX2.setIcon(icon)
self.btn_AIF1RX2.setAutoDefault(False)
self.btn_AIF1RX2.setDefault(False)
self.btn_AIF1RX2.setFlat(True)
self.btn_AIF1RX2.setObjectName(_fromUtf8("btn_AIF1RX2"))
self.verticalLayout_2.addWidget(self.btn_AIF1RX2)
self.QHBox_Playback.addLayout(self.verticalLayout_2)
self.gridLayout.addLayout(self.QHBox_Playback, 1, 0, 1, 1)
self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
self.horizontalLayout_3.setContentsMargins(-1, -1, 0, -1)
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
self.verticalLayout_3 = QtGui.QVBoxLayout()
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
self.label_6 = QtGui.QLabel(self.gridLayoutWidget)
self.label_6.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_6.setAlignment(QtCore.Qt.AlignCenter)
self.label_6.setObjectName(_fromUtf8("label_6"))
self.verticalLayout_3.addWidget(self.label_6)
self.label_5 = QtGui.QLabel(self.gridLayoutWidget)
self.label_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.verticalLayout_3.addWidget(self.label_5)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.btn_AIF1TX1_1 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_1.setMouseTracking(False)
self.btn_AIF1TX1_1.setFocusPolicy(QtCore.Qt.StrongFocus)
self.btn_AIF1TX1_1.setAcceptDrops(True)
self.btn_AIF1TX1_1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_1.setText(_fromUtf8(""))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/input_small.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btn_AIF1TX1_1.setIcon(icon1)
self.btn_AIF1TX1_1.setFlat(True)
self.btn_AIF1TX1_1.setObjectName(_fromUtf8("btn_AIF1TX1_1"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_1)
self.btn_AIF1TX1_2 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_2.setAcceptDrops(True)
self.btn_AIF1TX1_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_2.setText(_fromUtf8(""))
self.btn_AIF1TX1_2.setIcon(icon1)
self.btn_AIF1TX1_2.setFlat(True)
self.btn_AIF1TX1_2.setObjectName(_fromUtf8("btn_AIF1TX1_2"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_2)
self.btn_AIF1TX1_3 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_3.setAcceptDrops(True)
self.btn_AIF1TX1_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_3.setText(_fromUtf8(""))
self.btn_AIF1TX1_3.setIcon(icon1)
self.btn_AIF1TX1_3.setFlat(True)
self.btn_AIF1TX1_3.setObjectName(_fromUtf8("btn_AIF1TX1_3"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_3)
self.btn_AIF1TX1_4 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX1_4.setAcceptDrops(True)
self.btn_AIF1TX1_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_4.setText(_fromUtf8(""))
self.btn_AIF1TX1_4.setIcon(icon1)
self.btn_AIF1TX1_4.setFlat(True)
self.btn_AIF1TX1_4.setObjectName(_fromUtf8("btn_AIF1TX1_4"))
self.horizontalLayout.addWidget(self.btn_AIF1TX1_4)
self.verticalLayout_3.addLayout(self.horizontalLayout)
self.horizontalLayout_3.addLayout(self.verticalLayout_3)
self.verticalLayout_4 = QtGui.QVBoxLayout()
self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
self.label_7 = QtGui.QLabel(self.gridLayoutWidget)
self.label_7.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_7.setAlignment(QtCore.Qt.AlignCenter)
self.label_7.setObjectName(_fromUtf8("label_7"))
self.verticalLayout_4.addWidget(self.label_7)
self.label_8 = QtGui.QLabel(self.gridLayoutWidget)
self.label_8.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_8.setAlignment(QtCore.Qt.AlignCenter)
self.label_8.setObjectName(_fromUtf8("label_8"))
self.verticalLayout_4.addWidget(self.label_8)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setSpacing(1)
self.horizontalLayout_2.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.btn_AIF1TX2_1 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX2_1.setAcceptDrops(True)
self.btn_AIF1TX2_1.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_1.setText(_fromUtf8(""))
self.btn_AIF1TX2_1.setIcon(icon1)
self.btn_AIF1TX2_1.setFlat(True)
self.btn_AIF1TX2_1.setObjectName(_fromUtf8("btn_AIF1TX2_1"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_1)
self.btn_AIF1TX2_2 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX2_2.setAcceptDrops(True)
self.btn_AIF1TX2_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_2.setText(_fromUtf8(""))
self.btn_AIF1TX2_2.setIcon(icon1)
self.btn_AIF1TX2_2.setFlat(True)
self.btn_AIF1TX2_2.setObjectName(_fromUtf8("btn_AIF1TX2_2"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_2)
self.btn_AIF1TX2_3 = QtGui.QPushButton(self.gridLayoutWidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btn_AIF1TX2_3.sizePolicy().hasHeightForWidth())
self.btn_AIF1TX2_3.setSizePolicy(sizePolicy)
self.btn_AIF1TX2_3.setAcceptDrops(True)
self.btn_AIF1TX2_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_3.setText(_fromUtf8(""))
self.btn_AIF1TX2_3.setIcon(icon1)
self.btn_AIF1TX2_3.setFlat(True)
self.btn_AIF1TX2_3.setObjectName(_fromUtf8("btn_AIF1TX2_3"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_3)
self.btn_AIF1TX2_4 = QtGui.QPushButton(self.gridLayoutWidget)
self.btn_AIF1TX2_4.setAcceptDrops(True)
self.btn_AIF1TX2_4.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX2_4.setText(_fromUtf8(""))
self.btn_AIF1TX2_4.setIcon(icon1)
self.btn_AIF1TX2_4.setFlat(True)
self.btn_AIF1TX2_4.setObjectName(_fromUtf8("btn_AIF1TX2_4"))
self.horizontalLayout_2.addWidget(self.btn_AIF1TX2_4)
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
self.horizontalLayout_3.addLayout(self.verticalLayout_4)
self.gridLayout.addLayout(self.horizontalLayout_3, 1, 1, 1, 1)
self.lbl_playback = QtGui.QLabel(self.gridLayoutWidget)
self.lbl_playback.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.lbl_playback.setTextFormat(QtCore.Qt.AutoText)
self.lbl_playback.setObjectName(_fromUtf8("lbl_playback"))
self.gridLayout.addWidget(self.lbl_playback, 0, 0, 1, 1)
self.label_9 = QtGui.QLabel(self.gridLayoutWidget)
self.label_9.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.label_9.setAlignment(QtCore.Qt.AlignCenter)
self.label_9.setObjectName(_fromUtf8("label_9"))
self.gridLayout.addWidget(self.label_9, 0, 1, 1, 1)
self.dial = QtGui.QDial(self.centralwidget)
self.dial.setGeometry(QtCore.QRect(30, 360, 50, 64))
self.dial.setObjectName(_fromUtf8("dial"))
self.label_10 = QtGui.QLabel(self.centralwidget)
self.label_10.setGeometry(QtCore.QRect(20, 320, 52, 15))
self.label_10.setObjectName(_fromUtf8("label_10"))
self.widget = QtGui.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(160, 400, 331, 21))
self.widget.setObjectName(_fromUtf8("widget"))
self.groupBox = QtGui.QGroupBox(self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(130, 130, 361, 271))
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.graphicsView = WiringGraphicsView(self.groupBox)
self.graphicsView.setGeometry(QtCore.QRect(40, 30, 291, 241))
self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.NoBrush)
self.graphicsView.setBackgroundBrush(brush)
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.btn_AIF1RX1_2 = DragButton(self.groupBox)
self.btn_AIF1RX1_2.setGeometry(QtCore.QRect(50, 50, 51, 31))
self.btn_AIF1RX1_2.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX1_2.setMouseTracking(True)
self.btn_AIF1RX1_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX1_2.setText(_fromUtf8(""))
self.btn_AIF1RX1_2.setIcon(icon)
self.btn_AIF1RX1_2.setAutoDefault(False)
self.btn_AIF1RX1_2.setDefault(False)
self.btn_AIF1RX1_2.setFlat(True)
self.btn_AIF1RX1_2.setObjectName(_fromUtf8("btn_AIF1RX1_2"))
self.btn_AIF1TX1_5 = DragButton(self.groupBox)
self.btn_AIF1TX1_5.setGeometry(QtCore.QRect(270, 150, 41, 31))
self.btn_AIF1TX1_5.setMouseTracking(False)
self.btn_AIF1TX1_5.setFocusPolicy(QtCore.Qt.StrongFocus)
self.btn_AIF1TX1_5.setAcceptDrops(True)
self.btn_AIF1TX1_5.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1TX1_5.setText(_fromUtf8(""))
self.btn_AIF1TX1_5.setIcon(icon1)
self.btn_AIF1TX1_5.setFlat(True)
self.btn_AIF1TX1_5.setObjectName(_fromUtf8("btn_AIF1TX1_5"))
self.btn_AIF1RX1_3 = DragButton(self.groupBox)
self.btn_AIF1RX1_3.setGeometry(QtCore.QRect(60, 110, 51, 27))
self.btn_AIF1RX1_3.setBaseSize(QtCore.QSize(0, 0))
self.btn_AIF1RX1_3.setMouseTracking(True)
self.btn_AIF1RX1_3.setAcceptDrops(False)
self.btn_AIF1RX1_3.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.btn_AIF1RX1_3.setText(_fromUtf8(""))
self.btn_AIF1RX1_3.setIcon(icon)
self.btn_AIF1RX1_3.setAutoDefault(False)
self.btn_AIF1RX1_3.setDefault(False)
self.btn_AIF1RX1_3.setFlat(True)
self.btn_AIF1RX1_3.setObjectName(_fromUtf8("btn_AIF1RX1_3"))
WolfsonMixerWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(WolfsonMixerWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 562, 23))
self.menubar.setObjectName(_fromUtf8("menubar"))
WolfsonMixerWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(WolfsonMixerWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
WolfsonMixerWindow.setStatusBar(self.statusbar)
self.retranslateUi(WolfsonMixerWindow)
QtCore.QObject.connect(self.dial, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.label_10.setNum)
QtCore.QMetaObject.connectSlotsByName(WolfsonMixerWindow)
def retranslateUi(self, WolfsonMixerWindow):
WolfsonMixerWindow.setWindowTitle(_translate("WolfsonMixerWindow", "Wolfson Mixer", None))
self.label_2.setText(_translate("WolfsonMixerWindow", "AIF1RX1", None))
self.label.setText(_translate("WolfsonMixerWindow", "L", None))
self.label_3.setText(_translate("WolfsonMixerWindow", "AIF1RX2", None))
self.label_4.setText(_translate("WolfsonMixerWindow", "R", None))
self.label_6.setText(_translate("WolfsonMixerWindow", "AIF1TX1", None))
self.label_5.setText(_translate("WolfsonMixerWindow", "L", None))
self.label_7.setText(_translate("WolfsonMixerWindow", "AIF1TX2", None))
self.label_8.setText(_translate("WolfsonMixerWindow", "R", None))
self.lbl_playback.setText(_translate("WolfsonMixerWindow", "<html><head/><body><p><span style=\" font-weight:600;\">Playback (from RPi)</span></p></body></html>", None))
self.label_9.setText(_translate("WolfsonMixerWindow", "<html><head/><body><p><span style=\" font-weight:600;\">Record (to RPi)</span></p></body></html>", None))
self.label_10.setText(_translate("WolfsonMixerWindow", "TextLabel", None))
self.groupBox.setTitle(_translate("WolfsonMixerWindow", "GroupBox", None))
from wiringgraphicsview import WiringGraphicsView
from dragbutton import DragButton
import icons_rc
Here is an example how to draw a line between two QWidgets in a QGraphicsScene. In principle it is straightforward. The rectangle of a widget can be accessed by QGraphicsProxyWidget.geometry() and is in scene coordinates. So one can draw a line based on that.
Example:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
scene = QtGui.QGraphicsScene()
# put a button into the scene and move it
button1 = QtGui.QPushButton('Button 1')
scene_button1 = scene.addWidget(button1)
r1 = scene_button1.geometry()
r1.moveTo(-100, -50)
scene_button1.setGeometry(r1)
# put another button into the scene
button2 = QtGui.QPushButton('Button 2')
scene_button2 = scene.addWidget(button2)
r2 = scene_button2.geometry()
# add a line between the centers of each rectangles
scene.addLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)
# view on the scene
view = QtGui.QGraphicsView(scene)
view.resize(300, 200)
view.show()
app.exec_()
And it looks like:
And now the whole with dragging because it is not that trivial. Not the QGraphicsProxyWidget but the original QWidget, seems to get the mouse move/pressed events. We simply emit a new signal (dragged) and connect it to a function that can move the button in the scene around (using the return of scene.addWidget, the QGraphicsProxyWidget which is also a QGraphicsItem). It also redraws the line between the two buttons so they stay connected.
from PySide import QtGui, QtCore
class DraggablePushButton(QtGui.QPushButton):
"""
Extension of QPushButton that emits a dragged signal (QPointF which is the delta in movement of the mouse) as
long as it is pressed.
"""
dragged = QtCore.Signal(QtCore.QPointF)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def mousePressEvent(self, event):
self.position = event.globalPos()
def mouseMoveEvent(self, event):
# will only by called if the mouse is also pressed
position_now = event.globalPos()
self.dragged.emit(position_now - self.position)
self.position = position_now
def move_scene_button1_and_redraw_line(drag):
# move the button1 by a certain delta position and change line connecting them with it
scene_button1.moveBy(drag.x(), drag.y())
r1 = scene_button1.geometry()
line_item.setLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)
app = QtGui.QApplication([])
# the graphicsscene
scene = QtGui.QGraphicsScene()
scene.setSceneRect(-150, -100, 300, 200)
# put a draggable button into the scene
button1 = DraggablePushButton('Button 1')
scene_button1 = scene.addWidget(button1)
scene_button1.setPos(-100, -50)
r1 = scene_button1.geometry()
# connect dragged events to move of scene button
button1.dragged.connect(move_scene_button1_and_redraw_line)
# put another still standing button into the scene
button2 = QtGui.QPushButton('Button 2')
scene_button2 = scene.addWidget(button2)
r2 = scene_button2.geometry()
# draw line between button1 and button2
line_item = scene.addLine(r1.x() + r1.width() / 2, r1.y() + r1.height() / 2, r2.x() + r2.width() / 2, r2.y() + r2.height() / 2)
# view on the scene
view = QtGui.QGraphicsView(scene)
view.resize(330, 220)
view.show()
app.exec_()
And it still looks like:
I created this widget using Qt creator and generated this code
from PySide import QtCore, QtGui
class Ui_DATA_Entries_Widget(QtGui.QWidget):
def setupUi(self, DATA_Entries_Widget):
DATA_Entries_Widget.setObjectName("DATA_Entries_Widget")
DATA_Entries_Widget.resize(676, 50)
DATA_Entries_Widget.setMinimumSize(QtCore.QSize(676, 50))
DATA_Entries_Widget.setMaximumSize(QtCore.QSize(676, 50))
self.horizontalLayout = QtGui.QHBoxLayout(DATA_Entries_Widget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtGui.QLabel(DATA_Entries_Widget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.lineEdit = QtGui.QLineEdit(DATA_Entries_Widget)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
self.label_2 = QtGui.QLabel(DATA_Entries_Widget)
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.lineEdit_2 = QtGui.QLineEdit(DATA_Entries_Widget)
self.lineEdit_2.setObjectName("lineEdit_2")
self.horizontalLayout.addWidget(self.lineEdit_2)
self.label_3 = QtGui.QLabel(DATA_Entries_Widget)
self.label_3.setObjectName("label_3")
self.horizontalLayout.addWidget(self.label_3)
self.lineEdit_3 = QtGui.QLineEdit(DATA_Entries_Widget)
self.lineEdit_3.setObjectName("lineEdit_3")
self.horizontalLayout.addWidget(self.lineEdit_3)
self.label_5 = QtGui.QLabel(DATA_Entries_Widget)
self.label_5.setMinimumSize(QtCore.QSize(47, 32))
self.label_5.setObjectName("label_5")
self.horizontalLayout.addWidget(self.label_5)
self.lineEdit_4 = QtGui.QLineEdit(DATA_Entries_Widget)
self.lineEdit_4.setObjectName("lineEdit_4")
self.horizontalLayout.addWidget(self.lineEdit_4)
self.label_4 = QtGui.QLabel(DATA_Entries_Widget)
self.label_4.setObjectName("label_4")
self.horizontalLayout.addWidget(self.label_4)
self.lineEdit_5 = QtGui.QLineEdit(DATA_Entries_Widget)
self.lineEdit_5.setObjectName("lineEdit_5")
self.horizontalLayout.addWidget(self.lineEdit_5)
self.pushButton = QtGui.QPushButton(DATA_Entries_Widget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.retranslateUi(DATA_Entries_Widget)
QtCore.QMetaObject.connectSlotsByName(DATA_Entries_Widget)
def retranslateUi(self, DATA_Entries_Widget):
DATA_Entries_Widget.setWindowTitle(QtGui.QApplication.translate("DATA_Entries_Widget", "Form", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("DATA_Entries_Widget", "A", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("DATA_Entries_Widget", "B", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("DATA_Entries_Widget", "C", None, QtGui.QApplication.UnicodeUTF8))
self.label_5.setText(QtGui.QApplication.translate("DATA_Entries_Widget", "D", None, QtGui.QApplication.UnicodeUTF8))
self.label_4.setText(QtGui.QApplication.translate("DATA_Entries_Widget", "E", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("DATA_Entries_Widget", "Delete", None, QtGui.QApplication.UnicodeUTF8))
Now I need to add this widget dinamically, much like the the Test widget, that I got from another question:
from PySide import QtGui, QtCore
import sys
class Main(QtGui.QMainWindow):
def __init__(self, parent = None):
super(Main, self).__init__(parent)
# main button
self.addButton = QtGui.QPushButton('button to add other widgets')
self.addButton.clicked.connect(self.addWidget)
# scroll area widget contents - layout
self.scrollLayout = QtGui.QFormLayout()
# scroll area widget contents
self.scrollWidget = QtGui.QWidget()
self.scrollWidget.setLayout(self.scrollLayout)
# scroll area
self.scrollArea = QtGui.QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setWidget(self.scrollWidget)
# main layout
self.mainLayout = QtGui.QVBoxLayout()
# add all main to the main vLayout
self.mainLayout.addWidget(self.addButton)
self.mainLayout.addWidget(self.scrollArea)
# central widget
self.centralWidget = QtGui.QWidget()
self.centralWidget.setLayout(self.mainLayout)
# set central widget
self.setCentralWidget(self.centralWidget)
def addWidget(self):
self.scrollLayout.addRow(TestButton())
class TestButton(QtGui.QPushButton):
def __init__( self, parent=None):
super(TestButton, self).__init__(parent)
self.setText("I am in Test widget")
self.clicked.connect(self.deleteLater)
app = QtGui.QApplication(sys.argv)
myWidget = Main()
myWidget.show()
app.exec_()
How can I subtitute the TestButton in the second code with my custom widget easily?
Any help is much appreciated!
I wanted to have a total of 8 groupbox in the Dialog box. I don't know how to associate the horizontal scrollbar so that I can scroll it down and access all the group box. In the code below I have added only 2 as an example. Any help is appreciated.
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.buttonBox = QtGui.QDialogButtonBox(Dialog)
self.buttonBox.setGeometry(QtCore.QRect(300, 20, 81, 71))
self.buttonBox.setOrientation(QtCore.Qt.Vertical)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.scrollArea = QtGui.QScrollArea(Dialog)
self.scrollArea.setGeometry(QtCore.QRect(30, 20, 251, 251))
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtGui.QWidget(self.scrollArea)
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 249, 249))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.groupBox = QtGui.QGroupBox(self.scrollAreaWidgetContents)
self.groupBox.setGeometry(QtCore.QRect(10, 10, 211, 81))
self.groupBox.setObjectName("groupBox")
self.textEdit = QtGui.QTextEdit(self.groupBox)
self.textEdit.setGeometry(QtCore.QRect(10, 20, 171, 51))
self.textEdit.setObjectName("textEdit")
self.groupBox_2 = QtGui.QGroupBox(self.scrollAreaWidgetContents)
self.groupBox_2.setGeometry(QtCore.QRect(10, 110, 211, 111))
self.groupBox_2.setObjectName("groupBox_2")
self.textEdit_2 = QtGui.QTextEdit(self.groupBox_2)
self.textEdit_2.setGeometry(QtCore.QRect(10, 20, 171, 84))
self.textEdit_2.setObjectName("textEdit_2")
self.verticalScrollBar = QtGui.QScrollBar(self.scrollAreaWidgetContents)
self.verticalScrollBar.setGeometry(QtCore.QRect(230, 0, 16, 241))
self.verticalScrollBar.setOrientation(QtCore.Qt.Vertical)
self.verticalScrollBar.setObjectName("verticalScrollBar")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.retranslateUi(Dialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.groupBox.setTitle(QtGui.QApplication.translate("Dialog", "GroupBox", None, QtGui.QApplication.UnicodeUTF8))
self.groupBox_2.setTitle(QtGui.QApplication.translate("Dialog", "GroupBox", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
As I said in the comments, QScrollArea doesn't need manual QScrollBar. It will create when needed. I can't be sure what your problem is without seeing the 'not working' code, but my guess is the fixed sized items and their placement. You are probably putting things outside of the widgets margin or overlapping each other so that the inner widget does not grow appropriately.
Anyway, here is a minimal example that replicates your dialog (notice the scrollbar):
import sys
from PyQt4 import QtGui, QtCore
class MyDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(MyDialog, self).__init__(parent)
scrolllayout = QtGui.QVBoxLayout()
scrollwidget = QtGui.QWidget()
scrollwidget.setLayout(scrolllayout)
scroll = QtGui.QScrollArea()
scroll.setWidgetResizable(True) # Set to make the inner widget resize with scroll area
scroll.setWidget(scrollwidget)
self.groupboxes = [] # Keep a reference to groupboxes for later use
for i in range(8): # 8 groupboxes with textedit in them
groupbox = QtGui.QGroupBox('%d' % i)
grouplayout = QtGui.QHBoxLayout()
grouptext = QtGui.QTextEdit()
grouplayout.addWidget(grouptext)
groupbox.setLayout(grouplayout)
scrolllayout.addWidget(groupbox)
self.groupboxes.append(groupbox)
self.buttonbox = QtGui.QDialogButtonBox()
self.buttonbox.setOrientation(QtCore.Qt.Vertical)
self.buttonbox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
layout = QtGui.QHBoxLayout()
layout.addWidget(scroll)
layout.addWidget(self.buttonbox)
self.setLayout(layout)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog = MyDialog()
dialog.show()
sys.exit(app.exec_())