Как нарисовать разные линии внутри столбца QTableView в зависимости от данных в ячейках в ближнем столбце? - PullRequest
0 голосов
/ 28 октября 2019

Я хочу нарисовать линии внутри столбца, которые показывают возможные соединения между различными сигналами (Кроме того, я также хочу сделать радиокнопки на них, чтобы выбрать, какие соединения активны).

Но теперь у меня проблема с тем, что делегаты позволяют мне устанавливать SetItemDelegate только для всех столбцов или всех строк. Поэтому я не могу просто сделать разные блоки этих линий, такие как вертикальная линия, угловые линии, горизонтальная линия, а затем нарисовать их в зависимости от данных в ячейках. Я приложил пример изображения. Что я должен использовать, чтобы нарисовать что-то вроде этого?

Что-то вроде:

Определить новый стиль, переопределить метод drawPrimitive и выполнить произвольное рисование?

Не могли бы вы показать мне пример, пожалуйста?

Линиипример

Что у меня сейчас есть

Мой основной код для создания строк с сигналами (я их беру. TXT-файл для моделирования на данный момент):

       int IPFilesize = IPfilespl.size();
   ui->CompTab->setRowCount(IPFilesize);

   for (int i = 0; i<IPFilesize; i++)
       {
           QWidget *ChBx = new QWidget();
           QCheckBox *pCheckBox = new QCheckBox();
           QHBoxLayout *pLayout = new QHBoxLayout(ChBx);
           pLayout->addWidget(pCheckBox);
           pLayout->setAlignment(Qt::AlignCenter);
           pLayout->setContentsMargins(0,0,0,0);
           ChBx->setLayout(pLayout);
           ui->CompTab->setCellWidget(i, 0, ChBx);
           //connect(ChBx,SIGNAL(clicked()),this,SLOT(checkboxClicked()));
       }

   for (int ii = 0; ii<IPFilesize; ii++)
       {
           ui->CompTab->setItem(ii, 2, new QTableWidgetItem(IPfilespl.at(ii)) );
           //connect(ChBx,SIGNAL(clicked()),this,SLOT(checkboxClicked()));
       }
   ui->CompTab->setItemDelegateForColumn(1, new WireDelegateDown());

Код заголовка

class WireDelegate: public QStyledItemDelegate { protected:  void paint(QPainter* painter, const QStyleOptionViewItem& opt, const QModelIndex& index) const {

int x = opt.rect.x();
double y = opt.rect.y();
QPoint c = opt.rect.center();
double centerx = c.x();
double centery = c.y();
double r = opt.rect.right();
double width = opt.rect.width();
double height = opt.rect.height();
QPainterPath path;
path.addRect(centerx, centery-height/2, 5.0, height/2);
path.moveTo(0, 0);
path.addRect(centerx, centery, width/2, 5.0);
path = path.simplified();
painter->drawPath(path);

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Вы можете подумать, мешает ли QTableView больше, чем вам помогает. Встроенные виджеты просто фантастические, но часто я обнаружил, что, когда мне нужно выйти за рамки того, для чего они были специально предназначены, я в конечном итоге трачу больше времени на работу с ними, чем получаю выгоду. Я не знаю правильного решения для того, что вы делаете, но если бы это был я, я бы исследовал написание своего собственного представления, основанного на QAbstractItemView, а затем просто делал бы свою собственную собственную картину для всего этого.

Недостатком этого является то, что QTableView предоставляет вам большую поддержку взаимодействия, поэтому, если взаимодействие приносит вам большую пользу, вы должны написать и свое. Так что это компромисс. Также возможно, что встроенное взаимодействие для QTableView также помешает тому, что вы пытаетесь сделать. Это может пойти в любую сторону.

0 голосов
/ 28 октября 2019

Ваш делегат элемента может быть подклассом QAbstractItemDelegate . Затем вы можете установить его тип с помощью свойства, например shapeType (или как вы его называете). Основываясь на shapeType, вы можете выполнять внутреннюю работу по рисованию из переопределенного метода paint .

void MyConnectionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                           const QModelIndex &index) const
{
    if (m_shapeType  == ShapeType::horizontalLine) {
        //..... Your fancy drawings happens here based on shapetype
    } else if (m_shapeType  == ShapeType::verticalLine) {
    .
    .
    .

Как я вижу на рисунке (ваш желаемый результат), это не будет простыми это может быть довольно сложно реализовать такое поведение. Вам нужно будет рассчитать ширину, высоту, положение линий, цветов, точек, стрелок, узлов и т. Д. Для каждого делегата. Когда вы точно знаете, какие объекты должны быть нарисованы в каждой ячейке, нарисовать их с помощью QPainter - это простая задача.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...