Pyside2 QGuiApplication,Gui 在按钮上冻结
Pyside2 QGuiApplication, Gui freeze on button Clicked
我正在使用 QML、Pyside2 和 QGuiApplication 编写桌面应用程序
问题是当我点击任何按钮时 Gui 冻结,代码执行和 Gui returns 到正常状态。
我搜索并发现问题是我的应用程序的单线程。
所以我试着让它成为多线程
我试过了:
QGuiApplication.processEvents()
和:
app = QGuiApplication()
app.processEvents()
在 pyQT5 中,我知道这就是答案并解决了问题:
QApplication.processEvents()
如文档所述link函数:
processEvents()
应该可以但不能用!
这是我的 Qml 调用函数:
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)
}
}
我正在使用 QML、Pyside2 和 QGuiApplication 编写桌面应用程序 问题是当我点击任何按钮时 Gui 冻结,代码执行和 Gui returns 到正常状态。 我搜索并发现问题是我的应用程序的单线程。 所以我试着让它成为多线程 我试过了:
QGuiApplication.processEvents()
和:
app = QGuiApplication()
app.processEvents()
在 pyQT5 中,我知道这就是答案并解决了问题:
QApplication.processEvents()
如文档所述link函数:
processEvents()
应该可以但不能用!
这是我的 Qml 调用函数:
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)
}
}