在另一个 QWidget class' 函数中启动自定义 Widget
Initiating a custom QWidget within another QWidget class' function
我是 python 和 pyqt 的新手。我正在尝试创建一个 QToolButtons 矩阵,在按下按钮时,会弹出一个 QDialog 供用户输入(多个字段)。
我有一个用于按钮矩阵对象的 class 和一个用于对话框的 class 但似乎无法在按钮矩阵中获得函数 class 启动一个实例对话框 class / widget.
任何人都可以告诉我我做错了什么吗?
我提供了以下代码:
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_()
目前我刚刚尝试让我的 class' 函数从 class 中的一些演示代码创建一个对象 'inputdialogdemo'
此外,我想以某种方式将输入的值与矩阵上的相应按钮相关联。我认为这些值应该存储在每个按钮代表的另一个对象中。我的对象是 'Pixel',它包含红色、绿色和蓝色值。我还没有编写此功能的代码。这个方法听起来可行吗?
inputdialogdemo
实例在 __init__
和 button_released
中均已正确创建,问题是一旦这些函数 return、ex
实例得到垃圾收集:因为没有持久引用(ex
只是一个本地变量),python 自动删除,避免不必要的内存消耗
因为你需要一个对话框,最好的解决办法是继承QDialog
而不是QWidget
;这有两个重要的好处:它保持对话框 modal(它保持在其他 windows 之上并避免与它们交互)并提供 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()
对话框。
from PyQt4.QtGui import (QApplication, QWidget, QFormLayout, QInputDialog, QPushButton, QToolButton,
QLabel, QVBoxLayout, QHBoxLayout, QLineEdit, <b>QDialog, QDialogButtonBox</b>)
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()
<b>if ex.exec_():
red = ex.le1.text()
green = ex.le2.text()
blue = ex.le2.text()</b>
一些建议:
- 如果你需要一个数值,不要使用QLineEdit,而是QSpinBox;
- 要向另一个布局添加布局,请使用
setLayout()
,而不是 addItem()
;
- 连接到按钮点击,使用
clicked
信号,而不是 released
;
- 虽然没有严格禁止对象名称使用特殊字符,但通常最好避免使用它们;此外,将对象名称用于 实际 对象名称,而不是用于跟踪某些属性
- 您可以使用 dynamic properties:
跟踪任何 QObject 的自定义属性
button.setProperty('cluster', cluster_number)
button.setProperty('pixel', pixel_number)
- 除非您有强制性系统要求,否则您真的应该考虑切换到 PyQt5,因为 PyQt4 被认为已过时并且 deprecated/unsupported 自 2015 年以来;
- 总是喜欢 类 的大写名称,因为小写名称通常只用于变量和属性;阅读更多关于
Style Guide for Python Code;
我是 python 和 pyqt 的新手。我正在尝试创建一个 QToolButtons 矩阵,在按下按钮时,会弹出一个 QDialog 供用户输入(多个字段)。
我有一个用于按钮矩阵对象的 class 和一个用于对话框的 class 但似乎无法在按钮矩阵中获得函数 class 启动一个实例对话框 class / widget.
任何人都可以告诉我我做错了什么吗?
我提供了以下代码:
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_()
目前我刚刚尝试让我的 class' 函数从 class 中的一些演示代码创建一个对象 'inputdialogdemo'
此外,我想以某种方式将输入的值与矩阵上的相应按钮相关联。我认为这些值应该存储在每个按钮代表的另一个对象中。我的对象是 'Pixel',它包含红色、绿色和蓝色值。我还没有编写此功能的代码。这个方法听起来可行吗?
inputdialogdemo
实例在 __init__
和 button_released
中均已正确创建,问题是一旦这些函数 return、ex
实例得到垃圾收集:因为没有持久引用(ex
只是一个本地变量),python 自动删除,避免不必要的内存消耗
因为你需要一个对话框,最好的解决办法是继承QDialog
而不是QWidget
;这有两个重要的好处:它保持对话框 modal(它保持在其他 windows 之上并避免与它们交互)并提供 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()
对话框。
from PyQt4.QtGui import (QApplication, QWidget, QFormLayout, QInputDialog, QPushButton, QToolButton,
QLabel, QVBoxLayout, QHBoxLayout, QLineEdit, <b>QDialog, QDialogButtonBox</b>)
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()
<b>if ex.exec_():
red = ex.le1.text()
green = ex.le2.text()
blue = ex.le2.text()</b>
一些建议:
- 如果你需要一个数值,不要使用QLineEdit,而是QSpinBox;
- 要向另一个布局添加布局,请使用
setLayout()
,而不是addItem()
; - 连接到按钮点击,使用
clicked
信号,而不是released
; - 虽然没有严格禁止对象名称使用特殊字符,但通常最好避免使用它们;此外,将对象名称用于 实际 对象名称,而不是用于跟踪某些属性
- 您可以使用 dynamic properties: 跟踪任何 QObject 的自定义属性
button.setProperty('cluster', cluster_number)
button.setProperty('pixel', pixel_number)
- 除非您有强制性系统要求,否则您真的应该考虑切换到 PyQt5,因为 PyQt4 被认为已过时并且 deprecated/unsupported 自 2015 年以来;
- 总是喜欢 类 的大写名称,因为小写名称通常只用于变量和属性;阅读更多关于 Style Guide for Python Code;