我希望有一个简单的图形界面来控制Python中长计算中使用的变量。让我解释一下这个问题,并在MATLAB中展示一个我更了解的解决方案。我是python的初学者。
我有一个使用变量f
的函数x
。
function f
x = 1;
for n = 1:10
fprintf('%f\n', x)
pause(1)
end
end
我希望能够在计算过程中使用图形界面更改x
的值。在Matlab中,这可以相对简明地完成。我首先需要使x
成为global
变量,然后使用更新x
的简单回调创建一个小部件。最终的代码是:
function computation_with_gui
% the main function simply creates the control and calls f.
uicontrol('Style', 'slider', 'Min', 0, 'Max', 100, 'Position', [0 0 400 20], 'Callback', @callback)
f();
end
function callback(h, d)
% the callback simply updates x
global x
x = h.Value;
end
function f
% function f now declares x as global
global x
x = 1;
for n = 1:10
fprintf('%f\n', x)
pause(1)
end
end
上面的脚本显示一个滑块(可能是另一个小部件,这里不重要)并启动计算。在计算过程中滑块不会冻结,我可以使用它来控制x
显示的f
的值。最后,程序在f
完成时停止。总的来说,将这个简单的图形界面添加到f
所需的代码实际上是最小的。
我的问题是,如何在Python中做类似的事情?在本案中,我显然赞成简明扼要。我倾向于使用PyQt5(仅仅因为它配备了我的配置),但是如果另一个框架能够实现更简洁的东西,那也没关系。同样,如果使事情变得更容易,那么小部件将不是滑块。
答案 0 :(得分:0)
您可以执行与MATLAB中非常相似的操作。我将调整PyQt slider example中的TutorialsPoint来演示:
import sys, threading, time
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QLabel, QSlider, QVBoxLayout, QWidget
x = 1
class GUI(QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self.slider = QSlider(Qt.Horizontal)
self.slider.setMinimum(0)
self.slider.setMaximum(100)
self.slider.setValue(x)
self.slider.setTickPosition(QSlider.TicksBelow)
self.slider.setTickInterval(5)
layout = QVBoxLayout()
layout.addWidget(self.slider)
self.setLayout(layout)
self.slider.valueChanged.connect(self.valuechange)
def valuechange(self):
global x
x = self.slider.value()
def process(gui):
for n in range(10):
print(x)
time.sleep(1)
gui.close()
def main():
app = QApplication(sys.argv)
gui = GUI()
gui.show()
threading.Thread(target=process, args=(gui,)).start()
sys.exit(app.exec())
if __name__ == '__main__':
main()
如您所见,这里有一些差异。首先,任务必须在后台线程中启动,因为主线程将被app.exec
阻止。另一方面,处理函数需要有一种让GUI知道它已完成的方法,我通过传入对GUI窗口的引用来实现。
虽然使用全局变量通常是一个坏主意,但我在这里使用它作为MATLAB代码的直接翻译。