JP
Julia PominchukApril 18, 2016, 8:15 p.m.

Построение схем из графических элементов

QGraphicsScene, GridLayout, Qt, scheme

Добрый день!
Прошу, пожалуйста, помочь с таким вопросом.
Создаю программу, которая рассчитывает электрические или комбинационые схемы (точно пока не определилась, но это не особо влияет на суть вопроса). Целью задачи есть сложить эту схему.
Нажимая на кнопку, мы поучаем нужный элемент и перетаскиваем в нужную позицию.
На этом сайте нашла урок о графической сцене и перетаскиванию по ней элементов, он очень помог, но осталось два вопроса:
1) как сделать так, чтобы элемент становился не в произвольную позицию, а как будто разбить поле на прямоугольные участки;
2) приоритетный в решении момент. Как понять, что два элемента стоят рядом, то есть соединены в цепь или что выходы одного элемента подключены ко входам второго.
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

2
Evgenii Legotckoi
  • April 18, 2016, 10:41 p.m.
  • The answer was marked as a solution.

Добрый день. Давайте по порядку разберёмся.

1) как сделать так, чтобы элемент становился не в произвольную позицию, а как будто разбить поле на прямоугольные участки;

Я так понимаю, смотрели вот этот урок про перетаскивание графических элементов на графической сцене?

Чтобы все объекты перемещались по строго заданным координатам, то можно урок просто модифицировать следующим образом.

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    // Косметическая подготовка приложения
    this->resize(640, 640);          // Устанавливаем размеры окна приложения
    this->setFixedSize(640, 640);
 
    scene = new QGraphicsScene(this);   // Инициализируем графическую сцену
    scene->setItemIndexMethod(QGraphicsScene::NoIndex); // настраиваем индексацию элементов
 
    ui->graphicsView->resize(600, 600);  // Устанавливаем размер graphicsView
    ui->graphicsView->setScene(scene);  // Устанавливаем графическую сцену в graphicsView
    ui->graphicsView->setCacheMode(QGraphicsView::CacheBackground); // Кэш фона
    ui->graphicsView->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
 
    scene->setSceneRect(0, 0, 500, 500); // Устанавливаем размер сцены
    
    /// Добавляем этот кусок, чтобы сделать сетку
    for(auto i = 0; i < 21; ++i){
        scene->addLine(i*25, 0, i*25, 500, QPen(Qt::gray));
        scene->addLine(0, i*25, 500, i*25, QPen(Qt::gray));
    }
}
void Widget::on_pushButton_clicked()
{
    MoveItem *item = new MoveItem();        // Создаём графический элемент
    item->setPos(250, 250);  // Делаем строго заданную позици появления квадрата
    scene->addItem(item);   // Добавляем элемент на графическую сцену
}

И модифицируем метод события перемещения мыши в самом классе квадрата

void MoveItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    /* Устанавливаем позицию графического элемента
     * в графической сцене, транслировав координаты
     * курсора внутри графического элемента
     * в координатную систему графической сцены
     * */
    QPointF position = event->pos();
    int x = position.x();
    int y = position.y();
 
    x = x % 25;
    y = y % 25;
 
    if(x >= 13){
        x = position.x() - x + 25;
    } else {
        x = position.x() - x;
    }
 
    if(y >= 13){
        y = position.y() - y + 25;
    } else {
        y = position.y() - y;
    }
    this->setPos(mapToScene(QPointF(x, y)));
}

Также я немного уменьшил размеры квадратов для наглядности.

QRectF MoveItem::boundingRect() const
{
    return QRectF (-20, -20, 40, 40);
}
 
void MoveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(Qt::black);
    painter->setBrush(Qt::green);
    painter->drawRect(-20, -20, 40, 40);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

После этих изменений объекты будут двигаться с заданным шагом в 25 пикселей.

2) приоритетный в решении момент. Как понять, что два элемента стоят рядом, то есть соединены в цепь или что выходы одного элемента подключены ко входам второго.

А относительно присоединений.. Вам тогда нужно разработать собственный дизайн графических элементов, чтобы ключевые точки были посередине граней условных квадратов, областей QRect, в которых будут лежать Ваши электрические элементы. В данном примере условная область QRect будет занимать 4 клетки.

Тогда останется отслеживать пересечения данных условных точек, как показано в уроке про определение коллизий.

Останется только правильно составить алгоритм из пересекающихся элементов для расчёта. Но это уже довольно большой объём работы. В двух словах сходу не придумаешь. Нужно пораскинуть мозгами.

    JP
    • April 18, 2016, 11:59 p.m.
    Спасибо большое! Вы очень помогли!

      Comments

      Only authorized users can post comments.
      Please, Log in or Sign up
      Ua

      Qt - Test 001. Signals and slots

      • Result:84points,
      • Rating points4
      Ua

      Qt - Test 001. Signals and slots

      • Result:42points,
      • Rating points-8
      ОК

      Qt - Test 001. Signals and slots

      • Result:47points,
      • Rating points-6
      Last comments
      ИМ
      Игорь МаксимовNov. 22, 2024, 9:51 p.m.
      Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
      Evgenii Legotckoi
      Evgenii LegotckoiOct. 31, 2024, 11:37 p.m.
      Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
      A
      ALO1ZEOct. 19, 2024, 5:19 p.m.
      Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
      ИМ
      Игорь МаксимовOct. 5, 2024, 4:51 p.m.
      Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
      d
      dblas5July 5, 2024, 8:02 p.m.
      QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
      Now discuss on the forum
      f
      firstlunoxodFeb. 15, 2025, 1:46 p.m.
      Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
      Дмитрий
      ДмитрийFeb. 3, 2025, 4:24 p.m.
      Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
      NW
      Nayo WaiJan. 30, 2025, 7:22 p.m.
      не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
      n
      nklyJan. 3, 2025, 12:52 p.m.
      Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
      M
      MarselAug. 17, 2023, 12:26 a.m.
      OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

      Follow us in social networks