如何实现从 GUI 而不是以编程方式编辑 QTableWidget 的垂直和水平标题文本的能力? [英] How do I implement the ability to edit a QTableWidget's vertical and horizontal header text in-line from the GUI instead of programmatically?

查看:76
本文介绍了如何实现从 GUI 而不是以编程方式编辑 QTableWidget 的垂直和水平标题文本的能力?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个显示在用户界面中的 QTableWidget,我可以使用按钮添加和删除行和列.问题是,当我添加一行或一列时,我可以更改实际单元格中的数据,但我无法命名行或列.该名称只是一个静态数字.

I have a QTableWidget that is displayed in the user interface that I can add and remove rows and columns using buttons. The problem is, when I add a row or column, I can change the data in the actual cells, but I cannot name the row or column. The name is simply a static number.

有没有办法允许我的程序的用户双击行/列标题并在线编辑名称或类似的内容?

Is there a way to allow the user of my program to perhaps double-click on a row/column header and edit the name in-line or something similar?

谢谢.

推荐答案

据我所知,没有内置的方法可以做到这一点.然而,这可以手动实现.以下代码的主要思想是检测对标题项的双击,将 QLineEdit 放在它们上面并在失去焦点后保存编辑的文本.该示例基于 Qt 生成的设计器表单类,其中包含一个名为 ui->tableWidget 的表,该表可以是 QTableWidgetQTableView.>

As far as I know there is no built-in way to do this. However this can be implemented manually. The main idea of the following code is to detect double clicks on header items, place QLineEdit over them and save edited text once it loses focus. The example is based on Qt generated Designer Form Class with a table named ui->tableWidget which can be either QTableWidget or QTableView.

class MainWindow : public QMainWindow {
  Q_OBJECT
public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();
private:
  Ui::MainWindow *ui;
  QLineEdit* header_editor;
  int editor_index;
  bool eventFilter(QObject*, QEvent*);
};

来源:

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  header_editor = 0;
  ui->setupUi(this);
  ui->tableWidget->horizontalHeader()->viewport()->installEventFilter(this);
  ui->tableWidget->verticalHeader()->viewport()->installEventFilter(this);
}

MainWindow::~MainWindow() {
  delete ui;
}

bool MainWindow::eventFilter(QObject* object, QEvent* event) {
  if ((object == ui->tableWidget->horizontalHeader()->viewport() ||
       object == ui->tableWidget->verticalHeader()->viewport()) &&
      event->type() == QEvent::MouseButtonDblClick) {
    if (header_editor) { //delete previous editor just in case
      header_editor->deleteLater();
      header_editor = 0;
    }
    QMouseEvent* e = static_cast<QMouseEvent*>(event);
    QHeaderView* header = static_cast<QHeaderView*>(object->parent());
    int mouse_pos = header->orientation() == Qt::Horizontal ? e->x() : e->y();
    int logical_index = header->logicalIndex(header->visualIndexAt(mouse_pos));
    if (logical_index >= 0) { // if mouse is over an item
      QRect rect; // line edit rect in header's viewport's coordinates
      if (header->orientation() == Qt::Horizontal) {
        rect.setLeft(header->sectionPosition(logical_index));
        rect.setWidth(header->sectionSize(logical_index));
        rect.setTop(0);
        rect.setHeight(header->height());
      } else {
        rect.setTop(header->sectionPosition(logical_index));
        rect.setHeight(header->sectionSize(logical_index));
        rect.setLeft(0);
        rect.setWidth(header->width());
      }
      rect.adjust(1, 1, -1, -1);
      header_editor = new QLineEdit(header->viewport());
      header_editor->move(rect.topLeft());
      header_editor->resize(rect.size());
      header_editor->setFrame(false);
      //get current item text
      QString text = header->model()->
          headerData(logical_index, header->orientation()).toString();
      header_editor->setText(text);
      header_editor->setFocus();
      editor_index = logical_index; //save for future use
      header_editor->installEventFilter(this); //catch focus out event
      //if user presses Enter it should close editor
      connect(header_editor, SIGNAL(returnPressed()), 
              ui->tableWidget, SLOT(setFocus()));
      header_editor->show();
    }
    return true; // filter out event
  } else if (object == header_editor && event->type() == QEvent::FocusOut) {
    QHeaderView* header = static_cast<QHeaderView*>(
        header_editor->parentWidget()->parentWidget());
    //save item text
    header->model()->setHeaderData(editor_index, header->orientation(), 
                                   header_editor->text());
    header_editor->deleteLater(); //safely delete editor
    header_editor = 0;
  }
  return false;
}

这种方法的缺点是它很笨拙,当调整标题大小或滚动表格时,事情会变糟.这只是一个可以改进的例子.

Downsides of this method are that it's hacky, things go bad when headers are resized or table is scrolled. It's just an example that can be improved.

我觉得必须有一种更简单的方法.但是 Qt 头文件忽略 Qt::ItemIsEditable 标志并且不能使用委托.

I have a feeling there has to be a simpler way. But Qt headers ignore Qt::ItemIsEditable flag and can't use delegates.

这篇关于如何实现从 GUI 而不是以编程方式编辑 QTableWidget 的垂直和水平标题文本的能力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