I want to open links from a QWebView with target="_blank" in a new window of a new process.
I tried using QWebView::createWindow(QWebPage::WebWindowType), but I didn't find a way to get the url to send to the new process. Actually, I tried a hack to get the url using a hidden QWebView (returned by the createWindow method) with the urlChanged event, but sometimes this event is triggered twice, so it is not reliable.
Is there any way to get the URL in the createWindow method?
If not, what can I do to open this kind of links in a new window of a new process?
I found a way to do what I want.
I had to overload the mousePressEvent to get the mouse position so that I can get the url from it.
Here is the code:
QWebView* WebView::createWindow(QWebPage::WebWindowType) {
QWebHitTestResult result{page()->mainFrame()->hitTestContent(lastClickPosition)};
openNewWindow(result.linkUrl());
return nullptr;
}
void WebView::mousePressEvent(QMouseEvent* mouseEvent) {
lastClickPosition = mouseEvent->pos();
QWebView::mousePressEvent(mouseEvent);
}
I let this question opened a few days to see if anyone can find a better solution.
If you're trying for a multi-process webview architecture, I would suggest looking at QtWebEngine. QtWebEngine will be replacing QtWebKit and is based on Chromium. Because of this, it has a multi-process architecture by default. QtWebEngine will no longer be updated, so I would suggest migrating to QtWebEngine anyway.
QtWebEngine overview
Related
Hey im having issues with a website in the jxbrowser. it seems like it is running into a timeout or whatever and then in the jxbrowser there is a dialog showing up "website not responding" and i can click on "reload" or "leave".
Can I in any way access this dialog and overwrite it? For instance everytime i would get this dont ask but go to the homepage instead?
I'm having trouble finding this if it is even possible.
I found a solution. JXBrowser has a RenderAdapter where a function exists onRenderUnresponsive wich can be overridden. Look at this: https://jxbrowser.support.teamdev.com/support/solutions/articles/9000091687-detecting-unresponsive-web-page
In my case I simply want to reload the website:
Browser browser = new Browser();
browser.addRenderListener(new RenderAdapter() {
#Override
public void onRenderUnresponsive(RenderEvent event) {
browser.reloadIgnoringCache(false);
}
});
In QtWebkit, using QWebSettings class, I could enable like the permission to close the window using the JavaScript command window.close();:
setAttribute(QWebSettings::JavascriptCanCloseWindows, true);
But in QtWebEngine, such an attribute doesn't exist: http://doc.qt.io/qt-5/qwebenginesettings.html#WebAttribute-enum
How to allow JavaScript to close any QWebEngineView using window.close()?
Indeed, this attribute doesn't exist anymore in the Qt WebEngine.
However, you can close any views using the signal windowCloseRequested from your QWebEnginePage, and connecting it to a slot where you close the window. There is an example of use in the Demo Browser example, in the file webview.cpp:
connect(page(), &WebPage::windowCloseRequested, this, &QWidget::close);
We are testing an application with Selenium WebDriver. HTMLUnitDriver is our choice (because of non-gui-testing) and sometimes IEDriver for Presentationpurposes. Anyway, i try to perform a click on a button, this one has to open an rich:popuPanel(modal=true) and click a Link on that Panel. With IEDriver that's no problem, but with HTMLUnitDriver the popupPanel doesn't open. I tried to perform these clicks in several ways:
JavascriptExecutor jsdriver = (JavascriptExecutor) driver;
jsdriver.executeScript("$('input[id$=freigabeCmd_id]').focus();");
//below are the other tries
// jsdriver.executeScript("$('input[id$=freigabeCmd_id]').click();");
// jsdriver.executeScript("window.document.getElementById('editorViewForm_id:freigabeCmd_id').click()");
// jsdriver.executeScript("arguments[0].click()", freigabeButton);
// jsdriver.executeScript("arguments[0].fireEvent('onclick');", freigabeButton);
further i tried it the "normal way":
freigabeButton.click();
//below are other ways i found here on stackoverflow
// freigabeButton.sendKeys(Keys.ENTER);
// new Actions(driver).moveToElement(freigabeButton).clickAndHold().release().build().perform();
but nothing brought me to get the popupPanel "visible". Anyone got an idea why?! i'm really stuck right now. If you need more Informations pls let me know.
using: HTMLUnit Version 2.12 and latest SeleniumVersion
It might be that your webapp uses javascript to launch the rich pop-up panel, and you are running HtmlUnitDriver with javascript disabled? It is disabled by default, so you need to explicitly enable it.
My application consists of a WebView widget. A mouse click on the widget is not handled by the mousePressEvent() of my application, but by the WebView widget. So, I installed an event filter to receive the events. Now, I get notified of all events, except the mouseReleaseEvent for the right click (Everything works fine for left clicks and mousePressEvent for the right click is also getting registered). I guess it has got something to do with context events getting generated by right clicks (a pop-up menu gets generated). But since I am using a filter, the event should first be sent to me. The following is the code for the event filter
in Jambi, but I hope I can modify an answer given in Qt for Jambi.
public boolean eventFilter(QObject o,QEvent event)
{
if (event.type()==QEvent.Type.MouseButtonPress) // One can call the mousePressEvent() functions from here,which can do this work but speed
{
if (((QMouseEvent)event).button()==Qt.MouseButton.LeftButton)
{
mousebuttontype=1;
clickedorpressed=1;
}
else
if (((QMouseEvent)event).button()==Qt.MouseButton.RightButton)
{
mousebuttontype=2;
System.out.println("right");
}
t1=QTime.currentTime();
t1.start();
}
else
if (event.type()==QEvent.Type.MouseButtonRelease)
{
if (t1.elapsed()>900)
{
switch(mousebuttontype)
{
case 1: browser.back();
break;
case 2: browser.forward();
break;
}
}System.out.println("choda");
}
return false;
}
MY BASIC AIM IS GETTING THE TIME INTERVAL FOR WHICH THE RIGHT CLICK WAS PRESSED. ANY WORKAROUND ?
Some digging around certainly seems to suggest that there may be no right-mouse release event being generated if that is the trigger for a context menu on your particular system. These are conveyed as a QContextMenuEvent.
This Qt Labs post hints about this too.
A work around may be tricky if it is system dependent. Have you tried overriding event() in the QApplication class to see if the event comes through there? Some events don't necessarily get to the children but everything goes through QApplication::event().
Another option for you is, subclass Qwebview and override mouseReleaseEvent event
I've found a fix for this that I dont think will be system dependent.
My particular case was using mouseReleaseEvent in order to catch the events, and use them myself. I didn't get these events.
On all child widgets of the widget that I want to handle the event, I added to the class definition:
protected:
void mouseReleaseEvent(QMouseEvent *event) {event->ignore();}
This overrides the default implementation for context menu's, and sends the mouseReleaseEvent back up the parent chain like it would for other mousebuttons.
http://doc.qt.io/qt-5/qevent.html#ignore
This shows that it will probably propagate to the parent widget. As the link indicates, this fixed it for me at Qt 5.9, but I think it should work for virtually all version.
(I am aware this question is literally 7 years old, but it doesn't contain the fix that I think would be the best fix, and shows up as result 2 on google(qt not getting mouse release event on rightclick). So I think it deserves an up to date answer.)
Without going in to broader implementation explanations, the core problem I needed to solve related to this issue was that I needed to know if a context menu swallowed the right-click so I could ensure some custom state was handled properly. The simplest workaround I was able to find was to implement contextMenuEvent, which gets called after mousePressEvent, to detect if the event was accepted (a context menu was opened somewhere in my QGraphicsScene/Items). Here is a minimal example in Python to demonstrate how the event state might be used:
def contextMenuEvent(self, event):
event.setAccepted(False)
super(MyGraphicsView, self).contextMenuEvent(event)
self.__context_menu_used = event.isAccepted()
Note you can also skip running the the base class contextMenuEvent entirely to block the scene/items from opening a context menu. This is handy if you want to do 3D-DCC-like alt-RMB-zooming without accidentally opening a context menu, e.g.:
def contextMenuEvent(self, event):
# Block context menus if alt is held down
if event.modifiers() & QtCore.Qt.AltModifier:
return
event.setAccepted(False)
super(MyGraphicsView, self).contextMenuEvent(event)
self.__context_menu_used = event.isAccepted()
Can I add a ProgressEvent listener to the stage?
I don't see it in any of the auto-complete options when I am typing in Flex.
What do people normally do to get a progress readout of the entire main runner's loading progress?
I try the following, which is where I would expect to see the ProgressEvent options pop up:
stage.addEventListener(
Thanks...
Try adding it to loaderInfo.
something like:
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
Also , if you're using the framework, you should probably extend the DownloadProgressBar.
I remember this old tutorial, but surely there must be plenty online.
I have a new problem:
I use the following code to show the progress of the download of my site content:
public function mainProgress(e:ProgressEvent):void
{
var w:Number = e.bytesLoaded / e.bytesTotal;
_mainprog.graphics.clear();
_mainprog.graphics.beginFill(0x000000);
_mainprog.graphics.drawRect(0, 0, w * stage.stageWidth, 50);
_mainprog.graphics.endFill();
}
But it doesn't seem to work.
What happens is that the loaderInfo object thinks that the site has loaded before I am actually ready to display anything. So what ends up happening (I think) is the site loads, the loader progress disappears before the initial page's graphics have fully loaded, and then there is a delay between when the completion of the loaderInfo object happens and the actual graphics appearing.
Has anyone else had this problem before?
Thanks...