使用Qt开发中国象棋(三):走棋着法列表

        在一个完整的中国象棋游戏中,一般界面上都显示了中文着法,为了简单起见,我开发的这个用了两个着法列表,红方一个,黑方一个,其实用一个就够了,只是感觉那样稍微会麻烦些。着法列表显示了每一步的走棋。下图是着法列表的截图:

使用Qt开发中国象棋(三):走棋着法列表_第1张图片 使用Qt开发中国象棋(三):走棋着法列表_第2张图片

着法列表用的是一个叫StepList的类来实现的,因为有两个着法列表,所以用了两个StepList对象。实例化的时候,指定一个特殊的参数用来标示是左边的还是右边的。像下面那样。

    leftStepList = new StepList(this, true);
    rightStepList = new StepList(this, false);

       StepList类包括以下数据成员:

        一个QPixmap对象:用来标示是哪一方。

       一个QTableView指针对象:用于显示中文着法。

       一个QStandardItemModel指针对象:用于向tableView赋值。

      四个QPushButton指针对象:用于实现翻页和翻行功能。

       一个QLabel指针对象:用于显示当前页面信息。

       一个int类型成员:用于标示当前是第几步。在翻页和翻行中用到。

      一个QVector容器:用于保存所有的着法历史。

      有哪些成员函数,我就不介绍了,大家可以去看代码。

      关于tableView,下面是创建的代码:

void StepList::initTableView()
{
    tableView = new QTableView(this);
    tableView->move(0, 60);

    model = new QStandardItemModel(15, 3);
    model->setHeaderData(0, Qt::Horizontal, tr("序号"));
    model->setHeaderData(1, Qt::Horizontal, tr("走法"));
    model->setHeaderData(2, Qt::Horizontal, tr("时间"));

    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    tableView->setModel(model);
    tableView->setColumnWidth(0, 30);
    tableView->setColumnWidth(1, 70);
    tableView->setColumnWidth(2, 75);
    tableView->setFixedSize(200, 480);
}

        我们指定了tableView是3列15行,显示哪些内容。每列的大小。

        翻页和翻行是整个类中最主要的内容,用一个currentOrderNumber的成员变量记录当前走法的序号,根据这个我们可以确定当前页是第几页以及当前页的序号范围,这样我们就可以从vector中取数据,然后显示到界面上,比如说当我们点击“>”按钮后,当前选中的记录就是下一条记录,序号就会加一。下面是下一行和下一页所做的事情:

void StepList::nextRecord()
{
    currentOrderNumber++;
    updateHistoryDisplay();
}

void StepList::nextPage()
{
    currentOrderNumber = std::min(currentOrderNumber + MOVE_STEP_PER_PAGE, vecMoveHistory.size());
    updateHistoryDisplay();
}

void StepList::updateHistoryDisplay()
{
    QModelIndex modelIndex;
    for (int i = 0; i < MOVE_STEP_PER_PAGE; ++i)
    {
        for (int j = 0; j < COLUMN_PER_STEP; ++j)
        {
            modelIndex = model->index(i, j, QModelIndex());
            model->setData(modelIndex, tr(""));
        }
    }

    int currentPage = getPageNumber(currentOrderNumber);
    int totalPage = getPageNumber(vecMoveHistory.size());
    int currentRecordIndex = getRecordIndex(currentOrderNumber);

    if (vecMoveHistory.size() == 0)
    {
        btnPrevPage->setEnabled(false);
        btnPrevRecord->setEnabled(false);
        btnNextRecord->setEnabled(false);
        btnNextPage->setEnabled(false);
        tableView->clearSelection();
    }
    else
    {
        int startIndex = (currentPage - 1) * MOVE_STEP_PER_PAGE;
        int endIndex = std::min(currentPage * MOVE_STEP_PER_PAGE, vecMoveHistory.size()) - 1;

        for (int i = startIndex; i <= endIndex; i++)
        {
            modelIndex = model->index(i % MOVE_STEP_PER_PAGE, 0, QModelIndex());
            model->setData(modelIndex, vecMoveHistory.at(i).orderNumber);

            modelIndex = model->index(i % MOVE_STEP_PER_PAGE, 1, QModelIndex());
            model->setData(modelIndex, vecMoveHistory.at(i).moveStepInfo);

            modelIndex = model->index(i % MOVE_STEP_PER_PAGE, 2, QModelIndex());
            model->setData(modelIndex, vecMoveHistory.at(i).moveStepTime);
        }

        modelIndex = model->index(currentRecordIndex - 1, 0, QModelIndex());
        tableView->setCurrentIndex(modelIndex);

        btnPrevRecord->setEnabled(currentRecordIndex > 1);
        btnPrevPage->setEnabled(currentPage > 1);
        btnNextRecord->setEnabled(currentOrderNumber < vecMoveHistory.size());
        btnNextPage->setEnabled(currentPage < totalPage);
    }

    QString pageInfo;
    pageInfo.sprintf("当前页:%d/%d", currentPage, totalPage);
    lblPageInfo->setText(pageInfo);
}

         翻行和翻页,都是先设置currentOrderNumber的值,让后调用updateHistoryDisplay更新列表显示。我们每走一步完整的棋,记录就会下移一行,就相当于调用nextRecord。

源代码下载链接:http://download.csdn.net/detail/zxywd/9172917

你可能感兴趣的:(C++编程之中国象棋)