簡體   English   中英

Pyside2 QGuiApplication, Gui 凍結按鈕單擊

[英]Pyside2 QGuiApplication, Gui freeze on button Clicked

我正在使用 QML、Pyside2 和 QGuiApplication 編寫桌面應用程序,問題是當我單擊任何按鈕 Gui 凍結、代碼執行並且 Gui 返回正常 state 時。 我搜索並發現問題是我的應用程序的單線程。 所以我試着讓它多線程我試過:

QGuiApplication.processEvents()

和:

app = QGuiApplication()
app.processEvents()

在 pyQT5 我知道這是答案並處理問題:

QApplication.processEvents()

正如文檔所說,鏈接function:

processEvents()

應該工作但不工作!

這是我的 Qml 調用 function:

RoundButton{
     icon.source :"icons/baseline_play_arrow_black_48dp"
     onClicked: DataVisClass.road_analysis()
}

這是 DataVisClass.py:

from PySide2.QtCore import QObject, Slot
from PySide2.QtGui import QGuiApplication

class DataVis(QObject):
    def __init__(self,app):
        super().__init__()
        self.app = app
        self.roadAnalyser = RoadAnalyser()

    @Slot()
    def road_analysis(self):
        self.roadAnalyser.centrality(True, True, 'Piedmont, California, USA', "drive_service", "betweenness_centrality", self.app)

和 RoadAnalyser.py:

class RoadAnalyser:
    def centrality(self, logs, use_cache, place, net_type, alg_type, app):
        app.processEvents()
        QGuiApplication.processEvents()
        ox.config(log_console=logs, use_cache=use_cache)
        # place = 'Piedmont, California, USA'
        G = ox.graph_from_address(place, network_type=net_type)
        # G = ox.graph_from_address(place, network_type='drive_service')

        gdf = ox.gdf_from_place(place)
        area = ox.projection.project_gdf(gdf).unary_union.area

        # calculate basic and extended network stats, merge them together, and display
        stats = ox.basic_stats(G, area=area)
        extended_stats = ox.extended_stats(G, ecc=True, bc=True, cc=True)
        for key, value in extended_stats.items():
            stats[key] = value
            QGuiApplication.processEvents()
        pd.Series(stats)

        G_projected = ox.project_graph(G)
        max_node, max_bc = max(extended_stats[alg_type].items(), key=lambda x: x[1])
        # max_node, max_bc = max(extended_stats['betweenness_centrality'].items(), key=lambda x: x[1])
        print("Best node is : ",max_bc,max_node)

        # nc = get_node_colors_by_stat(G_projected, data=extended_stats['betweenness_centrality'])
        nc = get_node_colors_by_stat(G_projected, data=extended_stats[alg_type])
        # for each in nc :
        #     print(each)
        fig, ax = ox.plot_graph(G, fig_height=6, node_color=nc, node_size=20, node_zorder=2,
                                edge_linewidth=2, edge_color='#333333', bgcolor='k')
        # for each in extended_stats['betweenness_centrality'].items():
        #     print(each)

謝謝

耗時的任務不應該在主線程中運行,因為它們阻塞了事件循環,其中一個效果是凍結。 解決方案是在另一個線程中運行它:

  • 刪除與“app”或 QXApplication 相關的所有內容,因為它是不必要的

    class RoadAnalyser: def centrality(self, logs, use_cache, place, net_type, alg_type): ox.config(log_console=logs, use_cache=use_cache) # place = 'Piedmont, California, USA' G = ox.graph_from_address(place, network_type=net_type) # G = ox.graph_from_address(place, network_type='drive_service') gdf = ox.gdf_from_place(place) area = ox.projection.project_gdf(gdf).unary_union.area # calculate basic and extended network stats, merge them together, and display stats = ox.basic_stats(G, area=area) extended_stats = ox.extended_stats(G, ecc=True, bc=True, cc=True) for key, value in extended_stats.items(): stats[key] = value pd.Series(stats) G_projected = ox.project_graph(G) max_node, max_bc = max(extended_stats[alg_type].items(), key=lambda x: x[1]) # max_node, max_bc = max(extended_stats['betweenness_centrality'].items(), key=lambda x: x[1]) print("Best node is: ", max_bc, max_node) # nc = get_node_colors_by_stat(G_projected, data=extended_stats['betweenness_centrality']) nc = get_node_colors_by_stat(G_projected, data=extended_stats[alg_type]) # for each in nc: # print(each) fig, ax = ox.plot_graph( G, fig_height=6, node_color=nc, node_size=20, node_zorder=2, edge_linewidth=2, edge_color="#333333", bgcolor="k", )
  • 使用 threading.Thread

     import threading class DataVis(QObject): def __init__(self, app): super().__init__() self.app = app self.roadAnalyser = RoadAnalyser() @Slot() def road_analysis(self): threading.Thread( target=self.roadAnalyser.centrality, args=( True, True, "Piedmont, California, USA", "drive_service", "betweenness_centrality", ), ).start()

更新

如果要從線程發送信息,則必須使用信號

class DataVis(QObject):
    fooSignal = Signal(str)

    # ...

    @Slot()
    def road_analysis(self):

        threading.Thread(
            target=self.roadAnalyser.centrality,
            args=(
                True,
                True,
                "Piedmont, California, USA",
                "drive_service",
                "betweenness_centrality",
                self.fooSignal
            ),
        ).start()
class RoadAnalyser:
    def centrality(self, logs, use_cache, place, net_type, alg_type, signal):
        # ...
        signal.emit("foo")
Connections{
    target: DataVisClass
    function onFooSignal(msg){
         console.log(msg)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM