下面的代码创建一个带有日期选择器的简单窗口,以及一个用于激活其余代码的按钮(尚不是最优雅的按钮,我在这里临时使用全局变量,以便可以访问“处理”脚本它们,这些将很快被删除)
问题是,当我创建MyWindow类的对象时,似乎根本无法在start_processing()
调用的函数中访问它。
import calendar
import os
from datetime import date
from glob import glob
from time import time
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QComboBox, QPushButton, QLabel, QErrorMessage
def start_processing():
start = time()
files_found: tuple = file_search(month, year, r'O:\test\1 Originals')
for i in files_found:
process_file(i)
duration = time() - start
window1.set_text(f'Generation of files took {duration:.1f} seconds!')
class MyWindow(object):
def __init__(self):
self.app = QApplication([])
self.progress = QLabel('Foo')
self.title = 'Bar'
self.left = 10
self.top = 10
self.width = 300
self.height = 300
self.error_dialog = QErrorMessage()
self.setup_ui()
def setup_ui(self):
self.app.setStyle('Fusion')
window = QWidget()
layout = QVBoxLayout()
combobox_month = QComboBox()
combobox_year = QComboBox()
layout.addWidget(self.progress)
layout.addWidget(combobox_month)
layout.addWidget(combobox_year)
combobox_month.addItems(calendar.month_name[1:13])
combobox_year.addItems(['2017', '2018', '2019', '2020'])
combobox_year.setToolTip('Select the year')
combobox_month.setToolTip('Select the month')
combobox_month.setCurrentText('January')
combobox_year.setCurrentText('2019')
process_button = QPushButton('Process')
layout.addWidget(process_button)
window.setLayout(layout)
combobox_month.currentTextChanged.connect(self.on_combobox_month_changed)
combobox_year.currentTextChanged.connect(self.on_combobox_year_changed)
process_button.clicked.connect(self.on_button_clicked)
window.setGeometry(self.left, self.top, self.width, self.height)
window.setWindowTitle(self.title)
window.show()
self.app.exec_()
@staticmethod
def on_button_clicked():
start_processing()
@staticmethod
def on_combobox_month_changed(text):
global month
month_lookup = {v: k for k, v in enumerate(calendar.month_name)}
month = month_lookup[text]
@staticmethod
def on_combobox_year_changed(text):
global year
year = int(text)
def set_text(self, text):
self.progress.setText(text)
self.app.processEvents()
def error_message(self, text):
self.error_dialog.showMessage(text)
if __name__ == '__main__':
window1 = MyWindow()
如果我随后尝试window1.set_text('Blah')
,则在函数start_processing()
中会得到一个NameError: name 'window1' is not defined
。
start_processing是在脚本的主体中定义的,除此类中所包含的功能外,所有功能都已定义。
不确定我需要发布整个脚本的多少,但很高兴添加其他内容。
答案 0 :(得分:1)
在window1 = MyWindow()
完全完成执行之前,语句window1
不会真正为变量MyWindow()
赋值。 MyWindow()
必须先执行__init__()
,然后才能完成执行。但是首先setup_ui
必须完成执行。但是首先exec_
必须完成执行。但是exec_
会无限期地阻塞,只要窗口保持打开状态即可。因此,当用户单击按钮并触发on_button_clicked
时,window1
将没有值。
一种可能的解决方案是移动exec_
调用,这样__init__()
不会直接或间接调用它。例如,您可以在创建MyWindow()
之后立即在文件级范围内调用它。
if __name__ == '__main__':
window1 = MyWindow()
window1.app.exec_()