QT4.8
問題描述:1920x1080的觸摸屏硬體180°旋轉,是以軟體也要旋轉180°才能正常顯示,但是部署vnc後進行校準,結果觸摸時觸點與界面剛好相反旋轉180°
部署vnc前環境變量QWS_DISPLAY="Transformed:Rot180:Linuxfb:/dev/fb0:depth=24:0"
部署vnc後環境變量
QWS_DISPLAY="Multi:Transformed:Rot180:Linuxfb:/dev/fb0:depth=24:0 VNC:paintonscreen:size=1920x1080:depth=24:1"
1、分析校準程式
從現象來看校準後觸摸點與界面剛好相反旋轉180°,懷疑配置旋轉180°在校驗時失效,調試程式列印qt_screen->transformOrientation()旋轉度數
發現列印出來是0°,說明旋轉無效。
qt_screen->classId()列印其id檢視類型結果是QScreen::MultiClass類型
QScreen::MultiClass類型繼承QScreen但是沒有重新實作transformOrientation函數,是以相當于調用QScreen的transformOrientation函數,其實作直接傳回0,如下;
int QScreen::transformOrientation() const
{
return 0;
}
2、将vnc配置還原重新調試qt_screen->classId()是QScreen::TransformedClassl類型,其實作了重新實作transformOrientation函數,能正常傳回旋轉角度。
3、為什麼qt_screen類型不一樣,他是怎麼初始化的?
檢視代碼實在構造QApplication時候調用d->construct();裡面的qt_init進行初始化的
QApplication::QApplication(int &argc, char **argv, int _internal)
: QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
{ Q_D(QApplication); d->construct(); }
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLyUEVOpXWq1keNpHWwYUbiBnTzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcucTO0UzN0QTMzETMwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
這裡需要注意的是我們的qt_init/qt4.8.7/src/gui/kernel/qapplication_qws.cpp裡面的函數。
繼續分析找到init_display
qt_fbdpy = new QWSDisplay();
QWSDisplay::QWSDisplay()
{
d = new Data(0, qws_single_process);
}
QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
{
#ifdef QT_NO_QWS_MULTIPROCESS
Q_UNUSED(parent);
Q_UNUSED(singleProcess);
#else
if (singleProcess)
csocket = 0;
else {
csocket = new QWSSocket(parent);
QObject::connect(csocket, SIGNAL(disconnected()),
qApp, SLOT(quit()));
}
clientLock = 0;
#endif
init();
}
void QWSDisplay::Data::init()函數裡面找到qt_get_screen,qt_screen就是在這裡初始化的。
QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
從代碼分析,qt_screen就是根據QWS_DISPLAY配置的第一個冒号前面的驅動名稱建立的
是以配置vnc前建立的qt_screen是QTransformedScreen類型的,配置後是QMultiScreen類型的。
然後連接配接的時候QMultiScreen會繼續将後面的配置驅動添加到自己的子類下面
知道了qt_screen是怎麼來的,就知道怎麼解決:如下
修改校準程式處理:先儲存原始qt_screen, old_qt_screen=qt_screen;,然後将其子類TransformedClass的類指派給qt_screen,使用校準完成後再指派回去qt_screen=old_qt_screen;
if(qt_screen->classId()==QScreen::MultiClass)
{
QMultiScreen* p=dynamic_cast<QMultiScreen*>(qt_screen);
if(p)
{
QList<QScreen*>tmp= p->subScreens();
for(int i=0;i<tmp.size();i++)
{
if(tmp.at(i)->classId()==QScreen::TransformedClass)
{
qt_screen=tmp.at(i);
break;
}
}
}
}