В Qt нет похожего элемента (есть 2 разные библиотеки, подходы которых различаются), возможное решение - создать объект, который отображает qproperties:
from dataclasses import dataclass
import json
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
import sip
@dataclass
class Property:
qobject: QtCore.QObject = None
qproperty: str = ""
@property
def value(self):
if self.qobject and not sip.isdeleted(self.qobject):
return self.qobject.property(self.qproperty)
@value.setter
def value(self, value):
if self.qobject and not sip.isdeleted(self.qobject):
self.qobject.setProperty(self.qproperty, value)
class Widget(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
top_spinbox = QtWidgets.QSpinBox(maximum=2147483647)
left_spinbox = QtWidgets.QSpinBox(maximum=2147483647)
right_spinbox = QtWidgets.QSpinBox(maximum=2147483647)
bottom_spinbox = QtWidgets.QSpinBox(maximum=2147483647)
button = QtWidgets.QPushButton(self.tr("grab"), clicked=self.grab_screen)
file_menu = self.menuBar().addMenu(self.tr("&File"))
open_action = file_menu.addAction(self.tr("Open File..."))
open_action.triggered.connect(self.load_config)
save_action = file_menu.addAction(self.tr("Save"))
save_action.triggered.connect(self.save_config)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
flay = QtWidgets.QFormLayout(central_widget)
flay.addRow(button)
flay.addRow("Top:", top_spinbox)
flay.addRow("Left:", left_spinbox)
flay.addRow("Right:", right_spinbox)
flay.addRow("Bottom:", bottom_spinbox)
self.resize(640, 480)
self.region = {
"top": Property(qobject=top_spinbox, qproperty="value"),
"left": Property(qobject=left_spinbox, qproperty="value"),
"right": Property(qobject=right_spinbox, qproperty="value"),
"bottom": Property(qobject=bottom_spinbox, qproperty="value"),
}
@QtCore.pyqtSlot()
def grab_screen(self):
top = self.region["top"].value
left = self.region["left"].value
right = self.region["right"].value
bottom = self.region["bottom"].value
print(top, left, right, bottom)
@QtCore.pyqtSlot()
def load_config(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
self.tr("Select file"),
"/",
self.tr("JSON files (*.json);;All files (*.*)"),
)
if filename:
with open(filename, "r") as f:
data = json.load(f)
if "region" in data:
self.region["top"].value = data["region"].get("top", 0)
self.region["left"].value = data["region"].get("left", 0)
self.region["right"].value = data["region"].get("right", 0)
self.region["bottom"].value = data["region"].get("bottom", 0)
@QtCore.pyqtSlot()
def save_config(self):
filename, _ = QtWidgets.QFileDialog.getSaveFileName(
self,
self.tr("Save file"),
"/",
self.tr("JSON files (*.json);;All files (*.*)"),
)
if filename:
with open(filename, "w", encoding="utf-8") as f:
data = {
"region": {
"top": self.region["top"].value,
"left": self.region["left"].value,
"right": self.region["right"].value,
"bottom": self.region["bottom"].value,
},
}
json.dump(data, f, ensure_ascii=False, indent=2)
def main():
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Пример QLineEdit:
from dataclasses import dataclass
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
import sip
@dataclass
class Property:
qobject: QtCore.QObject = None
qproperty: str = ""
@property
def value(self):
if self.qobject and not sip.isdeleted(self.qobject):
return self.qobject.property(self.qproperty)
@value.setter
def value(self, value):
if self.qobject and not sip.isdeleted(self.qobject):
self.qobject.setProperty(self.qproperty, value)
def main():
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QLineEdit()
prop = Property(w, "text")
# variable for test
counter = 0
def on_timeout():
nonlocal counter
print("text:", prop.value)
counter += 1
prop.value = counter
timer = QtCore.QTimer(interval=1000, timeout=on_timeout)
timer.start()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()