Qt在主线程上运行lambda
Qt run lambda on main thread
在我的应用程序中,我有一个工作线程通过文件列表迭代,我试图更新GUI表视图,以指示当前文件是什么。在我的工作线程中,当我启动一个新文件时,我有以下行:
emit runOnGui([this,row](){ui.tblFiles->selectRow(row);});
其中runOnGui是一个信号,通过:
connect(this, &MainWindow::runOnGui, [this](function<void()> action){
action();
});
我的理解是action()现在应该在UI线程上运行,但有时,并非总是如此,这对我来说是分段的。反向跟踪看起来像:
#0 0x00007ffff537c28a in ?? () from /usr/lib/libQt5Core.so.5
#1 0x00007ffff537cf23 in ?? () from /usr/lib/libQt5Core.so.5
#2 0x00007ffff537d047 in ?? () from /usr/lib/libQt5Core.so.5
#3 0x00007ffff5376943 in QItemSelection::merge(QItemSelection const&, QFlags<QItemSelectionModel::SelectionFlag>) () from /usr/lib/libQt5Core.so.5
#4 0x00007ffff5379e43 in QItemSelectionModel::select(QItemSelection const&, QFlags<QItemSelectionModel::SelectionFlag>) () from /usr/lib/libQt5Core.so.5
#5 0x00007ffff6d97511 in ?? () from /usr/lib/libQt5Widgets.so.5
#6 0x0000000000465193 in MainWindow::<lambda()>::operator()(void) const (__closure=0x7fffda262710) at <...>/MainWindow.cpp:248
#7 0x00000000004682c8 in std::_Function_handler<void(), MainWindow::pushFiles()::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...) at /usr/include/c++/6.2.1/functional:1740
#8 0x0000000000472722 in std::function<void ()>::operator()() const (this=0x7fffda262710) at /usr/include/c++/6.2.1/functional:2136
#9 0x0000000000463798 in MainWindow::MainWindow(QWidget*)::{lambda(std::function<void ()>)#1}::operator()(std::function<void ()>) const () at <...>/MainWindow.cpp:34
#10 0x0000000000469a32 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<std::function<void()> >, void, MainWindow::MainWindow(QWidget*)::<lambda(std::function<void()>)> >::call(MainWindow::<lambda(std::function<void()>)> &, void **) (f=..., arg=0x7fffda2628e0) at /usr/include/qt/QtCore/qobjectdefs_impl.h:501
#11 0x000000000046977b in QtPrivate::Functor<MainWindow::MainWindow(QWidget*)::<lambda(std::function<void()>)>, 1>::call<QtPrivate::List<std::function<void()> >, void>(MainWindow::<lambda(std::function<void()>)> &, void *, void **) (f=..., arg=0x7fffda2628e0) at /usr/include/qt/QtCore/qobjectdefs_impl.h:558
#12 0x0000000000468d8c in QtPrivate::QFunctorSlotObject<MainWindow::MainWindow(QWidget*)::<lambda(std::function<void()>)>, 1, QtPrivate::List<std::function<void()> >, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=1, this_=0x7cc630, r=0x7fffffffe500, a=0x7fffda2628e0, ret=0x0) at /usr/include/qt/QtCore/qobject_impl.h:198
#13 0x00007ffff53ed85e in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/libQt5Core.so.5
#14 0x000000000047a669 in MainWindow::runOnGui(std::function<void ()>) (this=0x7fffffffe500, _t1=...) at <...>/moc_MainWindow.cpp:128
#15 0x0000000000465617 in MainWindow::pushFiles (this=0x7fffffffe500) at <...>/MainWindow.cpp:248
#16 0x0000000000476d14 in std::__invoke_impl<void, void (MainWindow::* const&)(), MainWindow*>(std::__invoke_memfun_deref, void (MainWindow::* const&)(), MainWindow*&&) ( __f=@0xa35080: (void (MainWindow::*)(MainWindow * const)) 0x4651ea <MainWindow::pushFiles()>, __t=<unknown type in <...>/simtool, CU 0x16a5cd, DIE 0x1cbd99>) at /usr/include/c++/6.2.1/functional:235
#17 0x0000000000476ca1 in std::__invoke<void (MainWindow::* const&)(), MainWindow*>(void (MainWindow::* const&)(), MainWindow*&&) ( __fn=@0xa35080: (void (MainWindow::*)(MainWindow * const)) 0x4651ea <MainWindow::pushFiles()>, __args#0=<unknown type in <...>/simtool, CU 0x16a5cd, DIE 0x1cbd99>) at /usr/include/c++/6.2.1/functional:260
#18 0x0000000000476c52 in std::_Mem_fn_base<void (MainWindow::*)(), true>::operator()<MainWindow*>(MainWindow*&&) const (this=0xa35080, __args#0=<unknown type in <...>/simtool, CU 0x16a5cd, DIE 0x1cbd99>) at /usr/include/c++/6.2.1/functional:613
#19 0x0000000000476c1d in std::_Bind_simple<std::_Mem_fn<void (MainWindow::*)()> (MainWindow*)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0xa35078) at /usr/include/c++/6.2.1/functional:1400
#20 0x0000000000476b37 in std::_Bind_simple<std::_Mem_fn<void (MainWindow::*)()> (MainWindow*)>::operator()() ( this=0xa35078) at /usr/include/c++/6.2.1/functional:1389
#21 0x0000000000476ad6 in std::thread::_State_impl<std::_Bind_simple<std::_Mem_fn<void (MainWindow::*)()> (MainWindow*)> >::_M_run() (this=0xa35070) at /usr/include/c++/6.2.1/thread:196
#22 0x00007ffff4e6e31f in std::execute_native_thread_routine (__p=0xa35070) at /build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:83
#23 0x00007ffff743f454 in start_thread () from /usr/lib/libpthread.so.0
#24 0x00007ffff45e27df in clone () from /usr/lib/libc.so.6
知道为什么会发生分段错误吗?
Misc信息:
- Qt 5.7 Arch Linux 4.7.4
- gcc 6.2.1
在信号/槽连接中自动跨越线程边界需要一个接收器对象,以便发出代码可以检查当前线程是否等于或不同于接收器的线程。
您可以尝试使用connect变体,它将引用对象作为第三个参数,或者使用QMetaObject::invokeMethod()
调用插槽,并显式地声明Qt::QueuedConnection
作为连接类型。
。
QMetaObject::invokeMethod(ui.tblFiles, "selectRow", Qt::QueuedConnection, Q_ARG(int, row));
相关文章:
- 运行同一解决方案的另一个项目的项目
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 代码在main()中运行,但在函数中出现错误
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- AWS Lambda C++运行时权限被拒绝
- 如何使用 SAM 在本地运行C++ AWS Lambda 函数?
- Lambda 捕获此函数和长时间运行的函数
- 析构函数在 lambda 捕获说明符中声明的类实例上运行两次
- 为什么我的全球外部lambda变量在运行时不初始化
- AWS Lambda C 在SAM中的运行时
- 在 QWidgets 线程的实例上运行 lambda 函数槽
- 如何立即运行lambda
- 运行时的C++lambda实现
- 安全地移动在访问其他成员的成员线程中运行 lambda 的对象
- Qt在主线程上运行lambda
- 如果lambda在运行时被移动/销毁,会发生什么