【问题标题】:How to continue after signal emission?信号发射后如何继续?
【发布时间】:2017-02-02 17:18:28
【问题描述】:

我正在用 Qt quick 和 C++ 构建一个黑白棋游戏。 我使用 QML 对话框中的这段代码开始新游戏,当一个玩家是人类时,我等待输入。当两个玩家是PC时,我面临GUI将等待插槽完成的问题,在PC玩家中插槽调用flipTurn()(因为是PC,没有输入等待),flipTurn是递归的,所以GUI 会一直阻塞直到游戏结束。 我希望它在每次移动后更新电路板。项目链接: reversi project

myBroker.createGame(blacktypebutton.checkedButton.playertype,
                                                   whitetypebutton.checkedButton.playertype,
                                                    getBlackAlgo(),
                                                    getWhiteAlgo(),
                                                    getBlackDep(),
                                                    getWhiteDep());
                                console.log("finished creating game !");

void Broker::flipTurn()
{
    if(someoneWon()){
        emit gameEnd();
        return;
    }
    emit updateBoard();
    if (currentGame->getTurn() == Constants::BLACK){
        currentGame->setTurn(Constants::WHITE);
        if (currentGame->getWhitePlayer().getType() == Constants::PC){
            currentGame->pcMove(Constants::WHITE);
            flipTurn();
        }
        else
            currentGame->updatePossible();


    }
    else{
        currentGame->setTurn(Constants::BLACK);
        if (currentGame->getBlackPlayer().getType() == Constants::PC){
            currentGame->pcMove(Constants::BLACK);
            flipTurn();
        }
        else
            currentGame->updatePossible();
        return;
    }
    emit updateBoard();

} 

bool Broker::createGame(int blacktype, int whitetype, int blackalg, int whitealg, int blackdep, int whitedep)
{
    currentGame = new Game(blacktype,whitetype,blackalg,whitealg,blackdep,whitedep);
    currentGame->setGameBoard(&gameBoard);
    updatePossible();
    emit gameStart();
}

void Broker::onGameStart()
{
    if(currentGame->getTurnType() == Constants::PC){
        currentGame->pcMove(currentGame->getTurn());
        cout<<"in ongamestart slot"<<endl;

        flipTurn();
    }
} 

【问题讨论】:

  • 我觉得这个程序应该是多线程的,分成GUI部分和AI部分。
  • 您不应该像在所有其他框架中一样,通过连续操作阻止 GUI 线程。将所有这些操作移至不同的线程,在 QML 中您可以使用 WorkerScript 或 C++ 中的 QThread
  • 我不认为这是一个需要线程的问题
  • 我考虑过多线程,但我没有找到任何好的教程,其中包含展示如何构建此类东西的示例,任何展示如何构建 GUI 并将其从逻辑中分离出来的教程都将被接受。

标签: qt qml signals qtquick2


【解决方案1】:

由于它是一个回合制游戏,你只需要一个不同的来源来触发下一个回合。

不是直接调用flipTurn(),而是通过Qt的事件循环调用它。

因为您可能希望计算机前的人看到游戏的进展,很可能会有延迟。

例如使用单次计时器

// instead of calling flipTurn() directly
QTimer::singleShot(500, this, SLOT(flipTurn()));

500 毫秒后调用下一个flipTurn()

【讨论】:

  • 试过了,没用 :( 我现在用 :QCoreApplication::processEvents(); 它可以很好地在每次 PC 转动后显示棋盘,但我无法退出游戏,我可以点击按钮 (虽然有延迟,因为我每次PC玩时都使用sleep(1)),但程序没有退出,因为游戏还没有结束。
  • 不要在主线程上使用睡眠。并且“没有”工作并不能提供信息来猜测可能是什么问题
【解决方案2】:

我用过

QCoreApplication::processEvents();

在每次调用 flipTurn() 之后,GUI 引擎会处理任何等待信号(在我的例子中是 updateBoard() 信号)。 虽然这不是最好的解决方案,但它对我的家庭作业很有效。

【讨论】:

    猜你喜欢
    • 2018-05-19
    • 1970-01-01
    • 2020-09-20
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    相关资源
    最近更新 更多