连续相机采集伴随着 dm-script 的无模式对话框

Continious camera acquisition accompanied with a modeless dialog by dm-script

我想制作一个连续获取相机图像的DM脚本,比如VIEW模式。在我的计划中,当按下位于 UIframe 对话框的 START 按钮时,将开始连续的相机采集;并且还同时显示了一个无模式对话框。当按下对话框中的 OK 按钮时,连续 aciition 停止。对于这种脚本,我认为需要一个后台线程。但是,我对这样的背景了解不够运行。

如果您分享一些智慧,我们将不胜感激。非常感谢您。

连续摄像头采集实际上与脚本中的后台线程无关,而是需要将硬件设置为连续读取模式。 到目前为止,官方脚本 API 不支持此功能。

但是,存在扩展的、面向对象的脚本 API,它可以更深入地控制相机。您需要通晓 DM 脚本的面向对象编码风格才能使用它,并且您需要联系 Gatan 才能访问此脚本 API,因为它不受官方支持.

为此,您可能需要使用 Gatan 主页上的 support-request form。 (页面底部的按钮)

采纳 kachigusa 对我的另一个回答的评论....

如果你想运行伪连续地减慢相机采集,即通过在单独的线程上执行重复的单个读出,那么你可能想要使用结构如下:

class CMyBackgroundAction
{
    number isRunning
    CMyBackgroundAction(object self) { isRunning = 0; }     // Initialisation in constructor

    // methods to access flag from outside the object
    void StopRunning(object self) { isRunning  = 0; }
    number GetIsRunning(object self) { return isRunning; }

    // The stuff that should run in the background until the flag is set
    void RunUntilBreak(object self)
    {
        Result("\n\n StartRunning")
        isRunning = 1
        while (isRunning)
        {
            Result( "\n New line..." )
            sleep(0.5)
            Result( "....done" )
        }
        Result("\n\n FINISHED")
    }
}

class CmyDLG : UIframe
{
    object backGroundRunObj

    void OnStartStop( object self )
    {
        if ( !backGroundRunObj.GetIsRunning() )
        {
            // Nothing running in the background yet.
            backGroundRunObj.StartThread( "RunUntilBreak" )
            self.LookUpElement("StartStopButton").DLGTitle("Stop")
        }
        else
        {
            // It exists, so it is running. Just set the break-flag
            backgroundRunObj.StopRunning();
            self.LookUpElement("StartStopButton").DLGTitle("Start")
        }
    }

    TagGroup BuildDLG( object self )
    {
        TagGroup dlg, dlgitems
        dlg = DLGCreateDialog("StartStop",dlgItems)
        dlgItems.DLGAddElement( DLGCreatePushButton( "Start", "OnStartStop" ).DLGIdentifier("StartStopButton" ) )
        return dlg
    }
    Object Init(object self)
    {
        backGroundRunObj = Alloc(CMyBackgroundAction)
        self.super.Init( self.BuildDLG() )
        return self
    }
}

Alloc(CmyDLG).Init().Display("Test")

当然还有其他几个构造,它们带有一个对话框来管理一个单独的线程。这只是一个例子。

如果您要 start/stop 某些以非常规律的间隔执行但需要主线程的东西 - 另一种选择是 register/deregister 来自对话框的周期性任务。这是一个例子:

class CMyBackgroundAction
{
    // The stuff that should run periodically
    void RunUntilBreak(object self)
    {
        Result("\n Doing action @" + GetTime(1) )
    }
}

class CmyDLG : UIframe
{
    object backGroundRunObj
    number taskID

    void OnStartStop( object self )
    {
        if ( 0 == taskID )
        {
            // Start by registering the task ( every 0.5 sec)
            taskID = AddMainThreadPeriodicTask(backGroundRunObj,"RunUntilBreak",0.5)
            Result("\n STARTED ")
            self.LookUpElement("StartStopButton").DLGTitle("Stop")
        }
        else
        {
            // Stop by removing the task
            RemoveMainThreadTask( taskID )
            Result("\n STOPPED ")
            taskID = 0
            self.LookUpElement("StartStopButton").DLGTitle("Start")
        }
    }

    TagGroup BuildDLG( object self )
    {
        TagGroup dlg, dlgitems
        dlg = DLGCreateDialog("StartStop",dlgItems)
        dlgItems.DLGAddElement( DLGCreatePushButton( "Start", "OnStartStop" ).DLGIdentifier("StartStopButton" ) )
        return dlg
    }
    Object Init(object self)
    {
        backGroundRunObj = Alloc(CMyBackgroundAction)
        taskID = 0
        return self.super.Init( self.BuildDLG() )
    }
}

Alloc(CmyDLG).Init().Display("Test")