使用stage出错的问题。

本文介绍了在使用ActionScript 3时遇到的TypeError:Error#1009问题,并提供了有效的解决方案。通过正确地使用stage属性并确保显示对象已添加到显示列表中,可以避免这一错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[color=red][转][/color]
  这两天看AS3 cookbook和AS3的帮助文档,里面很多代码执行后都会出现“TypeError: Error #1009: 无法访问空对象引用的属性或方法。”这个错误。几经周折,才知道解决办法:使用addEventListener( Event.ADDED_TO_STAGE, enterDLHandle ),把要用的stage代码放到enterDLHandle里面,就没问题了。不知道有没有其他解决方法,知道的说声啊~

在经典论坛上提问这个问题,终于有人做出全面回答了,在此感谢zjs35

首先要明白stage是什么意思,stage是显示对象的一个引用舞台的属性,如果显示对象不在显示列表中,即没有用addChild()添加,stage等于null,你的问题就在这里。
使用stage有下面几种方法:
1、文档类的构造函数中可以直接使用stage属性
2、非文档类可以通过参数传递到类里面。
class Test extends Shape
{
function Test(stage:Stage)
{
}
}
3、不想传递参数时,要注意代码的顺序。
class Test extends Shape
{
function Test()
{
}
functon useStage()
{
trace(stage)
}
}
这样使用
var test=new Test()
test.useStage()//null,你的问题出在这里
addChild(test)//添加到显示列表后,就可以使用stage属性。
test.useStage()//[object Stage]
总之,理解stage是显示对象的属性,位于显示列表中的显示对象的stage才引用舞台
import sys import json import os import copy # 添加copy模块用于深拷贝 from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QListWidget, QLabel, QDialog, QLineEdit, QTextEdit, QComboBox, QMessageBox, QTabWidget, QToolBar, QAction, QTreeWidget, QTreeWidgetItem, QSplitter, QStatusBar, QToolButton, QStackedWidget, QDateEdit, QListWidgetItem, QCheckBox, QFormLayout, QScrollArea, QSizePolicy) from PyQt5.QtCore import Qt, QSize, QDate from PyQt5.QtGui import QIcon, QFont, QColor, QPalette, QBrush, QLinearGradient class WorkflowManager(QMainWindow): def init(self): super().init() self.setWindowTitle(“工作流程管理器”) self.resize(1000, 650) self.workflows = [] self.current_workflow = None self.current_stage_index = 0 self.load_workflows() # 设置主窗口样式 self.setStyleSheet(""" QMainWindow { background-color: #f8f9fa; font-family: 'Segoe UI', 'Arial', sans-serif; } /* 其他样式保持变 */ """) # 创建主界面 self.create_main_ui() # 加载默认工作流程 if self.workflows: self.current_workflow = self.workflows[0] self.update_workflow_display() def create_main_ui(self): """创建主界面""" # ... [此部分代码保持变] ... def load_workflows(self): """加载工作流程并处理兼容性""" if os.path.exists("workflows.json"): try: with open("workflows.json", "r") as f: self.workflows = json.load(f) # 兼容旧数据结构:将字符串成果物转换为对象 for workflow in self.workflows: for stage in workflow["stages"]: if stage.get("artifacts") and isinstance(stage["artifacts"][0], str): stage["artifacts"] = [{"name": name, "completed": False} for name in stage["artifacts"]] except Exception as e: print(f"加载工作流程时出错: {e}") self.workflows = [] else: # 创建默认工作流程 - 使用新数据结构 default_workflow = { "name": "软件开发变更流程", "description": "标准的软件开发变更管理流程", "stages": [ {"name": "变更点分析", "description": "分析客户提供的变更需求", "color": "#4e73df", "artifacts": [{"name": "需求分析文档", "completed": False}], "completed": False}, # ... [其他阶段保持变] ... ], "tasks": [] } self.workflows.append(default_workflow) self.save_workflows() def save_workflows(self): """保存工作流程""" try: with open("workflows.json", "w") as f: json.dump(self.workflows, f, indent=4) self.status_bar.showMessage("工作流程已保存", 2000) except Exception as e: QMessageBox.critical(self, "保存错误", f"保存工作流程时出错: {str(e)}") def update_workflow_display(self): """更新工作流程显示""" if not self.current_workflow: # 清空显示 self.flow_title.setText("无选中的工作流程") self.clear_flow_stages() self.artifacts_label.setText("成果物检查") self.artifacts_list.clear() self.status_info.setText("") self.update_buttons_state() return # ... [此部分代码保持变] ... def clear_flow_stages(self): """清空流程阶段显示""" while self.flow_stages.count(): item = self.flow_stages.takeAt(0) if item.widget(): item.widget().deleteLater() def create_stage_widget(self, stage, index): """创建单个阶段显示组件""" # ... [此部分代码保持变] ... def darken_color(self, hex_color, percent): """使颜色变暗指定百分比""" # ... [此部分代码保持变] ... def select_workflow(self, item): """选择工作流程""" if not item: return self.current_workflow = item.data(0, Qt.UserRole) self.current_stage_index = 0 self.update_workflow_display() self.update_artifacts_display() def select_stage(self, index): """选择阶段""" if not self.current_workflow or index < 0 or index >= len(self.current_workflow["stages"]): return # ... [此部分代码保持变] ... def prev_stage(self): """返回上一阶段""" if not self.current_workflow or self.current_stage_index <= 0: return self.current_stage_index -= 1 self.update_workflow_display() self.update_artifacts_display() self.status_bar.showMessage(f"已返回阶段: {self.current_workflow['stages'][self.current_stage_index]['name']}", 2000) def next_stage(self): """进入下一阶段""" if not self.current_workflow or self.current_stage_index >= len(self.current_workflow["stages"]) - 1: return # ... [此部分代码保持变] ... def update_buttons_state(self): """更新按钮状态""" if not self.current_workflow: self.prev_stage_btn.setEnabled(False) self.next_stage_btn.setEnabled(False) return # ... [此部分代码保持变] ... def new_workflow(self): """新建工作流程""" dialog = WorkflowDialog(self) if dialog.exec_() == QDialog.Accepted: new_workflow = dialog.get_workflow() if new_workflow: # 确保获取到有效的工作流程 self.workflows.append(new_workflow) self.current_workflow = new_workflow self.current_stage_index = 0 self.save_workflows() self.update_workflow_display() self.update_artifacts_display() def edit_workflow(self): """编辑工作流程""" if not self.current_workflow: QMessageBox.warning(self, "警告", "请先选择一个工作流程!") return dialog = WorkflowDialog(self, self.current_workflow) if dialog.exec_() == QDialog.Accepted: edited_workflow = dialog.get_workflow() if edited_workflow: # 确保获取到有效的工作流程 index = self.workflows.index(self.current_workflow) self.workflows[index] = edited_workflow self.current_workflow = edited_workflow self.save_workflows() self.update_workflow_display() self.update_artifacts_display() def delete_workflow(self): """删除当前工作流程""" if not self.current_workflow: QMessageBox.warning(self, "警告", "请先选择一个工作流程!") return reply = QMessageBox.question( self, '确认删除', f"确定要删除工作流程【{self.current_workflow['name']}】吗?\n此操作可恢复!", QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.Yes: try: # 从工作流程列表中移除当前工作流程 self.workflows.remove(self.current_workflow) # 更新当前选中的工作流程 if self.workflows: self.current_workflow = self.workflows[0] self.current_stage_index = 0 else: self.current_workflow = None self.current_stage_index = -1 # 保存更改并更新界面 self.save_workflows() self.update_workflow_display() self.update_artifacts_display() self.status_bar.showMessage(f"工作流程已删除", 2000) except Exception as e: QMessageBox.critical(self, "删除错误", f"删除工作流程时出错: {str(e)}") def update_artifacts_display(self): """更新成果物显示并恢复状态""" self.artifacts_list.clear() if not self.current_workflow or self.current_stage_index < 0: self.artifacts_label.setText("成果物检查") self.status_info.setText("") return try: current_stage = self.current_workflow["stages"][self.current_stage_index] self.artifacts_label.setText(f"成果物检查 - {current_stage['name']}") for artifact in current_stage.get("artifacts", []): item = QListWidgetItem() widget = QWidget() layout = QHBoxLayout(widget) layout.setContentsMargins(10, 5, 10, 5) checkbox = QCheckBox(artifact["name"]) checkbox.setChecked(artifact["completed"]) checkbox.setStyleSheet("font-size: 19px;") checkbox.stateChanged.connect(lambda state, a=artifact: self.update_artifact_status(a, state)) layout.addWidget(checkbox) item.setSizeHint(widget.sizeHint()) self.artifacts_list.addItem(item) self.artifacts_list.setItemWidget(item, widget) # 更新状态信息 self.update_stage_status() except Exception as e: print(f"更新成果物显示时出错: {e}") def update_artifact_status(self, artifact, state): """更新成果物状态""" if not self.current_workflow: return try: artifact["completed"] = (state == Qt.Checked) self.update_stage_status() except Exception as e: print(f"更新成果物状态时出错: {e}") def update_stage_status(self): """更新阶段状态""" if not self.current_workflow or self.current_stage_index < 0: return try: current_stage = self.current_workflow["stages"][self.current_stage_index] artifacts = current_stage.get("artifacts", []) total_artifacts = len(artifacts) completed_artifacts = sum(1 for a in artifacts if a["completed"]) # 更新状态文本 if total_artifacts == 0: status_text = "当前阶段没有成果物" status_color = "#6c757d" elif completed_artifacts == 0: status_text = "状态: 待开始 (0% 完成)" status_color = "#e74a3b" current_stage["completed"] = False elif completed_artifacts < total_artifacts: percent = (completed_artifacts / total_artifacts) * 100 status_text = f"状态: 进行中 ({percent:.0f}% 完成)" status_color = "#f6c23e" current_stage["completed"] = False else: status_text = "状态: 已完成 (100% 完成)" status_color = "#1cc88a" current_stage["completed"] = True self.status_info.setText(status_text) self.status_info.setStyleSheet(f""" font-size: 12px; font-weight: 500; color: white; background-color: {status_color}; padding: 6px; border-radius: 4px; margin-top: 8px; """) self.update_buttons_state() except Exception as e: print(f"更新阶段状态时出错: {e}") def show_stats(self): """显示统计信息""" if not self.current_workflow: return # ... [此部分代码保持变] ... class WorkflowDialog(QDialog): “”“工作流程编辑对话框”“” def init(self, parent=None, workflow=None): super().init(parent) self.setWindowTitle(“编辑工作流程” if workflow else “新建工作流程”) self.resize(600, 450) # 深拷贝工作流程数据,避免直接修改原始数据 self.workflow = copy.deepcopy(workflow) if workflow else { "name": "", "description": "", "stages": [], "tasks": [] } self.setup_ui() def setup_ui(self): """设置对话框UI""" layout = QVBoxLayout(self) layout.setContentsMargins(15, 15, 15, 15) # 标题 title_text = "编辑工作流程" if self.workflow.get("name") else "新建工作流程" title = QLabel(title_text) title.setStyleSheet("font-size: 16px; font-weight: 600; color: #4e73df; margin-bottom: 15px;") layout.addWidget(title) # 基本信息 form_layout = QFormLayout() form_layout.setLabelAlignment(Qt.AlignRight) form_layout.setVerticalSpacing(10) self.name_edit = QLineEdit(self.workflow["name"]) self.name_edit.setPlaceholderText("输入工作流程名称") form_layout.addRow("流程名称:", self.name_edit) self.desc_edit = QTextEdit(self.workflow["description"]) self.desc_edit.setPlaceholderText("输入工作流程描述") self.desc_edit.setFixedHeight(60) form_layout.addRow("流程描述:", self.desc_edit) layout.addLayout(form_layout) # 阶段管理 stages_label = QLabel("阶段管理") stages_label.setStyleSheet("font-size: 14px; font-weight: 600; color: #4e73df; margin-top: 15px; margin-bottom: 8px;") layout.addWidget(stages_label) # 阶段列表和编辑区 stages_container = QHBoxLayout() stages_container.setSpacing(15) # 阶段列表 stages_list_container = QVBoxLayout() self.stages_list = QListWidget() self.stages_list.setFixedHeight(150) self.update_stages_list() self.stages_list.itemSelectionChanged.connect(self.on_stage_selection_changed) stages_list_container.addWidget(self.stages_list) stages_container.addLayout(stages_list_container, 1) # 阶段编辑区 stage_edit_container = QVBoxLayout() self.stage_edit = QWidget() self.stage_edit.setStyleSheet("background-color: #f8f9fa; border-radius: 6px; padding: 10px;") stage_edit_layout = QFormLayout(self.stage_edit) stage_edit_layout.setVerticalSpacing(8) self.stage_name_edit = QLineEdit() self.stage_name_edit.setPlaceholderText("输入阶段名称") stage_edit_layout.addRow("阶段名称:", self.stage_name_edit) self.stage_desc_edit = QTextEdit() self.stage_desc_edit.setPlaceholderText("输入阶段描述") self.stage_desc_edit.setFixedHeight(50) stage_edit_layout.addRow("阶段描述:", self.stage_desc_edit) self.stage_color_edit = QComboBox() self.stage_color_edit.addItems(["#4e73df", "#1cc88a", "#36b9cc", "#f6c23e", "#e74a3b", "#6f42c1", "#fd7e14", "#20c997"]) stage_edit_layout.addRow("阶段颜色:", self.stage_color_edit) # 成果物编辑 artifacts_label = QLabel("成果物 (每行一个):") stage_edit_layout.addRow(artifacts_label) self.artifacts_edit = QTextEdit() self.artifacts_edit.setPlaceholderText("输入成果物名称,每行一个") self.artifacts_edit.setFixedHeight(80) stage_edit_layout.addRow(self.artifacts_edit) stage_edit_container.addWidget(self.stage_edit) # 阶段操作按钮 stage_btn_layout = QHBoxLayout() stage_btn_layout.setSpacing(8) self.add_stage_btn = QPushButton("添加") self.add_stage_btn.setStyleSheet("background-color: #1cc88a; color: white; padding: 5px;") self.add_stage_btn.clicked.connect(self.add_stage) stage_btn_layout.addWidget(self.add_stage_btn) self.update_stage_btn = QPushButton("更新") self.update_stage_btn.setStyleSheet("background-color: #4e73df; color: white; padding: 5px;") self.update_stage_btn.clicked.connect(self.update_current_stage) stage_btn_layout.addWidget(self.update_stage_btn) self.remove_stage_btn = QPushButton("删除") self.remove_stage_btn.setStyleSheet("background-color: #e74a3b; color: white; padding: 5px;") self.remove_stage_btn.clicked.connect(self.remove_stage) stage_btn_layout.addWidget(self.remove_stage_btn) stage_edit_container.addLayout(stage_btn_layout) stages_container.addLayout(stage_edit_container, 2) layout.addLayout(stages_container) # 对话框按钮 btn_layout = QHBoxLayout() btn_layout.setAlignment(Qt.AlignRight) btn_layout.setSpacing(10) save_btn = QPushButton("保存") save_btn.setStyleSheet("background-color: #4e73df; color: white; min-width: 80px; padding: 6px;") save_btn.clicked.connect(self.on_save) btn_layout.addWidget(save_btn) cancel_btn = QPushButton("取消") cancel_btn.setStyleSheet("background-color: #6c757d; color: white; min-width: 80px; padding: 6px;") cancel_btn.clicked.connect(self.reject) btn_layout.addWidget(cancel_btn) layout.addLayout(btn_layout) # 初始化选择 if self.stages_list.count() > 0: self.stages_list.setCurrentRow(0) def update_stages_list(self): """更新阶段列表显示""" self.stages_list.clear() for stage in self.workflow["stages"]: item = QListWidgetItem(stage["name"]) item.setData(Qt.UserRole, stage) self.stages_list.addItem(item) def on_stage_selection_changed(self): """当阶段选择变化时更新编辑区域""" current_item = self.stages_list.currentItem() if current_item: self.select_stage(current_item) else: self.clear_stage_edit() def select_stage(self, item): """加载选中阶段的数据到编辑区域""" stage = item.data(Qt.UserRole) self.stage_name_edit.setText(stage["name"]) self.stage_desc_edit.setText(stage["description"]) # 设置颜色 color_index = self.stage_color_edit.findText(stage["color"]) if color_index >= 0: self.stage_color_edit.setCurrentIndex(color_index) # 加载成果物 artifact_names = [a["name"] for a in stage.get("artifacts", [])] self.artifacts_edit.setText("\n".join(artifact_names)) def add_stage(self): """添加新阶段""" name = self.stage_name_edit.text().strip() if not name: QMessageBox.warning(self, "警告", "请输入阶段名称!") return # 从文本创建成果物对象 artifacts = [ {"name": a.strip(), "completed": False} for a in self.artifacts_edit.toPlainText().split("\n") if a.strip() ] new_stage = { "name": name, "description": self.stage_desc_edit.toPlainText().strip(), "color": self.stage_color_edit.currentText(), "artifacts": artifacts, "completed": False } self.workflow["stages"].append(new_stage) self.update_stages_list() # 选中新添加的阶段 self.stages_list.setCurrentRow(len(self.workflow["stages"]) - 1) QMessageBox.information(self, "成功", f"阶段 '{name}' 已添加!", QMessageBox.Ok) def update_current_stage(self): """更新当前选中的阶段""" current_item = self.stages_list.currentItem() if not current_item: QMessageBox.warning(self, "警告", "请先选择一个阶段!") return name = self.stage_name_edit.text().strip() if not name: QMessageBox.warning(self, "警告", "请输入阶段名称!") return stage = current_item.data(Qt.UserRole) stage["name"] = name stage["description"] = self.stage_desc_edit.toPlainText().strip() stage["color"] = self.stage_color_edit.currentText() # 更新成果物列表 artifact_names = [a.strip() for a in self.artifacts_edit.toPlainText().split("\n") if a.strip()] # 创建新的成果物列表,保留现有成果物的状态 new_artifacts = [] existing_artifacts = {a["name"]: a for a in stage.get("artifacts", [])} for name in artifact_names: # 如果成果物已存在,保留其状态 if name in existing_artifacts: new_artifacts.append(existing_artifacts[name]) else: # 新增成果物,默认状态为未完成 new_artifacts.append({"name": name, "completed": False}) stage["artifacts"] = new_artifacts # 更新阶段列表并刷新显示 current_row = self.stages_list.currentRow() self.update_stages_list() self.stages_list.setCurrentRow(current_row) # 重新加载当前阶段的信息到编辑区域 self.select_stage(self.stages_list.currentItem()) QMessageBox.information(self, "成功", f"阶段 '{name}' 已更新!", QMessageBox.Ok) def remove_stage(self): """删除当前阶段""" current_item = self.stages_list.currentItem() if not current_item: QMessageBox.warning(self, "警告", "请先选择一个阶段!") return stage_name = current_item.text() # 检查是否是该工作流程的唯一阶段 if len(self.workflow["stages"]) <= 1: QMessageBox.warning(self, "警告", "工作流程必须至少包含一个阶段!") return reply = QMessageBox.question(self, '确认删除', f"确定要删除阶段【{stage_name}】吗? 所有关联任务也将被删除!", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: stage = current_item.data(Qt.UserRole) # 删除关联任务 self.workflow["tasks"] = [task for task in self.workflow["tasks"] if task.get("stage") != stage["name"]] # 删除阶段 self.workflow["stages"].remove(stage) # 更新列表 self.update_stages_list() # 清空编辑区域 self.clear_stage_edit() # 自动选择下一个阶段(如果有) if self.stages_list.count() > 0: self.stages_list.setCurrentRow(0) else: self.clear_stage_edit() QMessageBox.information(self, "成功", f"阶段 '{stage_name}' 已删除!", QMessageBox.Ok) def clear_stage_edit(self): """清空阶段编辑区域""" self.stage_name_edit.clear() self.stage_desc_edit.clear() self.stage_color_edit.setCurrentIndex(0) self.artifacts_edit.clear() def get_workflow(self): """获取编辑后的工作流程""" # 确保在关闭对话框前更新当前选中的阶段 if self.stages_list.currentItem(): self.update_current_stage() return { "name": self.name_edit.text().strip(), "description": self.desc_edit.toPlainText().strip(), "stages": self.workflow["stages"], "tasks": self.workflow["tasks"] } def on_save(self): """保存工作流程前的验证和处理""" # 检查工作流程名称 if not self.name_edit.text().strip(): QMessageBox.warning(self, "警告", "工作流程名称能为空!") return # 检查阶段数量 if not self.workflow["stages"]: QMessageBox.warning(self, "警告", "工作流程必须包含至少一个阶段!") return # 检查阶段名称 for stage in self.workflow["stages"]: if not stage.get("name", "").strip(): QMessageBox.warning(self, "警告", "阶段名称能为空!") return # 确保在关闭对话框前更新当前选中的阶段 if self.stages_list.currentItem(): self.update_current_stage() # 所有检查通过,接受对话框 self.accept() def accept(self): """覆盖accept方法,确保数据有效""" super().accept() if name == “main”: app = QApplication(sys.argv) # 设置应用程序样式 app.setStyle("Fusion") palette = QPalette() palette.setColor(QPalette.Window, QColor(248, 249, 250)) palette.setColor(QPalette.WindowText, QColor(73, 80, 87)) palette.setColor(QPalette.Base, QColor(255, 255, 255)) palette.setColor(QPalette.AlternateBase, QColor(248, 249, 250)) palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255)) palette.setColor(QPalette.ToolTipText, QColor(73, 80, 87)) palette.setColor(QPalette.Text, QColor(73, 80, 87)) palette.setColor(QPalette.Button, QColor(248, 249, 250)) palette.setColor(QPalette.ButtonText, QColor(73, 80, 87)) palette.setColor(QPalette.BrightText, QColor(255, 255, 255)) palette.setColor(QPalette.Highlight, QColor(78, 115, 223)) palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255)) app.setPalette(palette) # 设置应用字体 app_font = QFont("Segoe UI", 9) app.setFont(app_font) manager = WorkflowManager() manager.show() sys.exit(app.exec_()) 此项目打开是一片空白,请检查
最新发布
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值