a
andi87Oct. 26, 2017, 9:23 p.m.

QT gui: как поменять два элемента интерфейса местами?

Привет. Есть одна консольная игра nethack, для нее есть несколько графических интерфейсов. Мне приглянулся qt, но в нем есть один недостаток. Взгляните на первый скриншот в прикрепленной папке, окно игры состоит из трех основных элементов: карта (внизу), сообщения (слева сверху), статус (справа сверху). Я часто читаю окно сообщений, но расположено оно неудобно - слева, а было бы лучше, если располагалось бы в центре. Было бы неплохо поменять местами окна статуса и сообщений. Как я хочу сделать, изображено на втором скрине. К сожалению, я не нашел внутриигровых настроек, которые позволили бы это сделать. Все, что можно делать с этим окнами - это увеличивать или уменьшать их, перетягивая влево или вправо. Остается только редактирование исходного кода. Исходный код игры открыт, компилировать я умею. Знания qt - почти нулевые, навыки программирования - начальные. Смог найти код, который описывает, как сделаны окна сообщений и статуса. А что редактировать - понятия не имею. Прочитал немного документацию qt, узнал, что располагать элементы gui можно несколькими способами, можно вручную задавать координаты, или воспользоваться компоновщиком. Я не стал дальше читать, а решил спросить здесь. Как же все таки решить эту задачу? Кто хочет взглянуть на исходный код игры, он располагается здесь https://github.com/chasonr/nethack-3.6.0-patches/tree/interfaces . В папке win располагаются папки qt и qt4.

скрины.zip
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!

5
Evgenii Legotckoi
  • Oct. 27, 2017, 5:16 a.m.

День добрый.

