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 почитать подробнее)

            Комментарии

            Только авторизованные пользователи могут публиковать комментарии.
            Пожалуйста, авторизуйтесь или зарегистрируйтесь
            AD

            C++ - Тест 004. Указатели, Массивы и Циклы

            • Результат:50баллов,
            • Очки рейтинга-4
            m
            • molni99
            • 25 октября 2024 г. 22:37

            C++ - Тест 004. Указатели, Массивы и Циклы

            • Результат:80баллов,
            • Очки рейтинга4
            m
            • molni99
            • 25 октября 2024 г. 22:29

            C++ - Тест 004. Указатели, Массивы и Циклы

            • Результат:20баллов,
            • Очки рейтинга-10
            Последние комментарии
            ИМ
            Игорь Максимов22 ноября 2024 г. 8:51
            Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
            Evgenii Legotckoi
            Evgenii Legotckoi31 октября 2024 г. 11:37
            Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
            A
            ALO1ZE19 октября 2024 г. 5:19
            Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
            ИМ
            Игорь Максимов5 октября 2024 г. 4:51
            Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
            d
            dblas55 июля 2024 г. 8:02
            QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
            Сейчас обсуждают на форуме
            Evgenii Legotckoi
            Evgenii Legotckoi24 июня 2024 г. 12:11
            добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
            t
            tonypeachey115 ноября 2024 г. 3:04
            google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
            NSProject
            NSProject4 июня 2022 г. 0:49
            Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
            9
            9Anonim25 октября 2024 г. 6:10
            Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

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