I have a QWebView window that opens my local .html file.
This local .html file has an embed flash movie - .swf
It works nice, when I click on it, it gives me keyboard focus.
So, there's my problem, I want it to have focus right after launching my app, not how it behaves right now with this mouse click needed.
I tried modifying .html file with following:
<body onLoad="window.document.IP.focus();">
as mentioned in Adobe official solution
Besides that I tried:
<script>
window.onload = function() {
var input = document.getElementById("IP").focus();
}
</script>
where "IP":
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=43,0,0,0" id="IP" width="1024" height="768" align="middle">
[...]
<embed src="IP.swf" quality="best" salign="lt" bgcolor="#ffffff" width="1024" height="768" swliveconnect="true" id="IP" name="IP" align="middle" allowscriptaccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer_pl">
</object>
Stackoverflow Q1
Stackoverflow Q2
Edit 1.
class PlayFlash(QWebView):
def __init__(self):
# QWebView
self.view = QWebView.__init__(self)
self.setWindowFlag(Qt.FramelessWindowHint)
self.resize(1024, 768)
self.move(0, 0)
# enable flashplayer plugin
self._settings = QWebSettings.globalSettings()
self._settings.setAttribute(QWebSettings.PluginsEnabled, True)
self.setFocusPolicy(Qt.StrongFocus)
self.mouse = Controller()
self.timer = QTimer()
self.timer.setInterval(2000)
self.timer.timeout.connect(self.focusOnFlash)
self.timer.start()
self.timer_count = 0
if __name__ == "__main__":
# plugin path
os.environ['QTWEBKIT_PLUGIN_PATH'] = os.path.abspath('/home/kamil/gitlab/PlayFlash')
app = QApplication(sys.argv)
view = PlayFlash()
view.load("file:///home/kamil/gitlab/PlayFlash/PlayFlash.html")
# view.load("https://pythonspot.com")
view.show()
view.setFocus()
view.focusOnFlash()
app.exec_()
I had to add a timer that executes simulated click to get focus on that swf embed in html. Without that it does not have focus.
Related
Im new to python and VS and im trying to make a simple GUI with a button.
Once I click the button I want it to print(5).
The code looks as following but when I click "run" it exits without any action:
import wpf
from System.Windows import Application, Window
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'WpfApplication1.xaml')
BUTTON.Click += self.Button_Click
print(5)
def Button_Click(self, sender, e):
pass
if __name__ == '__main__':
Application().Run(MyWindow())
XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WpfApplication1" Height="300" Width="300">
<Grid>
<Button x:Name="BUTTON" Content="Button" HorizontalAlignment="Left" Margin="101,82,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" Background="#FFFF1616"/>
</Grid>
</Window>
Thank you.
You have to add an event handler for the button click. Just add this to your window init. (BUTTON should match the button's name on your xaml code)
ui = wpf.LoadComponent(self, 'WpfApplication1.xaml')
ui.BUTTON.Click += self.Button_Click
You can also achieve the same through the xaml code :
<Button x:Name="BUTTON" Click="Button_Click"></Button>
Working code with comments below:
import wpf
from System.Windows import Application, Window
class MyWindow(Window):
def __init__(self):
self.ui = wpf.LoadComponent(self, 'form.xaml')
# not needed because event handler
# is in XAML
# to handle event on code, remove this from xaml's button tag:
# Click="Button_Click"
# and uncomment line below:
# self.ui.Button.Click += self.Button_Click
def Button_Click(self, sender, e):
print('Button has clicked')
if __name__ == '__main__':
Application().Run(MyWindow())
# Alternatively, below also works:
# form = MyWindow()
# form.ShowDialog()
See screenshot of working form:
I hope this question isn't too far-fetched. I'm good with Selenium and I've been working with PyQt4 recently. I want to use them both together with a program I'm currently working on and it'd work out a lot more smoothly if I could embed the controllable browser into a Qt4 frame or widget. Can this be done? And if so, how?
It doesn't have to be done with Selenium, I just want to be able to control the browser or at least show a webpage in a Qt widget or frame.
So after some research into methods other people have used, I figured it out.
The code I used came from a "very simple browser" module I obtained from here
I modified the code to be more customizable for my future self.
Here's my modified version of the code:
from PyQt4 import QtCore, QtGui, QtWebKit
class Browser(QtGui.QMainWindow):
def __init__(self, size=[800,600], frame=None, centralWidget=None, default_url='https://www.google.com', backButton=True, forwardButton=True, topBar=True):
"""
Initialize the browser GUI and connect the events
"""
self.showBackButton = backButton
self.showForwardButton = forwardButton
self.showTopBar = topBar
QtGui.QMainWindow.__init__(self)
self.resize(size[0],size[1])
if (centralWidget == None):
self.centralwidget = QtGui.QWidget(self)
else:
self.centralwidget = centralWidget
self.mainLayout = QtGui.QHBoxLayout(self.centralwidget)
self.mainLayout.setSpacing(0)
self.mainLayout.setMargin(1)
if (frame == None):
self.frame = QtGui.QFrame(self.centralwidget)
else:
self.frame = frame
self.gridLayout = QtGui.QVBoxLayout(self.frame)
self.gridLayout.setMargin(0)
self.gridLayout.setSpacing(0)
self.horizontalLayout = QtGui.QHBoxLayout()
if (self.showTopBar):
self.tb_url = QtGui.QLineEdit(self.frame)
if (self.showBackButton):
self.bt_back = QtGui.QPushButton(self.frame)
if (self.showForwardButton):
self.bt_ahead = QtGui.QPushButton(self.frame)
if (self.showBackButton):
self.bt_back.setIcon(QtGui.QIcon().fromTheme("go-previous"))
if (self.showForwardButton):
self.bt_ahead.setIcon(QtGui.QIcon().fromTheme("go-next"))
if (self.showBackButton):
self.horizontalLayout.addWidget(self.bt_back)
if (self.showForwardButton):
self.horizontalLayout.addWidget(self.bt_ahead)
if (self.showTopBar):
self.horizontalLayout.addWidget(self.tb_url)
self.gridLayout.addLayout(self.horizontalLayout)
self.html = QtWebKit.QWebView()
self.gridLayout.addWidget(self.html)
self.mainLayout.addWidget(self.frame)
#self.setCentralWidget(self.centralwidget) --- Not needed when embedding into a frame
if (self.showTopBar):
self.connect(self.tb_url, QtCore.SIGNAL("returnPressed()"), self.browse)
if (self.showBackButton):
self.connect(self.bt_back, QtCore.SIGNAL("clicked()"), self.html.back)
if (self.showForwardButton):
self.connect(self.bt_ahead, QtCore.SIGNAL("clicked()"), self.html.forward)
self.connect(self.html, QtCore.SIGNAL("urlChanged(const QUrl)"), self.url_changed)
self.default_url = default_url
if (self.showTopBar):
self.tb_url.setText(self.default_url)
self.open(self.default_url)
def browse(self):
"""
Make a web browse on a specific url and show the page on the
Webview widget.
"""
if (self.showTopBar):
url = self.tb_url.text() if self.tb_url.text() else self.default_url
self.html.load(QtCore.QUrl(url))
self.html.show()
else:
pass
def url_changed(self, url):
"""
Triggered when the url is changed
"""
if (self.showTopBar):
self.tb_url.setText(url.toString())
else:
pass
def open(self, url):
self.html.load(QtCore.QUrl(url))
self.html.show()
It could use some work at the moment, but I've tested it out and it's doing exactly what I need it to do. I tested it out with the following chunk of code that runs when the script is executed
if (__name__ == "__main__"):
app = QtGui.QApplication(sys.argv)
window = QtGui.QMainWindow()
window.resize(800,600)
myFrame = QtGui.QFrame(window)
myFrame.resize(200,200)
myFrame.move(10,10)
main = Browser(centralWidget=myFrame, default_url='https://www.google.com/', forwardButton=False, backButton=False, topBar=False)
window.show()
sys.exit(app.exec_())
Like I said, it could use work, but it does exactly what I needed it to do. Now I can embed it into a frame (with the size of my choosing) to use within another application.
Regarding my modifications: I made it possible to keep/remove the back button, forward button and top bar (for the URL). But the webbrowser is still controllable using the "open" function.
And if you wanted to open another webpage, it's as simple as the following
main.open('https://your.webpage.here.com')
So, I am new to python programming. I have started to implement a UI in pyqt5 and there I have a button and I want to react when the user clicks it.
According to this Link I should simply write btn.clicked.connect(self.buton_pressed) however I get the message "Cannot find reference connect in function". (The surrounding code is at the end of the question)
So I googled a bit and all I found is that it should just work that way. I just don't get why it does not. I found this Stackoverflow question which also describes the old variant of how to do it. That did not work either, after some googeling I found out that it is no longer supported in pyqt5 or in some other package.
The function where I try to connec to the event:
def __add_button(self, text: str, layout: QLayout):
btn = QPushButton(text, self)
layout.addWidget(btn)
btn.clicked.connect(self.button_pressed)
# TODO: fix this.
return btn
The code where the GUI is generated and the function called, in the __init__ function
lblhm = QLabel("Hauptmessung", self)
layout.addWidget(lblhm)
self.__hm_b = self.__add_button("Messung öffnen", layout)
self.__hm_config_b = self.__add_button("Configruation öffnen", layout)
lblzm = QLabel("Zusatzmessung", self)
layout.addWidget(lblzm)
self.__zm_b = self.__add_button("Messung öffnen", layout)
self.__zm_config_b = self.__add_button("Configuration öffnen", layout)
The button_pressed function is not yet implemented, but it is supposed to open a openFile dialog for file selection.
According to this post i could just connect after returning the function, but then i would have to write it 4 times which is not very nice. Isn't the signal bound to the object not to the variable?
Thankful for any help :)
It's hard to understand your problem since you don't provide us with a working example, i.e. a peace of code one can run "as is". Something like this:
from PyQt4 import QtCore, QtGui
class MyWindow(QtGui.QWidget):
def __init__(self):
super().__init__()
layout = QtGui.QVBoxLayout()
self.setLayout(layout)
lblhm = QtGui.QLabel("Hauptmessung", self)
layout.addWidget(lblhm)
self.__hm_b = self.__add_button("Messung öffnen", layout)
self.__hm_config_b = self.__add_button("Configruation öffnen", layout)
lblzm = QtGui.QLabel("Zusatzmessung", self)
layout.addWidget(lblzm)
self.__zm_b = self.__add_button("Messung öffnen", layout)
self.__zm_config_b = self.__add_button("Configuration öffnen", layout)
def button_pressed(self):
print('Button pressed')
def __add_button(self, text: str, layout: QtGui.QLayout):
btn = QtGui.QPushButton(text, self)
layout.addWidget(btn)
btn.clicked.connect(self.button_pressed)
return btn
if __name__== '__main__':
import sys
app = QtGui.QApplication(sys.argv)
wnd = MyWindow()
wnd.show()
sys.exit(app.exec_())
There's no problem with this code under PyQt4. Does it work for with PyQt5?
I need to reimplement the "copy link" of a QWebView in the context menu for doing some other things inside the routine.
The copy link is the only one that really works inside an ajax site so I'm trying to reimplement the "download from link" passing trough this method.
The problem is that I don't know how to reimplement the basic functions of the "copy link" for retrieving the URL.
You can add extra menu items by reimplementing QWebView.contextMenu and generating a standard menu with QWebPage.createStandardContextMenu.
Then all you need to do is get a hit-test result from the position the context menu was requested from to give you the url (if there is one).
Here's a simple demo of the basic ideas:
from PyQt4 import QtGui, QtWebKit
class Browser(QtWebKit.QWebView):
def __init__(self):
super(Browser, self).__init__()
self.setHtml('''
<html><head><title>Test Page</title>
<body>
<p>link</p>
</body>
</html>
''')
def contextMenuEvent(self, event):
menu = self.page().createStandardContextMenu()
hit = self.page().currentFrame().hitTestContent(event.pos())
url = hit.linkUrl()
if not url.isEmpty():
menu.addSeparator()
action = menu.addAction('Download')
action.triggered.connect(lambda: self.download(url))
menu.exec_(event.globalPos())
def download(self, url):
print('download:', url)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
browser = Browser()
browser.setGeometry(800, 200, 400, 200)
browser.show()
sys.exit(app.exec_())
I want to dive in Python by building a simple browser-application. I've mad a minimalistic webkitbrowser with a tutorial and now want to extend the program, but I'm stuck at some tiny problems I cannot solve.
Python 3.3.3
using Glade for the UI
The first step is to simply add a second scrolledWindow in which the developer-tools should load, immediately.
Here is my .ui-file so far, and this is the python-code:
from gi.repository import Gtk, WebKit
UI_FILE = "browser.ui"
class Browser:
"""A simple Webkit-Browser in GTK+"""
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file(UI_FILE)
self.builder.connect_signals(self)
self.back = self.builder.get_object("back")
self.forward = self.builder.get_object("forward")
self.adress = self.builder.get_object("adress")
self.webview = WebKit.WebView()
scrolled_window = self.builder.get_object("scrolledwindow")
scrolled_window.add(self.webview)
self.settings = WebKit.WebSettings()
self.settings.set_property('enable-developer-extras', True)
self.webview.set_settings(self.settings)
self.devtools = WebKit.WebInspector()
scrolled_window_dev = self.builder.get_object("scrolledwindowDev")
scrolled_window_dev.add(self.devtools)
^^^^^
self.webview.connect("title-changed", self.on_title_changed)
self.window = self.builder.get_object("window")
self.window.show_all()
def on_title_changed(self, webview, frame, title):
self.window.set_title(title)
def on_button_clicked(self, button):
if button.get_stock_id() == Gtk.STOCK_GO_FORWARD:
self.webview.go_forward()
elif button.get_stock_id() == Gtk.STOCK_GO_BACK:
self.webview.go_back()
def on_entry_activate(self, widget):
url = widget.get_text()
if not "http://" in url:
url = "http://"+url
self.webview.load_uri(url)
def destroy(self, window):
Gtk.main_quit()
def main():
app = Browser()
Gtk.main()
if __name__ == "__main__":
main()
I get the error
TypeError: argument widget: Expected Gtk.Widget, but got
gi.repository.WebKit.WebInspector
Okay, this is stated in the reference of Webkit, that WebInspector is a GObject and not a GtkWidget. But I don't know what to do now.
So, can I make a GtkWidget from a GObject (if yes - how) or should I attach the dev-tools in a complete different way?
The inspector, as you noted, isn't a widget. It's a web page, so you need to create another webview for it. You do this by getting self.window.props.web_inspector (don't create a new inspector) and connecting to its inspect-web-view signal. Inside that signal handler, you need to create a new webview, add that webview to a window or wherever you want to display it, and return it.
You'll probably also want to handle the show-window, attach-window, detach-window, and close-window signals.
More documentation here: inspect-web-view
Example of running Inspector in separate window. Webkit-gtk.
This gist without many signals connected.
https://gist.github.com/alex-eri/53518825b2a8a50dd1695c69ee5058cc