实现Edit菜单

现在我们开始实现菜单 Edit 相应的槽函数。

void Spreadsheet::cut()
{copy();del();
}

cut()槽可以对Edit->Cut菜单做出响应。由于Cut 的执行效果与Copy之后再加上一个Delete的执行效果相同,所以其实现代码很简单。

void Spreadsheet::copy()
{QTableWidgetSelectionRange range = selectedRange();QString str;for (int i = 0; i < range.rowCount(); ++i) {if (i > 0)str += "\n";for (int j = 0; j < range.columnCount(); ++j) {if (j > 0)str += "\t";str += formula(range.topRow() + i, range.leftColumn() + j);}}QApplication::clipboard()->setText(str);
}

copy()槽能够对Edit->Copy做出响应。它会遍历当前选择(如果没有明确的选择,那么就认为选择的只是当前单元格)。每一个选中单元格的公式都会被添加到一个QString中,行与行之间利用换行符“\n”分隔,列与列之间则以制表符“\t’来分隔。下面给出了这一实现方法的示意图。

在Qt中,通过调用QApplication::clipboard()静态函数可以使用系统的剪贴板。通过调用QClipboard::setText(),就既可以在本应用程序中又可以在其他应用程序中使用放在剪贴板上的这些文本。这种使用制表符“\t”和换行符“\n"作为文件分隔符的形式可以被包括微软Excel在内的许多应用程序所支持。

函数QTableWidget::selectedRanges()返回一个选择范围列表。我们知道由于在构造函数中已经将选择模式设置为QAbstractemView::ContiguousSelection,所以选择范围不可能再超过1。为方便起见,我们定义了一个selectedRange( )函数来返回这个选择范围。

QTableWidgetSelectionRange Spreadsheet::selectedRange() const
{QList<QTableWidgetSelectionRange> ranges = selectedRanges();if (ranges.isEmpty())return QTableWidgetSelectionRange();return ranges.first();
}

如果只有一个选择,则只需简单地返回第一个(并且也只有这一个)选择即可。没有选择的情况应该永远不会发生,因为ContigousSeletion模式至少可以把当前单元格当作是已经选中的选择。但是,为了避免使程序出现缺陷的可能性,还是需要对这种当前没有选中单元格的情况进行单独处理。

void Spreadsheet::paste()
{QTableWidgetSelectionRange range = selectedRange();QString str = QApplication::clipboard()->text();QStringList rows = str.split('\n');int numRows = rows.count();int numColumns = rows.first().count('\t') + 1;if (range.rowCount() * range.columnCount() != 1&& (range.rowCount() != numRows|| range.columnCount() != numColumns)) {QMessageBox::information(this, tr("Spreadsheet"),tr("The information cannot be pasted because the copy ""and paste areas aren't the same size."));return;}for (int i = 0; i < numRows; ++i) {QStringList columns = rows[i].split('\t');for (int j = 0; j < numColumns; ++j) {int row = range.topRow() + i;int column = range.leftColumn() + j;if (row < RowCount && column < ColumnCount)setFormula(row, column, columns[j]);}}somethingChanged();
}

paste()槽对Edit->Paste菜单选项做出响应。我们从剪贴板中取回文本,并且调用静态函数QString::split()把这串字符变成一个QStringList。每行都会变成这个列表中的一个字符串。

接下来,需要求出复制区域的维数。行数就是QStringList 中字符串的个数;列数就是第一行中制表符“\t”字符的个数再加上1。如果只选中了一个单元格,就把这个单元格作为粘贴区域放在左上角;否则,就把当前选择作为要粘贴的区域。

为了执行粘贴操作,我们遍历所有行并且再次使用QString::split()把它们分隔到每一个单元格中,但是这一次要把制表符“\t”当作分隔符。

void Spreadsheet::del()
{QList<QTableWidgetItem *> items = selectedItems();if (!items.isEmpty()) {foreach (QTableWidgetItem *item, items)delete item;somethingChanged();}
}

del()槽对Edit->Delete菜单选项做出响应。如果有选中的项,那么该函数就会删除它们并且调用somethingChanged()函数。对选择中的每一个Cell对象使用delete足以清空所有这些单元格。当删除QTFableWidget的QTableWidgetTtem的时候,QTableWidget就会注意到这一情况的发生,而如果这些项中有可见的任意项,QTableWidget将会自动对自己进行重绘。如果在一个已经删除过的单元格位置上又调用了cell(),那么该函数将会返回一个空指针。

void Spreadsheet::selectCurrentRow()
{selectRow(currentRow());
}void Spreadsheet::selectCurrentColumn()
{selectColumn(currentColumn());
}

selectCurentRow()和selectCurrentColumn()对Edit->Select->Row和Edit->Select->Column菜单选项做出响应。这些实现分别依赖于QTableWidget的selectRow()和slectClum()函数。我们不必再去实现Edit->Select->All菜单选项的功能,因为该功能可以由QTableWidget从QAstactemView::selectAll()的函数中继承过来。

void Spreadsheet::findNext(const QString &str, Qt::CaseSensitivity cs)
{int row = currentRow();int column = currentColumn() + 1;while (row < RowCount) {while (column < ColumnCount) {if (text(row, column).contains(str, cs)) {clearSelection();setCurrentCell(row, column);activateWindow();return;}++column;}column = 0;++row;}QApplication::beep();
}

findNext()槽会遍历单元格一遍,它从当前光标右侧的单元格开始遍历到这一行的最后一列,然后再从下一行的第一个单元格开始继续遍历,如此反复,直到找到所要查找的文本,或者是直到最后一个单元格为止。

