我正在構建一個嵌入了 openstreetmap QML 組件的 Qt 5.11應用程式。我剛剛寫了一個最小的重現案例。它包括在地圖上顯示物件(此處為五個藍點)。懸停物件時,會顯示一個帶有一些文本的小彈出視窗。
當物件靠近邊緣時,彈出視窗無法正確顯示。我雖然會使用visibleArea檢查這個,但該屬性是在 Qt 5.12 中添加的。
我找不到讓彈出視窗完全可見的解決方案。Qt 5.11 中有我可以做的解決方法嗎?這里是 QML 檔案。只需鍵入qmlscene sample.qml并懸停藍點即可查看。
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtLocation 5.11
import QtPositioning 5.11
import QtQuick.Window 2.11
Window {
id: root; width: 800; height: 600;
Plugin { id: mapPlugin; name: "osm"; }
ListModel {
id: myModel
ListElement { latitude: 48.2351164; longitude: 6.8986936; name: "The point on the center"; }
ListElement { latitude: 48.235111272600186; longitude: 6.9007217756551995; name: "The point on the right"; }
ListElement { latitude: 48.23512783507458; longitude: 6.896574932520792; name: "The point on the left"; }
ListElement { latitude: 48.23614708436043; longitude: 6.898623901851295; name: "The point on the top"; }
ListElement { latitude: 48.23417574713512; longitude: 6.898641104398024; name: "The point on the bottom"; }
}
Map {
id: map
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(48.2351164, 6.8986936)
zoomLevel: 19
MapItemView {
model: myModel
delegate: MapQuickItem {
anchorPoint.x: myRect.width / 2
anchorPoint.y: myRect.height / 2
width: myRect.width
height: myRect.height
coordinate: QtPositioning.coordinate(model.latitude, model.longitude)
sourceItem: Rectangle {
id: myRect
readonly property int radius: 10
width: radius * 2
height: radius * 2
color: "transparent"
Canvas {
id: myCanvas
anchors.fill: parent
property alias textVisible: myPopup.visible
onPaint: {
var width = myRect.width;
var height = myRect.height;
var centreX = width / 2;
var centreY = height / 2;
var ctx = getContext("2d");
ctx.reset();
ctx.fillStyle = "blue";
ctx.globalAlpha = 1;
ctx.beginPath();
ctx.moveTo(centreX, centreY);
ctx.arc(centreX, centreY, myRect.radius, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
}
MouseArea {
x: 0; y: 0;
width: myRect.radius * 2
height: myRect.radius * 2
acceptedButtons: Qt.LeftButton
hoverEnabled: true
onEntered: { myCanvas.textVisible = true }
onExited: { myCanvas.textVisible = false }
}
}
Popup {
id: myPopup
x: myRect.width / 2 - width / 2
y: myRect.height / 2 20
visible: false
Label { text: model.name; horizontalAlignment: Text.AlignHCenter; }
}
}
}
}
}
}
任何幫助是極大的贊賞。
uj5u.com熱心網友回復:
您可以檢查(彈出寬度 彈出 x)是否超出螢屏寬度,然后更改x,y以調整彈出位置。您可以查看 Popup 組件的以下修改代碼。根據您的標記位置調整 X 和 Y。
Popup {
id: myPopup
x: {
if((mapItem.x myPopup.width) >= root.width)
return -(myRect.width/2)-(width)
else if((mapItem.x-myPopup.width) < 0)
return (myRect.width)
else
return myRect.width / 2 - width / 2
}
y: {
if((mapItem.y myPopup.height) >= root.height)
return -(myRect.height/2)-(height)
else if((mapItem.y-myPopup.height) < 0)
return (height)
else
return myRect.height / 2 - height / 2
}
visible: false
Label { text: model.name;anchors.centerIn: parent;horizontalAlignment: Text.AlignHCenter; }
}
uj5u.com熱心網友回復:
找了一陣子,終于碰到了這兩個函式:mapToItem和mapFromItem。
所以,我首先需要將當前專案點映射到map專案坐標系。然后,我必須檢查該點是否在地圖視口內。如果不是,我必須調整坐標,然后將點映射回當前專案坐標系。接近底部和右側邊界時,彈出視窗的寬度和高度似乎會減小,所以我不得不使用 contentHeight、contentWidth 和 padding 屬性來獲得真正的彈出視窗大小。
而且我必須將彈出視窗 x 和 y 初始化為一個不同于零的值,以允許滑鼠事件在藍點上傳遞。
這是作業代碼,供可能需要的人使用。
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtLocation 5.11
import QtPositioning 5.11
import QtQuick.Window 2.11
Window {
id: root; width: 800; height: 600;
Plugin { id: mapPlugin; name: "osm"; }
ListModel {
id: myModel
ListElement { latitude: 48.2351164; longitude: 6.8986936; name: "The point on the center"; }
ListElement { latitude: 48.235111272600186; longitude: 6.9007217756551995; name: "The point on the right"; }
ListElement { latitude: 48.23512783507458; longitude: 6.896574932520792; name: "The point on the left"; }
ListElement { latitude: 48.23614708436043; longitude: 6.898623901851295; name: "The point on the top"; }
ListElement { latitude: 48.23417574713512; longitude: 6.898641104398024; name: "The point on the bottom"; }
}
Map {
id: map
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(48.2351164, 6.8986936)
zoomLevel: 19
MapItemView {
model: myModel
delegate: MapQuickItem {
anchorPoint.x: myRect.width / 2
anchorPoint.y: myRect.height / 2
width: myRect.width
height: myRect.height
coordinate: QtPositioning.coordinate(model.latitude, model.longitude)
sourceItem: Rectangle {
id: myRect
readonly property int radius: 10
width: radius * 2
height: radius * 2
color: "transparent"
Canvas {
id: myCanvas
anchors.fill: parent
property alias textVisible: myPopup.visible
onPaint: {
var width = myRect.width;
var height = myRect.height;
var centreX = width / 2;
var centreY = height / 2;
var ctx = getContext("2d");
ctx.reset();
ctx.fillStyle = "blue";
ctx.globalAlpha = 1;
ctx.beginPath();
ctx.moveTo(centreX, centreY);
ctx.arc(centreX, centreY, myRect.radius, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
}
MouseArea {
x: 0; y: 0;
width: myRect.radius * 2
height: myRect.radius * 2
acceptedButtons: Qt.LeftButton
hoverEnabled: true
onPositionChanged: {
myCanvas.textVisible = true;
// absolute position in map coordinate system
var absPos = mapToItem(map, mouse.x, mouse.y);
// margin between mouse pointer and the popup
var cursorMargin = 10;
// extra margin for right and bottom side
var bottomRightSideExtraMargin = 10;
// add the cursor margin to the position
var absPopupX = absPos.x cursorMargin;
var absPopupY = absPos.y cursorMargin;
// adjust if the popup is out of view on the bottom or right sides
if (absPos.x myPopup.contentWidth myPopup.leftPadding myRect.radius * 2 bottomRightSideExtraMargin > root.width) {
absPopupX = root.width - (myPopup.contentWidth myPopup.leftPadding cursorMargin bottomRightSideExtraMargin);
}
if (absPos.y myPopup.contentHeight myPopup.topPadding myRect.radius * 2 bottomRightSideExtraMargin > root.height) {
absPopupY = root.height - (myPopup.contentHeight myPopup.topPadding cursorMargin bottomRightSideExtraMargin);
}
// convert back to the current item coordinate system
var popupPos = mapFromItem(map, absPopupX, absPopupY);
myPopup.x = popupPos.x;
myPopup.y = popupPos.y;
}
onExited: {
myCanvas.textVisible = false;
}
}
}
Popup {
id: myPopup
// original offset to allow mouse hover
x: 20; y: 20;
visible: false
Label { text: model.name; horizontalAlignment: Text.AlignHCenter; }
}
}
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/409026.html
標籤:
上一篇:從多個DLL版本中進行選擇
下一篇:類似系統的QT普通命令執行
