带有 c++ 的图形用户界面.当我使用按钮时滞后
GUI with c++. lagged when i use button
我是 GUI C++新手,正在修改随机器发送给我的代码,我想在单击按钮时进行 while 循环,我尝试了线程,它仍然卡住了。
void CDlgWriteEPC::loop()
{
// Do something
}
void CDlgWriteEPC::OnBnClickedOk()
{
std::thread loadingThread(&CDlgWriteEPC::loop, this);
loadingThread.join();
}
join 会阻止当前线程,直到另一个线程完成,所以这没有帮助。您应该启动工作线程,立即返回和工作线程完成后应该发送某种消息。
示例代码中的函数名称似乎来自 MSVC++ MFC应用程序,因此我们将使用它。
简而言之,Windows GUI 应用程序是事件驱动的,每次事件发生时,都会发生发送WM_MESSAGE。框架接收这些消息并调用相应的函数来处理它。我们可以定义自己的消息和消息处理程序。这样,工作线程可以将此类消息发送到框架,它将调用我们的处理程序函数。
WM_APP被定义为私人用户消息的起点,因此不会有与现有系统消息的任何冲突。
(https://msdn.microsoft.com/en-us/library/windows/desktop/ms644930%28v=vs.85%29.aspx)
因此,假设我们正在构建一个 MFC 对话框应用程序,用于搜索文件中的某些内容。如果文件很大,则可能需要很长时间,并防止阻塞主线程和收到"窗口没有响应"消息,我们需要在工作线程中执行此操作。我们可能会例如,还需要一个进度条。
首先,我们在现有的 dialog 类中定义我们自己的消息,从 WM_APP + 1 开始我们添加处理程序函数,这些函数必须属于以下类型: afx_msg LRESULT (CWnd::*)(WPARAM, LPARAM)
WPARAM 和 LPARAM 是发布消息时传递的参数,您可以使用它们发送自定义数据。在我们的示例中,我们可以使用它们来发送进度条的进度百分比。
(https://msdn.microsoft.com/en-us/library/k35k2bfs.aspx)
class CMyAppDlg : public CDialogEx
{
public:
//Public so the worker thread class can use these same sames when posting a message.
enum Messages
{
MSG_ThreadProgress = WM_APP + 1,
MSG_ThreadDone
};
private:
afx_msg LRESULT OnThreadProgress(WPARAM wParam, LPARAM lParam)
{
ProgressBar->SetPos(wParam); //Worker thread posts progress as wParam
};
afx_msg LRESULT OnThreadDone(WPARAM wParam, LPARAM lParam)
{
//Get result from worker thread class and use it...
};
};
然后我们需要将我们的消息和处理程序添加到消息映射中,您应该将它们添加到已经对话框/文档的.cpp文件中的现有消息映射。
BEGIN_MESSAGE_MAP(CMyAppDlg, CDialogEx)
ON_MESSAGE(MSG_ThreadProgress, &CMyAppDlg::OnThreadProgress)
ON_MESSAGE(MSG_ThreadDone, &CMyAppDlg::OnThreadDone)
END_MESSAGE_MAP()
现在我们可以简单地将这些消息发布在我们的工作线程中,框架主线程将处理消息并更新进度条或使用结果:
class ThreadClass
{
public:
//Constructor takes a reference to our dialog class because we need the window handle
//to post a message
ThreadClass(CMyAppDlg& MyAppDlg) : mMyAppDlg(MyAppDlg) {};
void operator()() //Thread worker code...
{
while (what_we_look_for_not_found)
{
int Progress = 0;
//Search for a while and update progress variable...
//Post message to dialog asking it to update the progressbar
PostMessage(mMyAppDlg.m_hWnd, CMyAppDlg::MSG_ThreadProgress, Progress, 0);
}
//Finished searching...
StoreResult();
//Post message to dialog informing it thread is done and result can be retrieved.
PostMessage(mMyAppDlg.m_hWnd, CMyAppDlg::MSG_ThreadDone, 0, 0);
}
private:
CMyAppDlg& mMyAppDlg;
};
QT使用与SIGNAL和SLOT类似的系统,其他框架肯定有自己的等效系统。如果您使用的是MSVC++ MFC以外的其他东西,您应该能够在手册中找到更多信息。
- 问:如何使用C++中的按钮从窗口打开窗口
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- QML按钮点击功能执行顺序
- 当用户超过按钮点击限制时报告
- 函数计算用户按下按钮的频率
- 热键/按钮,根据需要进行编译,但不运行(在F5和Ctrl+Shift+B之间)
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- 垂直方向的 Gtk3+ 旋转按钮 (c/c++)
- Qt自定义QPush按钮未显示在布局上
- SDL 操纵杆按钮按下/C++
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- Qt中来自不同功能的按钮引用
- WinAPI 在单击第一个对话框上的按钮控件并销毁第一个对话框后创建第二个对话框
- Win32 发送输入鼠标移动滞后并冻结
- ImGui 在单击按钮后冻结
- WinAPI 无法创建按钮
- 按钮悬停在 QT 中垂直布局的选项卡小部件中不起作用
- 带有 c++ 的图形用户界面.当我使用按钮时滞后
- 按钮的巨大"Grid"严重滞后,按钮无法启用