SharpCap 4.1 Beta Update - 28th December 2022

Discussions, Bug Reports and Issues related to Beta versions of SharpCap
Jean-Francois
Posts: 402
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: SharpCap 4.1 Beta Update - 28th December 2022

#11

Post by Jean-Francois »

Hello Robin,

Happy New Year too !

I did some test with the last 4.1 version.
One error comes from the Python script ... some modules can not be imported (csv, os, time).

In the SharpCap directory, I can open the "PythonLib.zip" file and the files csv.py, os.py and time.py are present.
But ... in the 4.0 version the zip-file is ~ 5.5 MB, in the 4.1 version only ~ 3.9 MB.

Regards,
Jean-Francois
User avatar
admin
Site Admin
Posts: 13347
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: SharpCap 4.1 Beta Update - 28th December 2022

#12

Post by admin »

Hi Jean-Francois,

that's an odd one. I updated Iron Python to 2.7.12 (from 2.7.11) for the beta, which I wasn't expecting to give any significant issues. The size difference seems to be that the new version of the library does not contain 2 large 'whl' files, but they seem to be related to pip (in a folder called 'ensurepip') so I don't think they are relevant to the issue here.

I will investigate.

cheers,

Robin
Jean-Francois
Posts: 402
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: SharpCap 4.1 Beta Update - 28th December 2022

#13

Post by Jean-Francois »

Hello Robin,

Thanks for the investigation.
I try the following: I copy the file PythonLib.zip from the version 4.0 in the 4.1 directory ... the same effect.

I did in the past hours some programming of my LED-GPS calibration script.
But, sometimes I do not understand why "simple" things are not working.
It was the try to change the text of the "starting" button during the calibration process and then to change the text again at the end of the process.
It was not possible ... all the time it was the "final" status from the beginning of the process.

Regards,
Jean-Francois
User avatar
admin
Site Admin
Posts: 13347
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: SharpCap 4.1 Beta Update - 28th December 2022

#14

Post by admin »

Hi Jean-Francois,

it was a weird bug due to the installation (worked fine on my development machine, but a problem when installed). I have had to put some more DLLs onto the disk as individual files rather than having them packed into a larger container file, since it was the loading them from the packed container that somehow caused the problem.

Will be fixed in the next update :)

cheers,

Robin
Jean-Francois
Posts: 402
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: SharpCap 4.1 Beta Update - 28th December 2022

#15

Post by Jean-Francois »

Hello Robin,

Thanks.
Do you remark that the IronPython 3.4 is finally released ?

Regards,
Jean-Francois
User avatar
admin
Site Admin
Posts: 13347
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: SharpCap 4.1 Beta Update - 28th December 2022

#16

Post by admin »

Hi Jean-Francois,

good spot - I had not seen that. I will investigate bringing that in to SharpCap in the near future, so be ready to update your scripts to Python3 :D

cheers,

Robin
Jean-Francois
Posts: 402
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: SharpCap 4.1 Beta Update - 28th December 2022

#17

Post by Jean-Francois »

Hello,

OK, Yee ! super more script work :-)

May be you can quick solve a small script problem ?

Here a small code:

Code: Select all

import time
import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")

from System.Drawing import Color, Font, FontStyle, Point
from System.Windows.Forms import Application, Button, CheckBox, Form, FormStartPosition, Label, Panel, RadioButton, TextBox

class CalibrationLEDMenuForm(Form):
    def __init__(self):
        self.Text = "LED Calibration"
        self.Width = 400
        self.Height = 150
        self.setupCheckButtons()
        self.TopMost = True

    def setupCheckButtons(self):
        self.Cal_LED = Button()
        self.Cal_LED.Text = "Start Calibration LED"
        self.Cal_LED.Location = Point(25, 25)
        self.Cal_LED.Click += self.calib_led
        self.Cal_LED.AutoSize = True

        self.button_Exit = Button()
        self.button_Exit.Text = "Exit"
        self.button_Exit.Location = Point(250, 25)
        self.button_Exit.Click += self.exit
        self.button_Exit.AutoSize = True

        self.Controls.Add(self.Cal_LED)
        self.Controls.Add(self.button_Exit)

    def calib_led(self, sender, event):
        self.Cal_LED.Text = "Calibration"
        self.Cal_LED.BackColor = Color.Red
        time.sleep(2)
        self.Cal_LED.Text = "Start Calibration LED"
        self.Cal_LED.BackColor = Color.Gray

    def exit(self, sender, event):
        print("Stop LED calibration script")
        self.Close()

form = CalibrationLEDMenuForm()
form.StartPosition = FormStartPosition.CenterScreen
form.Show()
It starts a small window with 2 buttons.
The idea is that after clicking on the button "Start Calibration LED", the color and the text of the button change during a process (here wait 2 seconds), and then after the process, the button change again the color and the text.

