Class 类与自定义对话框一起使用时,DM无法识别该类

Class 类与自定义对话框一起使用时,DM无法识别该类,class,customdialog,dm-script,Class,Customdialog,Dm Script,那里 我正在修改一个DM脚本来读取hdf5文件。有一个名为“MetaStr2TagGroup”的用户定义类。它在脚本中运行良好 我正在尝试构建一个自定义对话框,以便以一种简单的方式为用户提供更多选项。自定义对话框可以很好地处理我的测试,而不需要实际的脚本部分 当我将类为“MetaStr2TagGroup”的脚本放在自定义对话框脚本的前面时,就会出现问题。它仍然运行以提供一个对话框并允许所有操作。但一旦我要求它运行脚本,它就会给我一条错误消息“找不到名为‘metastr2taggroup’的类”,

那里

我正在修改一个DM脚本来读取hdf5文件。有一个名为“MetaStr2TagGroup”的用户定义类。它在脚本中运行良好

我正在尝试构建一个自定义对话框,以便以一种简单的方式为用户提供更多选项。自定义对话框可以很好地处理我的测试,而不需要实际的脚本部分

当我将类为“MetaStr2TagGroup”的脚本放在自定义对话框脚本的前面时,就会出现问题。它仍然运行以提供一个对话框并允许所有操作。但一旦我要求它运行脚本,它就会给我一条错误消息“找不到名为‘metastr2taggroup’的类”,但该类仍然位于整个脚本的前面

我不明白,有人能解释一下为什么会发生这种情况,以及如何避免这种情况吗

我的简化代码结构如下所示。根据BmyGuest的评论,我添加了对象局部辅助对象局部辅助对象=Alloc(辅助对象)。到目前为止还不起作用

Class Helper{
    functions1(){}
    functions2(){}
    TagGroup functions3(){
        Call function 1 and function 2}
}
Function4()   {
    Call function3()
}
Function5(){}
Function6(){
    Call function4()
}

class Converter : UIframe   {
    **object Local_helper**
    Action1(){}
    Action2()   {
        **local_Helper = Alloc( Helper )**
        Call Function6()
    }
}

TagGroup MakeFields1{}
TagGroup MakeFields2{}

//Main start here
Call MakeField1()
Call MakeField2()
object dialog_frame = alloc(Converter).init()

您遇到的问题是,“UIframe”对话框是在不同的线程上创建的。按下对话框按钮时,原始“脚本”不再在范围内(仅对话框对象在范围内)

因此以下代码无法正常运行:

class CHelper
{
    void DoStuff2( object self ) { OKDialog( "Action!" ); }
}

class CMyDialog : UIframe
{
    void DoStuff( object self )
    {
        Result( "\n Running method from other class: " )
        Alloc( CHelper ).DoStuff2()
    }

    object Init( object self )
    {
        TagGroup dlg, dlgItems
        dlg = DLGCreateDialog( "Test", dlgItems )
        dlgItems.DLGAddElement( DLGCreatePushButton( "Do Action", "DoStuff" ) )
        return self.super.init( dlg )
    }
}

Alloc( CMyDialog ).Init().Display( "My DLG" )
class CHelper
{
    void DoStuff2( object self ) { OKDialog( "Action!" ); }
}

class CMyDialog : UIframe
{
    object localHelper
    void DoStuff( object self )
    {
        Result( "\n Running method from other class: " )
        localHelper.DoStuff2()
    }

    object Init( object self )
    {
        localHelper = Alloc( CHelper )
        TagGroup dlg, dlgItems
        dlg = DLGCreateDialog( "Test", dlgItems )
        dlgItems.DLGAddElement( DLGCreatePushButton( "Do Action", "DoStuff" ))
        return self.super.init( dlg )
    }
}

Alloc( CMyDialog ).Init().Display( "My DLG" )
您可以做的是在创建UI对象时分配第二类的对象。这可以在UIclass的构造函数方法中完成,也可以将代码放入Init()方法中。现在,第二个对象在范围内(因为它是dialog对象的一部分),您可以直接使用它:

此代码运行正常:

class CHelper
{
    void DoStuff2( object self ) { OKDialog( "Action!" ); }
}

class CMyDialog : UIframe
{
    void DoStuff( object self )
    {
        Result( "\n Running method from other class: " )
        Alloc( CHelper ).DoStuff2()
    }

    object Init( object self )
    {
        TagGroup dlg, dlgItems
        dlg = DLGCreateDialog( "Test", dlgItems )
        dlgItems.DLGAddElement( DLGCreatePushButton( "Do Action", "DoStuff" ) )
        return self.super.init( dlg )
    }
}

Alloc( CMyDialog ).Init().Display( "My DLG" )
class CHelper
{
    void DoStuff2( object self ) { OKDialog( "Action!" ); }
}

class CMyDialog : UIframe
{
    object localHelper
    void DoStuff( object self )
    {
        Result( "\n Running method from other class: " )
        localHelper.DoStuff2()
    }

    object Init( object self )
    {
        localHelper = Alloc( CHelper )
        TagGroup dlg, dlgItems
        dlg = DLGCreateDialog( "Test", dlgItems )
        dlgItems.DLGAddElement( DLGCreatePushButton( "Do Action", "DoStuff" ))
        return self.super.init( dlg )
    }
}

Alloc( CMyDialog ).Init().Display( "My DLG" )

