a
andi8726 октября 2017 г. 21:23

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

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

скрины.zip
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

5
Evgenii Legotckoi
  • 27 октября 2017 г. 5:16

День добрый.

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

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

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

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

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

      Evgenii Legotckoi
      • 28 октября 2017 г. 6:38
      • Ответ был помечен как решение.
      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
        • 28 октября 2017 г. 8:50

        Благодарю за информацию и предложенное решение. Поменял код, ничего не изменилось. Но я обратил внимание, что измененный код входит в блок 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
          • 28 октября 2017 г. 9:14

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

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

            Комментарии

            Только авторизованные пользователи могут публиковать комментарии.
            Пожалуйста, авторизуйтесь или зарегистрируйтесь
            e
            • ehot
            • 31 марта 2024 г. 21:29

            C++ - Тест 003. Условия и циклы

            • Результат:78баллов,
            • Очки рейтинга2
            B

            C++ - Тест 002. Константы

            • Результат:16баллов,
            • Очки рейтинга-10
            B

            C++ - Тест 001. Первая программа и типы данных

            • Результат:46баллов,
            • Очки рейтинга-6
            Последние комментарии
            k
            kmssr9 февраля 2024 г. 2:43
            Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
            АК
            Анатолий Кононенко5 февраля 2024 г. 9:50
            Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
            EVA
            EVA25 декабря 2023 г. 18:30
            Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
            J
            JonnyJo25 декабря 2023 г. 16:38
            Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
            G
            Gvozdik19 декабря 2023 г. 5:01
            Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
            Сейчас обсуждают на форуме
            DA
            Dr Gangil Academics20 апреля 2024 г. 14:45
            Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
            a
            a_vlasov14 апреля 2024 г. 13:41
            Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
            Павел Дорофеев
            Павел Дорофеев14 апреля 2024 г. 9:35
            QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
            f
            fastrex4 апреля 2024 г. 11:47
            Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
            P
            Pisych27 февраля 2023 г. 12:04
            Как получить в массив значения из связанной модели? Спасибо, разобрался:))

            Следите за нами в социальных сетях