例如,如果当前的单元格是C24,那么就会搜索D24、E24、… 、Z24,然后再去搜索A25、B25、C25、… 、Z25;等等,一直遍历到Z999为止。如果找到了一个匹配项,那么就清空当前选择,把单元格光标移动到那个匹配的单元格上,并且让包含Spreasheet的窗口变成激活状态。如果没能找到匹配的单元格,那么就让应用程序发出"哔"(beep)的一声来表明搜索已经结束,匹配没有成功。

void Spreadsheet::findPrevious(const QString &str, Qt::CaseSensitivity cs)
{int row = currentRow();int column = currentColumn() - 1;while (row >= 0) {while (column >= 0) {if (text(row, column).contains(str, cs)) {clearSelection();setCurrentCell(row, column);activateWindow();return;}--column;}column = ColumnCount - 1;--row;}QApplication::beep();
}

fndPrevious()槽与findNext()槽相似,区别之处是它会向相反的方向遍历并且会在单元格A1处停下来。

Qt4_实现Edit菜单相关推荐

  1. Qt4_实现其他菜单

    实现其他菜单 我们将要实现对Tools和Options菜单做出响应的槽. void Spreadsheet::recalculate() {for (int row = 0; row < Row ...

  2. Qt4_实现File菜单

    实现File菜单 在这一节中,将实现那些能够让File菜单项正常工作并且能够对最近打开文件进行管理的槽函数和私有函数. void MainWindow::newFile() {if (okToCont ...

  3. Qt4_创建菜单和工具栏

    创建菜单和工具栏 绝大多数现代图形用户界面应用程序都会提供一些菜单.上下文菜单和工具栏.菜单可以让用户浏览应用程序并且可以学会如何处理一些新的事情,上下文菜单和工具栏则提供了对那些经常使用的功能进行快 ...

  4. Eclipse 菜单

    Eclipse 菜单 Eclipse 查看的菜单栏通常包含以下几个菜单: File 菜单 Edit 菜单 Navigate 菜单 Search 菜单 Project 菜单 Run 菜单 Window ...

  5. Unity5x编辑器的主菜单和布局

    一.主菜单按钮 1.Unity编辑器左上角有一排主菜单按钮 2.File菜单 (1).创建新场景, 快捷键Ctrl+N, 常用操作 (2).打开场景, 快捷键Ctrl+O, 常用操作 (3).保存当前 ...

  6. 【STM32】 keil软件工具--菜单详解

    转载至:https://blog.csdn.net/ybhuangfugui/article/details/51501781 Ⅰ.写在前面 本文带来关于Keil软件菜单的内容,系列教程中前面讲述的内 ...

  7. Delphi Menu Designer(菜单设计器)之一

    菜单包括大多数Windows应用程序的大部分内容.一些Windows应用程序没有菜单,但绝大多数都有.Delphi使用Menu Designer使得创建菜单变得容易.Menu Designer有如下特 ...

  8. 在PyQt中构建 Python 菜单栏、菜单和工具栏

    摘要:菜单.工具栏和状态栏是大多数GUI 应用程序的常见且重要的图形组件.您可以使用它们为您的用户提供一种快速访问应用程序选项和功能的方法. 本文分享自华为云社区<Python 和 PyQt:创 ...

  9. Keil(MDK-ARM-STM32)系列教程(七)菜单

    Ⅰ.写在前面 本文带来关于Keil软件菜单的内容,系列教程中前面讲述的内容都可以通过菜单而找到,只是大部分内容都可以通过快捷按钮或快捷键找到,该文就讲述主菜单里每一个子菜单的内容. Keil有些菜单在 ...

最新文章

  1. 「杂谈」旷视科技新产品监视学生上课不是什么好事儿
  2. css出现的问题以及解决,div+css的浮动常出现的问题以及解决办法_html/css_WEB-ITnose...
  3. 【zepto学习笔记01】核心方法$()
  4. 使用C# lock同时访问共享数据
  5. java 时间段内月份_java获取某段时间内的月份列表
  6. 人工智能与量子计算在有前途的新忆阻器中融合
  7. Java:JDK、JRE和JVM的关系(图示详解,一眼就能看明白!)
  8. hadoop相关问题-stop-all.sh
  9. kali下破解小区门禁卡实例
  10. yansongda 支付宝提现,商家转账
  11. 作文 我眼中的计算机1000字,我眼中的自己作文范文1000字(精选6篇)
  12. Android-自定义幸运抽奖转盘
  13. 一个web前端专科生面试后的感概
  14. Centos7 安装部署apache。简单易上手
  15. unity3d显示c4d材质_学习笔记分享 如何学好C4D
  16. 7485设计8位比较器
  17. Python 数据扩充(亮度、翻转、噪声)
  18. 思杰pvs服务器压力无法最大化,XXX学校桌面虚拟化方案剖析.docx
  19. Python3获取5000个元素的单字符表
  20. 洛谷——T156530 儒略历

热门文章

  1. 计算机系统-小数(浮点数)在内存中的存储
  2. C++:定义头文件/定义命名空间
  3. 数字信号处理实验matlab版答案,数字信号处理习题答案及matlab实验详解.pdf
  4. mysql udf禁用_如何禁用 mysql 的 udf 功能
  5. vbreport8.wpf.viewer 个别电脑不显示_手机听歌不过瘾?一招将Win10电脑变成蓝牙音箱...
  6. 记录表类型 oracle,[转]关于oracle的记录类型
  7. Java 游戏报错 看不懂求教
  8. 技术胖Flutter第四季-19导航父子页面的跳转返回
  9. sort函数用于vector向量的排序
  10. 卡尔曼滤波—建立状态空间表达式