另一种选择是将“第二”类作为库安装。这样,它总是可以分配的。但是,我不建议使用这种解决方案。

很抱歉,如果这个问题越来越广泛(另一个答案是对您的问题的“简短”答案,可能会成为“可接受的”答案)。不过,我将在这里回答并解释有关示例代码的内容


在第一步中,我将修改伪代码,使其语法正确:

如果您执行此代码,它将“运行”,但它不会做很多有用的事情。但是,它更像你的代码吗?下面列出了我所做的一些更改以及一些通用的“面向对象编码”信息,正如您在评论中指出的,您可能没有正确理解这个概念。所以请原谅,如果我说的是你已经知道的话。(我保持简单。):

  • 任何方法(类构造函数/析构函数除外)都需要返回类型,即使它只是
    void

  • 任何类方法都需要类型为
    object
    的第一个参数,它是该类对象的自引用。这是惯例 调用
    self
    来反映这一点,但这不是要求

  • 当您用所有脚本代码声明一个“类”时,实际上根本不使用该代码。仅当您分配新对象时(使用 “alloc”)您实际上“创建”了一个包含代码的对象。只有 在这一点上,它确实存在于内存中。如果你分配两个 不同的对象,您有两个“不同”的代码集(如 启动脚本两次),以便在 类,则需要指定该方法应属于哪个对象 打电话!这就是在所有面向对象编码中使用
    self
    变量的原因

  • 我还将“main”脚本放入了一个单独的方法中,我不想在这里详细介绍,但您应该知道,当您在脚本的主级别上创建
    对象类型的变量时,它将而不是在脚本完成时超出范围。该对象将保留在内存中!如果在任何
    {
    }
    节中定义它,那么一旦该节完成,它将超出范围

好的,回到你的例子。让我先“优化”一些东西。虽然可以将“全局”方法(即在主脚本级别上定义的方法)与“类方法”(即在类中定义的方法)相结合,但除非有充分的理由,否则我通常会避免使用它。通常,我们的目标是将属于一个对象的所有代码封装到该对象的类中。我假设您的“MakeFields”方法用于创建UI的对话框布局?如果是这样的话,把它放到课堂上!我通常会这样做:

Class myDLG : UIFrame {
    taggroup CreateDlgTgs( object self ){
        taggroup dlg,dlgItems
        dlg = DLGCreateDialog( "Mine", dlgItems )
        dlgItems.DLGAddElement( DLGCreateLabel( "Label" ) )
        return dlg
    }
    object MyInit( object self ){
        taggroup dlg = self.CreateDlgTgs()
        self.Init( dlg )
        return self
    }
}

void main(){
    object myDLG = Alloc( myDLG ).MyInit()
    myDLG.Pose()
}
main()
但是我会通过不创建一个新的
MyInit
来“简化”它,而是保持它的简单性
Init
。如果我自己的
Init
方法的签名与默认的
UIframe:Init
不同-也就是说,如果有任何附加参数-那么代码实际上不会更改。但是如果我使用相同的签名,我需要调用对象的
父方法。这就是为什么会出现
super
关键字。它表示我不想调用类MyDialog:Init的
Init
,而是要调用MyDialog父类的
Init
。因此,代码变成:

Class myDLG : UIFrame {
    [...]
    object Init( object self ){
        taggroup dlg = self.CreateDlgTgs()
        object dlgObj = self.super.Init( dlg )
        return dlgObj
    }
}

void main(){
    object myDLG = Alloc( myDLG ).Init()
    myDLG.Pose()
}
main()
接下来,请注意
Init()
的返回值是脚本对象本身。通过此操作,以及直接使用其他返回值,可以将事情简化为:

Class myDLG : UIFrame {
    [...]
    object Init( object self ){
        return self.super.Init( self.CreateDlgTgs() )
    }
}

void main(){
    Alloc( myDLG ).Init().Pose()
}
main()
更详细地查看分配行:

  • Alloc
    创建该类型的对象。该命令返回对象
  • 要调用类的
    Init
    方法,需要使用对象作为第一个参数,因为签名
    object Init(object self)
    。但是,第一个参数可以方便地写在命令前面,命令之间用点隔开。以下两个是等效的:
    ShowImage(img)
    img.ShowImage
    
    Class myDLG : UIFrame {
        [...]
    
        void RunAll( object self ) {
        self.Init().Pose()
        }
    }
    
    Alloc( myDLG ).RunAll()
    
    Class Helper{
        void functions1( object self ){ OKDialog("F1"); }
        void functions2( object self ){ OKDialog("F2"); }
        TagGroup functions3( object self ){
            self.functions1()
            self.functions2()
        }
        void Function4( object self ){
            self.functions3()
        }
        void functions5( object self ){ OKDialog("F5"); }
        void Function6( object self ){
            self.function4()
        }
    }
    
    class Converter : UIframe   {
    
        object Local_helper
        void Action1( object self ){ OKDialog("A1"); }
        void Action2( object self ){
            local_Helper = Alloc( Helper )
            local_Helper.function6()
        }
        TagGroup MakeFields1( object self ){
            return NewTagGroup(); 
        }
        TagGroup MakeFields2( object self ){ 
            return NewTagGroup(); 
        }
    }
    
    //Main start here
    void main()
    {
        object dialog_frame = alloc(Converter)
        dialog_frame.MakeFields1()
        dialog_frame.MakeFields2()
        dialog_frame.init()
    }