UI в Destkop & Tablet pc. Адаптируемся к размеру и разрешению экрана.

В одном из проектов среди требований по UI было:

  • полноэкранный режим;
  • работа на обычных компьютерах;
  • работа на Tablet PC.

Используемые Tablet PC:

Сперва Samsung не тянул по производительности, но после существенной оптимизации удалось добиться необходимой производительности, и Samsung в одно части стал приоритетным.

Все ничего только приведу характеристики(диагональ, разрешение):

  • x230t 12,5 » 1366×768;
  • ATIV 11,6″ 1920×1080.

Если размер и разрешения x230t  де факто стандарт для ноутбуков, и требовалось лишь учесть HD мониторы с соотношением сторон 4:3, то с ATIV пришлось выкручиваться.

Первое от чего следует предостеречь, так это от фиксированных размеров элементов, т.к. при смене DPI все надписи вылезут из заданных границ.

Выходом стало получение размера монитора и его разрешения, и в зависимости от их значений выбираем нужный QSS если проект на Widgets, а в QtQuick я использовал State Machine что бы не создавать нескольких QML версток.

В коде выразилось наличием синглетона DisplayInfoSingleton со всей необходимой информацией.

#ifndef DISPLAYINFO_H_
#define DISPLAYINFO_H_

#include

#include <QtCore/QObject>

namespace GUI
{
	/*!
	 * @brief интерфейс информации о мониторе
	 */
	class IDisplayInfo
	{
	public:

		virtual ~IDisplayInfo ( )
		{
		}

		/*!
		 * @brief получить размер диагонали
		 * @return размер диагонали в дюймах
		 */
		virtual float diagonal ( ) const = 0;

		/*!
		 * @brief разрешение по горизонтали
		 */
		virtual int horizontalResolution ( ) const = 0;

		/*!
		 * @brief разрешение по вертикали
		 */
		virtual int verticalResolution ( ) const = 0;

	};

	/*!
	 * @brief реализация платформо независимых методов IDisplayInfo
	 */
	class AbstractDisplayInfo : public IDisplayInfo
	{
	public:
		virtual int horizontalResolution ( ) const;
		virtual int verticalResolution ( ) const;
	};

	/*!
	 * @brief синглетон содержащий конкретный объект IDisplayInfo
	 */
	class DisplayInfoSingleton
	{
	public:

		/*! миллиметров в дюйме */
		static const float MILLIMETR_2_INCH;

		/*! ширина формата Full HD */
		static const int FULL_HD_WIDTH = 1920;

		/*! высота формата Full HD */
		static const int FULL_HD_HEIGHT = 1080;

		/*!
		 * @brief инстанцирование синглетона
		 * @return ссылка на конкретного объекта DisplaInfo
		 */
		static IDisplayInfo& instance ( );

	protected:

		DisplayInfoSingleton ( );

	private:

		Q_DISABLE_COPY(DisplayInfoSingleton)

		/*!
		 * @brief создание конкретного объекта DisplayInfo
		 * @return платформозависимый объект класса DisplayInfo
		 */
		static IDisplayInfo* createObject ( );

		static std::unique_ptr m_info;  //!< конкретный DisplayInfo
	};

} /* namespace GUI */
#endif /* DISPLAYINFO_H_ */

 

#include

#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>

#include "DisplayInfo.h"

namespace GUI
{
	std::unique_ptr DisplayInfoSingleton::m_info = std::unique_ptr(DisplayInfoSingleton::createObject ());
	const float DisplayInfoSingleton::MILLIMETR_2_INCH = 0.0393700787;

	int AbstractDisplayInfo::horizontalResolution ()  const
	{
		return QApplication::desktop()->screenGeometry().width();
	}
	int AbstractDisplayInfo::verticalResolution ()  const
	{
		return QApplication::desktop()->screenGeometry().height();
	}

	IDisplayInfo& DisplayInfoSingleton::instance ( )
	{
		return *m_info;
	}
} /* namespace GUI */

 

#include

#include <QtCore/QDebug>

#include "DisplayInfo.h"

#include <X11/Xlib.h>

namespace
{
	using namespace GUI;

	/*!
	 * @brief Unix реализация информации дисплея
	 */
	class DisplayInfoUnix : public AbstractDisplayInfo
	{
	public:

		DisplayInfoUnix ( ) :
						m_display (0)
		{
			m_display = XOpenDisplay (NULL);
			if (m_display == NULL) {
				qDebug () << "Error XOpenDisplay";
			}
		}

		~DisplayInfoUnix ( )
		{
			if (m_display) {
				XCloseDisplay (m_display);
			}
		}

		float diagonal ( ) const
		{
			if (m_display) {
				const int horzSizeMM = DisplayWidthMM (m_display, 0);
				const int vertSizeMM = DisplayHeightMM (m_display, 0);

				return sqrt (pow (horzSizeMM, 2) + pow (vertSizeMM, 2)) * DisplayInfoSingleton::MILLIMETR_2_INCH;
			}

			static const int diagonalSize = 19;
			return diagonalSize;
		}

	private:

		Q_DISABLE_COPY(DisplayInfoUnix)

		Display* m_display;  //!< дисплей
	};
}

namespace GUI
{
	IDisplayInfo* DisplayInfoSingleton::createObject ( )
	{
		return new DisplayInfoUnix ();
	}
}

 

#include

#include <QtCore/qt_windows.h>

#include "DisplayInfo.h"

namespace
{
	using namespace GUI;

	/*!
	 * @brief Win реализация информации дисплея
	 */
	class DisplayInfoWin : public AbstractDisplayInfo
	{
	public:

		DisplayInfoWin ( )
		{
			m_screen = GetDC (NULL);
		}

		~DisplayInfoWin ( )
		{
			ReleaseDC (NULL, m_screen);
		}

		float diagonal ( ) const
		{
			const int horzSizeMM = GetDeviceCaps (m_screen, HORZSIZE);
			const int vertSizeMM = GetDeviceCaps (m_screen, VERTSIZE);

			return sqrt (pow (horzSizeMM, 2) + pow (vertSizeMM, 2)) * DisplayInfoSingleton::MILLIMETR_2_INCH;
		}

	private:

		Q_DISABLE_COPY(DisplayInfoWin)

		HDC m_screen;  //!< дескриптор экрана
	};

}

namespace GUI
{
	IDisplayInfo* DisplayInfoSingleton::createObject ( )
	{
		return new DisplayInfoWin ();
	}
}

 

SET(SOURCES DisplayInfo.cpp
#...
)
set(DEPEND_LIB
#...
)

IF(WIN32)
    SET(SOURCES
        ${SOURCES}
        DisplayInfoWin.cpp
     )
    SET (DEPEND_LIB
         ${DEPEND_LIB}
         Gdi32
     )
ELSE(WIN32)
    SET(SOURCES
        ${SOURCES}
        DisplayInfoUnix.cpp
    )
    SET (DEPEND_LIB
         ${DEPEND_LIB}
         XLib
     )
ENDIF(WIN32)