2015-01-15 13 views
5

Ich habe ein Problem mit einem Webbrowser auf der weißen Liste, den meine Firma für eines unserer entwickelt/gewartet hat Produktlinien. Der Browser läuft auf Qt 4.8.6 mit qtwebkit (Migration auf 5.X wäre ideal, aber das Embedded-Linux-Betriebssystem, das wir verwenden, ist zu alt, um die neueren Versionen basierend auf unseren Tests zu unterstützen und auf ein neueres zu aktualisieren OS ist zu teuer für uns/unsere Kunden). Die primäre Schnittstelle zum Browser ist ein 6x8-Touchscreen, der in einem Flugzeugcockpit montiert ist.QtWebView - Wie Scrollen der Seite und Scrollen von Elementen in einer Seite (zB Google Maps) zu aktivieren

Für Websites mit scrollbaren/eingebetteten Karten (z. B. Google Maps) möchten die Benutzer des Browsers die gesamte Seite ziehen, wenn sie etwas außerhalb der Karte auswählen, und nur die Karte ziehen (ohne die gesamte Seite scrollen) wenn die Karte ausgewählt ist (Ala die meisten der gängigen mobilen Browser).

So weit, ich bin in der Lage eine oder das andere zu tun, aber nicht beides:

  • Wenn ich Maus-Handler in eine QWebView oder QGraphicsWebView Haken, ich den Cursor in eine Hand drehen kann und sehr leicht unterstützt das Ziehen der gesamten Webseite. Dies verhindert jedoch die Fähigkeit der Seite, die Mausereignisse zu handhaben, wenn ein Benutzer über eine Karte zieht (d. H. Wenn ein Benutzer über eine Karte zieht, zieht er die gesamte Seite, ohne die Karte zu verschieben).

  • Wenn ich die Hooks nicht hinzufüge, um Mausereignisse zu behandeln, können Dinge wie Karten durch Ziehen/Ziehen gescrollt werden, aber natürlich verliert der Benutzer die Fähigkeit, die gesamte Seite zu ziehen.

Gerade jetzt, verwendet der Browser die später mit Bildlaufleisten deaktiviert und ein Overlay-Richtungspfeil, damit der Benutzer die gesamte Seite blättern (wie die Anzeigegröße begrenzt ist, und Scrollbalken nehmen zu viel Platz wenn sie so groß sind, dass der Benutzer mit ihnen interagieren kann) ... aber das ist nicht ideal.

Meine Frage: Gibt es einen einfachen Weg, um die Seite und Elemente auf einer Seite nahtlos scrollen zu können?

Danke! Rob

Antwort

2

Scheint mir, als ob Sie überprüfen müssen, ob Sie über eine solche Karte sind und das Ereignis in diesem Fall ignorieren (weitergeben). Ich denke, man sollte so etwas wie diese in der Lage sein zu tun:

bool GraphicsWebView::isOverMap(QPoint pos) { 
    QWebPage* webPage = this->page(); 
    if (webPage) { 
     QWebFrame* webFrame = webPage->frameAt(pos); 
     if (webFrame) { 
      QString selectorQuery = "#map-canvas"; // Based on https://developers.google.com/maps/tutorials/fundamentals/adding-a-google-map 
      QList<QWebElement> list = webFrame->findAllElements(selectorQuery).toList(); // Find all the maps! 

      foreach(QWebElement element, list) { 
       if (element.geometry().contains(pos)) { 
        return true; // Cursor is over a map 
       } 
      } 
     } 
    } 
    return false; // No match 
} 

Offensichtlich ist dies eine ziemlich spezifische Funktion, aber es ist wahrscheinlich eine Art und Weise mit einer besseren Selektor Abfrage zu entwickeln, das auf all diesen Arten von QWebElement gelten .

Sie Mausereignisse Haken durch QGraphicsWebView Subklassen Unter der Annahme und Neuimplementierung void mouseMoveEvent(QGraphicsSceneMouseEvent * event), ich schlage vor, Sie tun so etwas wie:

void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { 
    if (isOverMap(mapFromScene(event->scenePos()).toPoint())) { // We got a map! 
     event.ignore(); // Clear the accept flag 
     return; // Return, we're done here 
    } 

    handleMoveView(); // Not over any maps, let's scroll the page 
} 

Teil des Dokuments erklärt, wie die Ereignisse in Bezug auf das oberste Element behandelt werden. Ich empfehle Ihnen besonders, den dritten Absatz zu lesen.

Hoffe, dass hilft!

EDIT: Hab ein bisschen mehr Forschung und es sieht so etwas wie das allgemeinere sein könnte: graphicsView.focusItem()->flags().testFlag(QGraphicsItem::ItemIsMovable);

Es ist zumindest wert als Ersatz untersuchen zu isOverMap()

EDIT: Gotcha, hier ist etwas, was du dann versuchen kannst. Beginnen Sie mit der Unterklasse QGraphicsSceneMouseEvent und fügen Sie ein Signal mit dem Namen void destroyedWithoutAccept() hinzu, das im Destruktor ausgegeben wird, wenn das Ereignis nicht akzeptiert wurde.

Dann ändern mousemove wie folgt aussehen:

void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { 
    MyEvent myEvent = new MyEvent(event); // Copy event 
    event.accept(); // accept original event 
    connect(myEvent, SIGNAL(destroyedWithoutAccept), 
      this, SLOT(handleMoveView)); // Callback if unused 

    QGraphicsWebView::mouseMoveEvent(myEvent); // Pass it to Base class 
} 

Wenn das funktioniert, könnte es ein wenig Verzögerung einführen, wenn deleteLater es zu zerstören verwendet wird. Aber in diesem Fall reimplementieren Sie es auch.

+0

Danke für die Antwort! Leider war Google Maps nur ein Beispiel ... die Fluggesellschaften versuchen tatsächlich, eine Auswahl von Wetter, Flugverfolgung und anderen verwandten Seiten zu verwenden. Einige von ihnen haben interaktive Karten und andere nicht (jede Implementierung ist auch einzigartig). Ich habe nur Google Maps erwähnt, da ich gerade mit diesem Test experimentiere. Ich habe auch zuvor das oben beschriebene Verhalten des Treffertests ausprobiert, hatte aber keinen Zugriff (es meldet immer "falsch", wenn Sie abfragen, ob es beweglich ist oder nicht). – Bob

+0

Kein Problem. Habe gerade einen neuen Schnitt gemacht, der zu einem besseren und flexibleren Design führen sollte. – Atlante45