A proper way to detect if device is either a cellphone or a tablet?
-
Hi,
I have been researching about the better way to detect if a Qt app is running from a cellphone or a tablet. Here is an interesting approach:
https://stackoverflow.com/questions/31203068/a-proper-way-to-detect-tablet-or-mobile-in-qt-using-non-native-toolsBut I wonder if there is a more recent way to do it. I am playing around with a mobile app using QWidgets and I want to show a customized interface for phones and other for the tablets. Is it possible?
I appreciate any advice on this matter. Thanks!
-
@jsulm Yes and not. I mean, I need to show a comfortable interface depending on the physical size of the screen. Let me give you some examples:
- Cellphone with this display resolution: 960x540 / dpi=159. I have lack of space to work here, so I have to show the small interface.
- Tablet with this display resolution: 1920x1128 / dpi = 240. I have enough space to work here, so I can display the large interface.
- Cellphone with this display resolution: 2560x1440 / dpi = 581. I have enough space to work here, BUT if I try the large interface, the user experience is very poor, because although I can show all the GUI components, as it is a cellphone, the elements are so tiny that is very difficult to pick them with my finger. So, in this case I choose the small interface, in despite of the plenty space.
Concluding, the physical screen size (not the display resolution) would help me a lot to decide what interface to show. Now, thinking of the problem, asking for the physical screen size is just a technical way to approach my original question: how can I detect if a device is a cellphone or a tablet?
PS: I wonder if making some calculation with the resolution parameters and the dpi value I can solve the problem. i.e.
if (width > 1200) { if (dpi < 300) { // it's a tablet showLargeUI(); } else { // it's a cellphone showSmallUI(); } } else if (width < 1200 and dpi < 300) { // it's a cellphone showSmallUI(); }
It has any sense?
-
@xtingray
yyou could check int QPaintDevice::heightMM() I'm howerver not sure how reliable that function is.The better option would probably be a compination of
int QPaintDevice::physicalDpiX() const
andconst QRect QDesktopWidget::availableGeometry(int screen = -1) const
for you to decide upon, to use the mobile ui or not.
-
@xtingray To me it sounds like you need the resolution and physical display size instead to try to find out whether a device is tablet or smart phone. Especially there is no clear differentiation between tablet and smartphone I would say. There are tablets with big displays but low resolution for example as well.
-
Yes, both are just things with a rectangular display of some size and resolution and the same set of applications - except that some devices have an application called "Phone", but that doesn't influence the design of other applications in any way...
-
You can also have a look at V-Play Engine for Qt-based mobile Apps and Games, which already offers simple properties like App::tablet or App::landscape to create responsive UIs based on the screen size or orientation.
The NavigationStack component, which offers native-styled page transitions and navigation bars for iOS and Android, also allows to automatically use a splitView on tablets.
Here's a short example:
import VPlayApps 1.0 import QtQuick 2.0 App { NavigationStack { id: navStack splitView: tablet // activates split-view feature for tablets // initial page (placed in left column if tablet is true) initialPage: Page { title: "Main Page" AppButton { text: "Add Detail Page" anchors.centerIn: parent onClicked: navStack.push(detailPage) } } } // Component for Detail Page // placed in right column if tablet is true, added on top of stack otherwise Component { id: detailPage Page { title: "Detail Page" AppText { anchors.centerIn: parent text: "This is the detail Page." } } } }
To learn more about handling different devices and screens with V-Play, please have a look at the tutorial Supporting Multiple Screen Sizes and Screen Densities with V-Play Apps.
Cheers,
GT -
I found this approach for Android devices. For now, it works for my needs as a temporary workaround:
QAndroidJniObject qtActivity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); QAndroidJniObject resources = qtActivity.callObjectMethod("getResources","()Landroid/content/res/Resources;"); QAndroidJniObject displayMetrics = resources.callObjectMethod("getDisplayMetrics","()Landroid/util/DisplayMetrics;"); int dpi = displayMetrics.getField<int>("densityDpi"); int width = displayMetrics.getField<int>("widthPixels"); int height = displayMetrics.getField<int>("heightPixels"); qreal w = width/dpi; qreal h = height/dpi; qreal diagonal = sqrt((w*w)+(h*h)); // If diagonal > 7" it's a tablet
PS: Just out of curiosity, can I mix QML and QWidget code in the same mobile app?
-
@xtingray said in A proper way to detect if device is either a cellphone or a tablet?:
PS: Just out of curiosity, can I mix QML and QWidget code in the same mobile app?
-