Там есть класс главного окна приложения. NetHackQtMainWindow. Он располагается в файле qt_win.cpp .
В нём есть различные QGridLayout - это размещения, в которых находятся виджеты. Полагаю, что в одном из этих размещений и располагаются эти виджеты интерфейса.
В проекте нет ни одного файла компоновщика, там всё вручную сделано. Поэтому остаётся только найти в исходниках нужный Layout и поменять порядок установки в него виджетов.
    a
    • Oct. 27, 2017, 12:37 p.m.
    • (edited)

    Как я понял, каждый элемент - это один виджет. Т.е. окно сообщений - это один виджет, окно статуса - другой. Вы говорите, что все сделано вручную. Но тогда зачем в коде применяется qgridlayout? Я прочитал, если применять абсолютный или ручной метод позиционирования, qgridlayout вообще не используется. Или я что-то неправильно понял?

    >Поэтому остаётся только найти в исходниках нужный Layout
    Как я должен искать? Могут ли эти qgridlayout в qt_win.cpp указать, где именно искать?

    >Поэтому остаётся только найти в исходниках нужный Layout и поменять порядок установки в него виджетов.
    Вы можете уточнить, как должен выглядеть Layout? Я пробовал поискать в исходниках по слову Layout, нашел вызов функции layout(), это оно? А как меняется порядок установки виджетов? Это нужно координаты задавать? Или как-то по другому? Где-то нашел, что используется сортировка по имени виджетов. Можно ссылку на какой нибудь пример кода, который в котором описывается порядок установки виджетов? Чтобы я хоть примерно представлял, что искать. Есть два файла, qt4msg.cpp и qt4stat.cpp, которые описывают окна статуса и сообщений. В первом файле нет ни одного слова layout, во втором есть, но относится по видимому не к расположению самого окна статуса, а элементов внутри него.

    Еще вопрос, какую программу использовать для отладки? Чтобы можно было что-то поменять в коде, и сразу посмотреть на результат. Компилирую проект через mingw32-make, но каждый раз компилировать утомительно.

      Evgenii Legotckoi
      • Oct. 28, 2017, 6:38 a.m.
      • The answer was marked as a solution.
      qgridlayout вообще не используется. Или я что-то неправильно понял?
      Скорее я не совсем чётко выразился. Под ручной вёрсткой в Qt Creator я подразумеваю всегда написание вёрстки через код в исходниках, без использования дизайнера интерфейсов. То есть в проекте тогда будут содержаться *.ui файлы, но их в данном проекте нет. Значит вся вёрстка писалась вручную в коде. То есть это моё утверждение не касается того, с использованием абсолютного позиционирования было сделано или через компоновщики QGridLayout.

      Очень старый код там... и очень слабый, но нужно отдать должное тому кто писал его, сил было вложено много.

      Возможно, стоит поправить этот код
      void NetHackQtMainWindow::ShowIfReady()
      {
          if (message && map && status) {
      	QPoint pos(0,0);
      	QWidget* p = qt_compact_mode ? stack : centralWidget();
      	message->Widget()->recreate(p,0,pos);
      	map->Widget()->recreate(p,0,pos);
      	status->Widget()->recreate(p,0,pos);
      	if ( qt_compact_mode ) {
      	    message->setMap(map);
      	    stack->addWidget(map->Widget(), 0);
      	    stack->addWidget(message->Widget(), 1);
      	    stack->addWidget(status->Widget(), 2);
      	    raiseMap();
      	} else {
      	    layout();
      	}
      	showMaximized();
          } else if (isVisible()) {
      	hide();
          }
      }
      попробуйте переписать так
      void NetHackQtMainWindow::ShowIfReady()
      {
          if (message && map && status) {
      	QPoint pos(0,0);
      	QWidget* p = qt_compact_mode ? stack : centralWidget();
      	message->Widget()->recreate(p,0,pos);
              map->Widget()->recreate(p,0,pos);
              status->Widget()->recreate(p,0,pos);
      	if ( qt_compact_mode ) {
      	    message->setMap(map);
      	    stack->addWidget(map->Widget(), 0);
                  stack->addWidget(status->Widget(), 1);
      	    stack->addWidget(message->Widget(), 2);
      	    raiseMap();
      	} else {
      	    layout();
      	}
      	showMaximized();
          } else if (isVisible()) {
      	hide();
          }
      }
      Для отладки и вообще для работы с проектом используйте Qt Creator. Это IDE.
        a
        • Oct. 28, 2017, 8:50 a.m.

        Благодарю за информацию и предложенное решение. Поменял код, ничего не изменилось. Но я обратил внимание, что измененный код входит в блок if (qt_compact_mode), а compact mode - это опция игры, которая насколько я понял, разделяет окна сообщений, статуса и карты на три отдельных окна windows. Вроде то, что мне нужно, но когда меняю эту опцию, при запуске игра вылетает с ошибкой. Полагаю, что искать решение ошибки не вариант.  Наткнулся на такой вот код, в qt4main.cpp:

        void NetHackQtMainWindow::AddMessageWindow(NetHackQtMessageWindow* window)
        {
            message=window;
            hsplitter->insertWidget(0, message->Widget());
            ShowIfReady();
        }
        
        void NetHackQtMainWindow::AddMapWindow(NetHackQtMapWindow2* window)
        {
            map=window;
            vsplitter->insertWidget(1, map->Widget());
            ShowIfReady();
            connect(map,SIGNAL(resized()),this,SLOT(layout()));
        }
        
        void NetHackQtMainWindow::AddStatusWindow(NetHackQtStatusWindow* window)
        {
            status=window;
            hsplitter->insertWidget(2, status->Widget());
            ShowIfReady();
        Почему то кажется, что это именно то, что мне нужно. Не знаю правда, что здесь нужно поменять, буду разбираться методом тыка. Про использование Qt Creator - понятно, но непонятно, что нужно сделать, чтобы начать отладку. Я так понимаю, нужно нажать открыть проект, но в папке с исходниками нет ни одного файла с расширением проекта qt. Есть файл проекта visual studio, но при попытке отладить вылазят ошибки.
          a
          • Oct. 28, 2017, 9:14 a.m.

          Ура, я сделал это. Получилось с первого раза, причем результат оказался близок к идеалу. Просто решил для начала поменять цифры местами, было:

              hsplitter->insertWidget(0, message->Widget());
              hsplitter->insertWidget(2, status->Widget());
          Стало:
              hsplitter->insertWidget(2, message->Widget());
              hsplitter->insertWidget(0, status->Widget());
          Окна поменялись местами, причем осталась возможность менять их размер и положение по горизонтали. Задача решена, спасибо! Есть еще некритичные моменты по интерфейсу, которые хотелось бы поменять, теперь будет время про qt почитать подробнее)

            Comments

            Only authorized users can post comments.
            Please, Log in or Sign up
            d
            • dsfs
            • April 26, 2024, 4:56 a.m.

            C ++ - Test 004. Pointers, Arrays and Loops

            • Result:80points,
            • Rating points4
            d
            • dsfs
            • April 26, 2024, 4:45 a.m.

            C++ - Test 002. Constants

            • Result:50points,
            • Rating points-4
            d
            • dsfs
            • April 26, 2024, 4:35 a.m.

            C++ - Test 001. The first program and data types

            • Result:73points,
            • Rating points1
            Last comments
            k
            kmssrFeb. 8, 2024, 6:43 p.m.
            Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
            Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
            EVA
            EVADec. 25, 2023, 10:30 a.m.
            Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
            J
            JonnyJoDec. 25, 2023, 8:38 a.m.
            Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
            G
            GvozdikDec. 18, 2023, 9:01 p.m.
            Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
            Now discuss on the forum
            PS
            Peter SonMay 3, 2024, 5:57 p.m.
            Best Indian Food Restaurant In Cincinnati OH Ready to embark on a gastronomic journey like no other? Join us at App india restaurant and discover why we're renowned as the Best Indian Food Restaurant In Cincinnati OH . Whether y…
            Evgenii Legotckoi
            Evgenii LegotckoiMay 2, 2024, 2:07 p.m.
            Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
            IscanderChe
            IscanderCheApril 30, 2024, 4:22 a.m.
            Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
            G
            GarApril 22, 2024, 5:46 a.m.
            Clipboard Как скопировать окно целиком в clipb?
            Павел Дорофеев
            Павел ДорофеевApril 14, 2024, 2:35 a.m.
            QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь

            Follow us in social networks