无限循环 - >需要显示Qt的主屏幕
这里我又来了! 因此,我正在用C++开发一个GBC模拟器,但我遇到了一些问题。首先,我在VS10中使用Qt,到目前为止工作很好。但是,我有我的GUI(主窗口)与几个对象(QListWidget,按钮等)。所以,在我的CPU类中,我有一个模拟所有GBC指令的循环。它以一种简单的方式工作。获取代码,解码,获取并在开关中调用操作,重新执行。所以,我的问题是,在每种情况下,我都想让主屏幕显示更新列表。无限循环 - >需要显示Qt的主屏幕
下面的图片,我不能张贴原因我没有10个rep点。 http://i.stack.imgur.com/BdaHo.png
因此,一段代码,这样你就可以(试试吗?)了解怎么回事:(cpu.cpp)
next:
op = FETCH;
setSelection((UINT32)op);
ciclos = cycles_table[op];
switch(op)
{
do the magic
emit onEndProcess((UINT32)op);
goto next;
}
cpu.h
signals:
void onEndProcess(UINT32);
其接收通过ratagbc (ratagbc.h)
public slots:
void receivedEndProcess(UINT32);
而实现:
void RataGBC::receivedEndProcess(UINT32 i){
this->ui.listWidget->item(i+1)->setSelected(true);
this->show();
}
而且在比例构造,ui.setupUI(...)后,我有:
cpp = new cpu();
connect(cpp,SIGNAL(onEndProcess(UINT32)),this,SLOT(receivedEndProcess(UINT32)));
}
其中CPP是CPU类的一个实例。这里有一个问题,这个连接返回false!我注意到
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
RataGBC w;
dasm dsm;
FILE *file = fopen("Tetris DX.gbc","r");
int c = 0;
while(dsm.DAsm(file,w.ui.listWidget,c));
fclose(file);
w.cpp->start();
w.show();
return a.exec();
}
一件事是,我需要实现(空白)onEndProcess我cpu.cpp,或者它给我链接错误。它真的有必要吗?
希望你们能明白我的需要! 谢谢!
您试图在同一个线程中运行两个“无限循环”。一个是你的CPU循环,显然会阻塞。另一个是Qt事件循环,在你退出应用程序之前它将会阻塞。
我可能在这里是错误的,因为我从来没有实现过一个CPU模拟器,但 - 尽管可能 - 我认为你不应该在与GUI相同的线程中运行CPU循环,因为CPU很紧且可能对定时波动敏感。
相反,你应该在一个单独的线程中运行的CPU,并使用queued slots其他多线程结构,如QMutex,QAtomicInt和QAtomicPointer GUI线程和交流。
以下是我将如何实现它(很显然你应该适应吧):
GUI线程
这是你运行QApplication::exec()
。
- 构建主窗口(与列表和绘图表面)
- 启动CPU线程
- 每当输入事件发生时,信号的变化与CPU线程
- 每当CPU线程更新视频缓冲器,更新图纸表面
- 当用户退出,停止CPU线程
ç PU线程
执行新的QThread执行以下操作。
- 取指,译码,执行
- 读取输入时,它被更新
- 写显存,并通知GUI线程更新绘图表面
- 当被告知退出。
请记住,只有GUI线程可以操纵UI小部件,如列表和菜单。 CPU线程应该使用诸如排队插槽之类的机制来告诉GUI线程更新小部件。
为什么该帖子得到-1?尽管我没有足够的知识来判断这是否是最好的答案,而且参考答案似乎至少是合理的。因此,也许有人可能会帮助我理解坏品质在哪里...... – Thilo 2012-02-29 21:10:06
@Thilo:因为它不必要的复杂,而且过于复杂的解决方案会浪费开发时间,这会花费时间和金钱。记住KISS原则。程序员的工作不是提供最复杂的解决方案,而是最便宜的解决方案。在这种情况下,实际上不需要另外的线程和可能会出现的同步问题/错误。没有线程,你可以用20行或更少的代码实现整个事情。 – SigTerm 2012-02-29 21:17:24
这是一个有效的观点。不过,我认为我的答案是:在同一线程中运行CPU和GUI会使CPU受到事件循环时序波动的影响。如果准确性不是问题,我的建议确实有点矫枉过正。也就是说,Qt中的多线程编程非常简单,尤其是使用库提供的结构。 – andref 2012-02-29 21:25:39
使用具有0超时的QTimer执行空闲处理。
使QObject(将你的“模拟CPU”存储在其中)插槽,连接到定时器信号,并在该插槽中一次处理一个程序(RagaGBC)的一步。即执行你模拟程序的一个步骤。或者几个步骤,但不是全部。启动计时器以启动模拟程序。
完成后,请致电QCoreApplication::exit();
。
如果您不明白如何制作QObject /使用计时器,请阅读Qt教程。
我不明白你的意思。我应该将QApplication作为参数传递给cpu吗?哪些步骤?谢谢 ! – Leonardo 2012-02-29 19:44:02