I'm new to python and pyqt. I am am trying to create a matrix of QToolButtons where upon pressing a button, a QDialog pops up for user input (more than one field).
I have a class for a button matrix object and a class for a dialog but can't seem to get a function within the button matrix class initiate an instance of the dialog class / widget.
Can anyone please advise me on what I'm doing wrong?
I have provided the code below:
from PyQt4 import QtGui
from PyQt4.QtGui import QApplication, QWidget, QFormLayout, QInputDialog, QPushButton, QToolButton, QLabel, QVBoxLayout, QHBoxLayout, QLineEdit
class Pixel(object):
def __init__(self, pixel_number, r_value, g_value, b_value):
self.pixel = pixel_number
self.red_value = r_value
self.green_value = g_value
self.blue_value = b_value
class inputdialogdemo(QWidget):
def __init__(self, parent = None):
QWidget.__init__(self, parent)
#super(inputdialogdemo, self).__init__(parent)
layout = QFormLayout()
self.btn1 = QPushButton("Enter red value")
self.le1 = QLineEdit()
self.btn1.clicked.connect(self.getRed)
layout.addRow(self.btn1,self.le1)
self.btn2= QPushButton("Enter green value")
self.le2 = QLineEdit()
self.btn2.clicked.connect(self.getGreen)
layout.addRow(self.btn1,self.le2)
self.btn3 = QPushButton("Enter blue value")
self.le3 = QLineEdit()
self.btn3.clicked.connect(self.getBlue)
layout.addRow(self.btn3,self.le3)
self.setLayout(layout)
self.setWindowTitle("RGB input dialog ")
def getRed(self):
num, ok = QInputDialog.getText(self, 'Red Input Dialog', 'Enter your name:')
if ok:
self.le1.setText(str(num))
def getGreen(self):
num,ok = QInputDialog.getInt(self,"Green input dualog","enter a number")
if ok:
self.le2.setText(str(num))
def getBlue(self):
num,ok = QInputDialog.getInt(self,"Blue input dualog","enter a number")
if ok:
self.le3.setText(str(num))
class ClusterArray(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
#self.button_layout = QHBoxLayout()
self.button_layout = QtGui.QGridLayout()
self.widget_layout = QtGui.QGridLayout()
for cluster_number in range(1, 15):
for pixel_number in range(1, 5):
button = QToolButton()
button.setText(str(cluster_number) + str(pixel_number))
button.setObjectName(f"Cluster{cluster_number},Pixel{pixel_number}")
button.released.connect(self.button_released)
self.button_layout.addWidget(button, cluster_number, pixel_number)
self.status_label = QLabel('No button clicked')
self.widget_layout.addItem(self.button_layout)
self.widget_layout.addWidget(self.status_label)
self.setLayout(self.widget_layout)
ex = inputdialogdemo()
def button_released(self):
sending_button = self.sender()
self.status_label.setText('%s Clicked!' % str(sending_button.objectName()))
ex = inputdialogdemo()
ex.show()
#i, okPressed = QInputDialog.getInt(self, "Get integer","Percentage:", 28, 0, 100, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = ClusterArray()
widget.show()
# ex = inputdialogdemo()
# ex.show()
sys.exit(app.exec_()
At the moment I've just tried to get my class' function to create an object from some demo code in a class called 'inputdialogdemo'
Also, I would like to keep the inputted values associated with the corresponding button on the matrix somehow. I'm thinking the values should be stored in another object that each button represents. My object would be 'Pixel' that holds red, green and blue values. I have yet to code this functionality. Does this method sound feasible?
The inputdialogdemo
instance is correctly created both in the __init__
and in button_released
, the problem is that as soon as those function return, the ex
instance gets garbage collected : since there is no persistent reference ( ex
is just a local variable), python automatically deletes it to avoid unnecessary memory consumption.
Since you're needing a dialog , the best solution is to inherit from QDialog
instead of QWidget
; this has two important benefits: it keeps the dialog modal (it stays on top of other windows and avoid interaction with them) and provides the exec_()
method, which does not return until the dialog is closed; then you can add a QDialogButtonBox for standard Ok/Cancel buttons, and connect its accepted
and rejected
to the accept()
and reject()
slots of the dialog.
from PyQt4.QtGui import (QApplication, QWidget, QFormLayout, QInputDialog, QPushButton, QToolButton,
QLabel, QVBoxLayout, QHBoxLayout, QLineEdit, )
class inputdialogdemo(QDialog):
def __init__(self, parent = None):
# ...
buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
layout.addRow(buttonBox)
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
class ClusterArray(QWidget):
# ...
def button_released(self):
sending_button = self.sender()
self.status_label.setText('%s Clicked!' % str(sending_button.objectName()))
ex = inputdialogdemo()
Some suggestions:
setLayout()
, not addItem()
;clicked
signal, not released
; button.setProperty('cluster', cluster_number)
button.setProperty('pixel', pixel_number)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.