I have a code that suppose to open/create new window if the link is target _blank but, it doesn't do as intended and gives no action in return.
Here is the code:
class MyPage(QWebEnginePage):
def __init__(self, parent=None):
super(MyPage, self).__init__(parent)
def triggerAction(self, action, checked=False):
if action == QWebEnginePage.OpenLinkInNewWindow:
self.createWindow(QWebEnginePage.WebBrowserWindow)
return super(MyPage, self).triggerAction(action, checked)
class MyWindow(QtWebEngineWidgets.QWebEngineView):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.myPage = MyPage(self)
self.setPage(self.myPage)
def createWindow(self, windowType):
if windowType == QWebEnginePage.WebBrowserWindow:
self.webView = MyWindow()
self.webView.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
return self.webView
return super(MyWindow, self).createWindow(windowType)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
main.load(QUrl("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_a_target"))
sys.exit(app.exec_())
Would like to know why it's not working, if possible.
Thanks,
Max
If you directly test the link in any browser you will see that the action is to create a new tab, so windowType is for that case the type QWebEnginePage::WebBrowserTab, at that time we create the new window and show it as shown below:
class MyWindow(QWebEngineView):
[...]
def createWindow(self, windowType):
if windowType == QWebEnginePage.WebBrowserTab:
self.webView = MyWindow()
self.webView.setAttribute(Qt.WA_DeleteOnClose, True)
self.webView.show()
return self.webView
return super(MyWindow, self).createWindow(windowType)
Related
I have a scenario where one window is running in python Pyqt5. I want that when certain event happens another window also opens up.
I have written a code which I suppose should run fine but when event occurs to open other GUI, I gets an error.
My code:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
app = QApplication(sys.argv)
win = QWidget()
l1 = QLabel("URL:")
url = QLineEdit()
l3 = QLabel("Wait (sec):")
wait = QLineEdit()
l2 = QLabel("Iteration:")
l2.move(20,100)
global add1
count = QLineEdit()
fbox = QFormLayout()
fbox.addRow(l1, url)
fbox.addRow(l3, wait)
vbox = QVBoxLayout()
vbox.addWidget(count)
fbox.addRow(l2, vbox)
startButton=QPushButton("Start")
fbox.addRow(startButton)
startButton.clicked.connect(self.requests)
win.setLayout(fbox)
win.setWindowTitle("--")
win.resize(300,200)
win.show()
sys.exit(app.exec_())
def requests(self):
for x in range(0,int(count.text())):
//certain event happens here, which will cause other window to get open
self.dialog = PopUp(self)
self.dialog.show()
def stop(self):
sys.exit()
class PopUp(QMainWindow):
def __init__(self, parent=None):
super(PopUp, self).__init__(parent)
app = QApplication(sys.argv)
win = QWidget()
l1 = QLabel("URL:")
nextUrl = QLineEdit()
fbox = QFormLayout()
fbox.addRow(l1, url)
startButton = QPushButton("Go")
fbox.addRow(startButton)
startButton.clicked.connect(self.requests)
win.setLayout(fbox)
win.setWindowTitle("--")
win.resize(300, 200)
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
I see that code is right but I am getting an unknown error:
QCoreApplication::exec: The event loop is already running
I have searched on google and here in stack overflow but didn't get anything worthy. Anyone knows that why this error comes and why is it coming in my code??
Each PyQt5 application must create one application object app = QApplication(sys.argv). Remove from the class MainWindow and the class PopUp - app = QApplication (sys.argv) .
sys.exit(app.exec_()) - the mainloop of the application, he must also be alone. Remove from the class MainWindow and the class PopUp - sys.exit(app.exec_())
I improved the readability of your example a bit.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class PopUp(QMainWindow):
def __init__(self, x, url, parent=None):
super(PopUp, self).__init__(parent)
self.url = url.text()
self.x = x + 1
self.setWindowTitle("-- PopUp {} --".format(self.x))
self.setGeometry(self.x*100, self.x*100, 300, 200)
win = QWidget()
self.setCentralWidget(win)
nextUrl = QLineEdit(self.url)
self.startButton = QPushButton("Go {}".format(self.x))
fbox = QFormLayout(win)
fbox.addRow(QLabel("URL:"), nextUrl)
fbox.addRow(self.startButton)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.dialogs = []
self.flag = False
win = QWidget()
self.setCentralWidget(win)
self.url = QLineEdit() # + self
wait = QLineEdit()
self.count = QLineEdit() # + self
startButton = QPushButton("Start")
startButton.clicked.connect(self.requests)
fbox = QFormLayout(win)
fbox.addRow(QLabel("URL:"), self.url)
fbox.addRow(QLabel("Wait (sec):"), wait)
fbox.addRow(QLabel("Iteration:"), self.count)
fbox.addRow(startButton)
def requests(self):
if self.dialogs and self.flag:
_ = [ i.hide() for i in self.dialogs]
self.dialogs = []
for x in range(0, int(self.count.text())):
# certain event happens here, which will cause other window to get open
dialog = PopUp(x, self.url, self)
dialog.startButton.clicked.connect(self.requests2)
dialog.show()
self.dialogs.append(dialog)
self.flag = True
def stop(self): # ?
sys.exit()
def requests2(self):
print("def requests2(self): clicked Button {}".format(self.sender().text()))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainWindow()
main.setWindowTitle("-- Title --")
main.resize(300,200)
main.show()
sys.exit(app.exec_())
How can I add a context menu to the items in my QToolBar. The reason for the context menu, is i want to give each Action a right-click > Delete action. Similar to the Chrome browsers ability to remove bookmarks from the bookmark toolbar. How do i achieve this in Pyside?
import os, sys
from PySide import QtGui, QtCore
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.resize(300,200)
self.createToolBars()
self.createActions()
def createToolBars(self):
self.toolBar = self.addToolBar('Presets')
self.toolBar.setIconSize(QtCore.QSize(16,16))
self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
def createActions(self):
self.toolBar.clear()
presets = ['Abby','Kevin','Bob','Mary']
for x in presets:
act = QtGui.QAction(x, self)
act.setData(x)
self.toolBar.addAction(act)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
You have to implement a custom QToolBar and implement the contextMenuEvent method:
import os
import sys
from PySide import QtCore, QtGui
class ToolBar(QtGui.QToolBar):
def contextMenuEvent(self, event):
current_action = self.actionAt(event.pos())
if current_action is None:
return
menu = QtGui.QMenu()
delete_action = menu.addAction("delete")
action = menu.exec_(event.globalPos())
if action == delete_action:
self.removeAction(current_action)
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.resize(300,200)
self.createToolBars()
self.createActions()
def createToolBars(self):
self.tool_bar = ToolBar('Presets', self)
self.addToolBar(self.tool_bar)
self.tool_bar.setIconSize(QtCore.QSize(16,16))
self.tool_bar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
def createActions(self):
self.tool_bar.clear()
presets = ['Abby','Kevin','Bob','Mary']
for x in presets:
act = QtGui.QAction(x, self)
act.setData(x)
self.tool_bar.addAction(act)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
How can I get the value returned from mousePressEvent of a widget and apply it to another widget?
Here's the widget with the mousePressEvent:
class Text(QTextEdit):
...
def mousePressEvent(self, event):
if event.button()==Qt.LeftButton:
return "test"
Now I want to use the string returned from the event and apply it to another widget:
class OtherWidget(QWidget):
...
self.label=QLabel()
self.label.setText(???) # <=== How to put the string here?
...
How can I do that? I have tried the following but it does not work.
self.label.setText(Text().mousePressEvent())
The events do not return anything for what you point out is impossible, Qt to send information asynchronously uses the signals, in the next part I show an example:
from PyQt5 import QtCore, QtWidgets
class Text(QtWidgets.QTextEdit):
mousePressSignal = QtCore.pyqtSignal(str)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
text = "test: {}-{}".format(event.pos().x(), event.pos().y())
self.mousePressSignal.emit(text)
class OtherWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(OtherWidget, self).__init__(parent)
self.label = QtWidgets.QLabel()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
#QtCore.pyqtSlot(str)
def setText(self, text):
self.label.setText(text)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
t = Text()
o = OtherWidget()
o.resize(640, 480)
t.mousePressSignal.connect(o.setText)
t.show()
o.show()
sys.exit(app.exec_())
i am building a desktop application using PyQt python which has a QwebBrowser. now i am running some function using javascript which is returning a value say abc as per following example.
class QWebView(QWebView):
def contextMenuEvent(self,event):
menu = QMenu()
self.actionShowXpath = menu.addAction("Show Xpath")
QObject.connect(self.actionShowXpath,SIGNAL("triggered()"),self,SLOT("slotshowxpath()"))
menu.exec_(self.mapToGlobal(QPoint(event.x(),event.y())))
#pyqtSlot()
def slotshowxpath(self):
frame.evaluateJavaScript("var abc = function get()");
result = frame.evaluateJavaScript("abc").toString()
**some code code to put result in QLineEdit Widget**
# something like below
# xpath.setText(result)
def window():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
web = QWebView(w)
web.load(QUrl("http://www.indiatimes.com/"))
web.show()
xpath = QtGui.QLineEdit("", w)
sys.exit(app.exec_())
if __name__ == '__main__':
window()
now, i want to put the value of abc in a QLineEdit widget("xpath") present in my application.please give me suggestion that how i can i do this?
I can't work up an example because QtWebkit has been removed from Qt 5.6, but if the problem you are having is because you don't have a reference to your QLineEdit, then pass the QLineEdit to your QWebView class's __init__() function:
def start_app():
app = QtGui.QApplication(sys.argv)
main_window = QtGui.QWidget()
xpathInput = QtGui.QLineEdit(main_window)
web_view = MyWebView(main_window, xpathInput) #<===HERE
web_view.load(QUrl("http://www.indiatimes.com/"))
main_window.show()
sys.exit(app.exec_())
Then in your QWebView class:
class MyWebView(QWebView):
def __init__(self, parent, xpath_widget):
#QWebView.__init__(parent)
QWebView.__init__(self, parent)
#or: super(MyWebView, self).__init__(parent)
self.xpath_widget = xpath_widget
def contextMenuEvent(self,event):
menu = QMenu()
self.actionShowXpath = menu.addAction("Show Xpath")
#QObject.connect(
# self.actionShowXpath,
# SIGNAL("triggered()"),
# self,SLOT("slotshowxpath()")
#)
self.actionShowXpath.triggered.connect(self.show_xpath)
menu.exec_(self.mapToGlobal(QPoint(event.x(),event.y())))
##pyqtSlot()
def show_xpath(self):
frame = ...
frame.evaluateJavaScript("var abc = function get()");
result = frame.evaluateJavaScript("abc").toString()
#some code code to put result in QLineEdit Widget**
self.xpath_widget.setText(result)
But I think a better way to organize your code would be to do something like this:
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.xpathInput = QtGui.QLineEdit(self)
self.web_view = QWebView(self)
self.web_view.load(QUrl("http://www.indiatimes.com/"))
self.menu = QMenu()
self.actionShowXpath = self.menu.addAction("Show Xpath")
#QObject.connect(
# self.actionShowXpath,
# SIGNAL("triggered()"),
# self,SLOT("slotshowxpath()")
#)
self.actionShowXpath.triggered.connect(self.show_xpath)
menu.exec_(self.mapToGlobal(QPoint(event.x(),event.y())))
def show_path(self):
frame = ...
result = frame.evaluateJavaScript("abc").toString()
self.xpathInput.setText(result)
def start_app():
app = QtGui.QApplication(sys.argv)
main_window = MyWindow()
main_window.show()
sys.exit(app.exec_())
this example
helped me a lot in understanding of how does the events work.
But I have another problem. After an event when I want to call a function of a main class it seems like it was starting from Filter class and, unfortunately I'm not able to fetch the content from Designer-made file.
class Filter(QtCore.QObject):
def eventFilter(self, widget, event):
if event.type() == QtCore.QEvent.FocusOut:
print 'focus out'
print widget.objectName()
if widget.objectName() == 'edit_notes':
StartQT4().object_edit_notes('edit_notes')
return False
else:
return False
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self._filter = Filter()
self.ui.edit_notes.installEventFilter(self._filter)
def object_edit_notes(self, w):
self.__init__()
something = self.ui.edit_notes.toPlainText()
something = unicode(something).encode('utf-8')
print something
return False
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
Attribute .something prints nothing. I tried to call identical function with the signal method button clicked() and it works fine.
Can you help me with this?
You don't need a separate class for the event-filter. Any object which inherits QObject or QWidget will do, which includes QMainWindow.
So move the event-filter into your StartQT4 class, like this:
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# filter the events through self
self.ui.edit_notes.installEventFilter(self)
def object_edit_notes(self, w):
# this will convert a QString to a python unicode object
something = unicode(self.ui.edit_notes.toPlainText())
print something
def eventFilter(self, widget, event):
if (event.type() == QtCore.QEvent.FocusOut and
widget is self.ui.edit_notes):
print 'focus out'
self.object_edit_notes('edit_notes')
return False
return QMainWindow.eventFilter(self, widget, event)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())