It is not working as expected ... during the 2 sec ... nothing change. The button change only after the end of the process.
If you have an idea to modify it, please help me.

Regards,
Jean-Francois
User avatar
admin
Site Admin
Posts: 13347
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: SharpCap 4.1 Beta Update - 28th December 2022

#18

Post by admin »

Hi Jean-Francois,

yes, what is happening is (I think) that your button press handler is sleeping betweent the first change and the second. Because of this, it is not processing windows messages in the UI thread, which stops the effects of the colour change from being shown on the screen.

There are a few ways around this, one quick but dirty way is to make a call to

Code: Select all

System.Windows.Forms.Application.DoEvents()
at strategic places in the code (ie after the first colour change).

Another would be to make the button handler change the colour once and then set up a System.Windows.Forms.Timer to fire after 2 seconds, and in the timer handler, change the colour the second time.

Hope this helps,

Robin
Jean-Francois
Posts: 402
Joined: Sun Oct 13, 2019 10:52 am
Location: Germany

Re: SharpCap 4.1 Beta Update - 28th December 2022

#19

Post by Jean-Francois »

Hello Robin,

Yes, it helps ... for the simple example :-)

But now the more "advanced" example ...

Code: Select all

import time
import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")

from System.Drawing import Color, Font, FontStyle, Point
from System.Windows.Forms import Application, Button, CheckBox, Form, FormStartPosition, Label, Panel, RadioButton, TextBox
from System.Threading import Thread, ThreadStart, ApartmentState


def LED_Calibration():
    time.sleep(2)

def Test_Thread():
    th = Thread(ThreadStart(LED_Calibration))
    th.SetApartmentState(ApartmentState.STA)
    th.Start()

class CalibrationLEDMenuForm(Form):
    def __init__(self):
        self.Text = "LED Calibration"
        self.Width = 400
        self.Height = 150
        self.setupCheckButtons()
        self.TopMost = True

    def setupCheckButtons(self):
        self.Cal_LED = Button()
        self.Cal_LED.Text = "Start Calibration LED"
        self.Cal_LED.Location = Point(25, 25)
        self.Cal_LED.Click += self.calib_led
        self.Cal_LED.AutoSize = True

        self.button_Exit = Button()
        self.button_Exit.Text = "Exit"
        self.button_Exit.Location = Point(250, 25)
        self.button_Exit.Click += self.exit
        self.button_Exit.AutoSize = True

        self.Controls.Add(self.Cal_LED)
        self.Controls.Add(self.button_Exit)

    def calib_led(self, sender, event):
        self.Cal_LED.Text = "Calibration"
        self.Cal_LED.BackColor = Color.Red
        System.Windows.Forms.Application.DoEvents()
        Test_Thread()
        self.Cal_LED.Text = "End Calibration LED"
        self.Cal_LED.BackColor = Color.Gray

    def exit(self, sender, event):
        print("Stop LED calibration script")
        self.Close()

form = CalibrationLEDMenuForm()
form.StartPosition = FormStartPosition.CenterScreen
form.Show()
The script is for the LED calibration of the QHY-174-GPS camera ... you give me some code for a process in a separate thread (so that the live image of the LED calibration is visible during the calibration).
But now, the color change is so quick between Red and Gray, that the button is not "red" during the calibration process.
I tried to have the change of the button color in the LED_Calibration() function. But it was not possible to "transfer" the (self) in the Test_Thread() function.


Regards,
Jean-Francois
User avatar
admin
Site Admin
Posts: 13347
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: SharpCap 4.1 Beta Update - 28th December 2022

#20

Post by admin »

Hi,

unfortunately the whole area of getting mutlithreaded applications to work correctly with Windows UI is not simple, and it's made harder by the fact that you are trying to do it in IronPython, so there are fewer samples and examples out there to work from.

Test_Thread will return pretty much instantly - it starts the new thread but does not wait for it to complete. You can wait for a thread with .Join(), but that is usually a bad idea - it will often lock the UI and make it unresponsive.

The correct way to do this is to use the Form class to get back onto the right thread after the worker thread completes its work. In C# you would have something like this as a method on the Form

Code: Select all

        public void WorkFinished()
        {

            if (InvokeRequired)
            {
                BeginInvoke(new Action(WorkFinished));
                return;
            }
            
            // do stuff that needs to happen in the UI thread, like change colours of buttons, re-enable them, etc
        }
You can call WorkFinished from the UI thread or a background thread - if it is the UI thread then 'InvokeRequired' will be true, so it will call 'BeginInvoke' which will call the function again, but make it run on the UI thread. The bottom half of the function will run on the UI thread.

This should translate to IronPython with a sprinking of 'self.' , and you will need to import Action from System if it is not already imported.

Then you make your thread function a member of the form (or at least have access to the form) so you can call 'WorkFinished' after the sleep() in the thread function.

Hope this helps,

Robin
Post Reply