> On Dec 6, 2019, at 10:03 AM, Jason H <jh...@gmx.com> wrote:
> 
> Do you processing function in C++, in a QThread or QRunnable.
> Have Python start the execution of that function in compiled code.
> At the end of processing have it signal the results to the main thread.
>  
> This means moving your work funtion into C++, and probably translating 
> between Qt and python types (Shiboken should automate this I think?)

So if I am understanding you correctly, you are suggesting re-writing all the 
python processing code in C++? Yeah, that’s not going to happen. :-)

As far as “translating between Qt and python types”, considering that my python 
type is a Pandas data frame, I’d be surprised if there was a good/easy way to 
do this.

If it helps clarify the problem, the “large data structures” I mention are 
Pandas Data Frames, and the processing is not a simple loop, but rather an 
extended series of manipulations of said data frames. I’m not even sure I want 
to think about what it would take to port this to C++ :-D…

Some of the sample code I am dealing with, if it helps:

        so2_int_peak_centre_record = [self.mstr_df['record'][x] for x in 
self.so2_int_peak_centre_indx]
        h2s_int_peak_centre_record = [self.mstr_df['record'][x] for x in 
self.h2s_int_peak_centre_indx]
        co2_licor_peak_centre_record = [self.mstr_df['record'][x] for x in 
self.co2_licor_peak_centre_indx]

        # -------trig calculations to work out distance around arc between 
points
        right_angle_rad = 1.571
        self.contour_df['dUTMx'] = self.contour_df['UTMx'].shift(1) - 
self.contour_df['UTMx']
        self.contour_df['dUTMy'] = self.contour_df['UTMy'].shift(1) - 
self.contour_df['UTMy']
        self.contour_df['dist_from_prev'] = 
distance_from_prev(self.contour_df['dUTMx'], self.contour_df['dUTMy'])
        self.contour_df['dist_from_prev'].fillna(0, inplace=True)  # infill NaN 
with 0
        self.contour_df['beta_rad'] = np.arctan(self.contour_df['dUTMx'] / 
self.contour_df['dUTMy'])
        self.contour_df['beta_rad'].fillna(0, inplace=True)  # infill NaN with 0
        self.contour_df['a'] = np.radians(self.wind_azimuth) - 
self.contour_df['beta_rad'] + right_angle_rad
        self.contour_df['len_cos_a'] = self.contour_df['dist_from_prev'] * 
abs(np.cos(self.contour_df['a']))

        # ------trig calculations to work out absolute distance between points 
and wind centroid
        self.contour_df['delta_utmx_volc'] = self.contour_df['UTMx'] - 
self.volcano_utmx
        self.contour_df['delta_utmy_volc'] = self.contour_df['UTMy'] - 
self.volcano_utmy
        self.contour_df['volc_theta'] = 
np.degrees(np.arctan(abs(self.contour_df['delta_utmx_volc']) / 
abs(self.contour_df['delta_utmy_volc'])))
        self.contour_df['volc_azimuth'] = np.nan

        for i in range(self.contour_df.index[0], self.contour_df.index.max()):
            dx = self.contour_df['delta_utmx_volc'][i]
            dy = self.contour_df['delta_utmy_volc'][i]

            if dx > 0 and dy > 0:
                self.contour_df['volc_azimuth'][i] = 
self.contour_df['volc_theta'][i]

            elif dx > 0 > dy:
                self.contour_df['volc_azimuth'][i] = 180 - 
self.contour_df['volc_theta'][i]

            elif dx < 0 and dy < 0:
                self.contour_df['volc_azimuth'][i] = 180 + 
self.contour_df['volc_theta'][i]

            elif dx < 0 < dy:
                self.contour_df['volc_azimuth'][i] = 360 - 
self.contour_df['volc_theta'][i]

            if i % 50 == 0:
                self.yield_thread()

        self.contour_df['volc_dist'] = 
np.sqrt((self.contour_df['delta_utmy_volc']**2) + 
(self.contour_df['delta_utmx_volc']**2))  # distance from point to volcano

This goes on for almost 200 lines. That one for loop there, simple as it is, 
takes about half a second to complete (even without the yield_thread in there). 
And this is just a portion of one of four similar functions I am trying to run. 
So yeah, not porting to C any time soon :-)

>  
>  
> To clarify the original objective:
>  
> Given that:
> A) python threads can not execute simultaneously due to the GIL (unless one 
> thread releases the GIL, which does not appear to be the case in my code, or 
> perhaps due to something with PySide), AND
> B) my code does not lend itself to using multiprocessing rather than 
> threading due to the large data structures involved (thus the reason the 
> calculations take a while) -
>  
> How can I keep the GUI responsive while the calculations proceed?
>  
> So far the only solution I have come up with is to periodically call 
> QApplication.processEvents() on the main thread from within my calculation 
> code, but that is ugly and, according to everything I see online, indicative 
> of a bad design. As I don’t want a bad design, what is the alternative? Or is 
> this simply one of the rare cases where that *is* the correct answer?
>  

_______________________________________________
PySide mailing list
PySide@qt-project.org
https://lists.qt-project.org/listinfo/pyside

Reply via email to