working on simple GUI project. I've got some code from online,and found out how to connect the IP-webcam app, but the question is how do I use this code in my PyQt4 GUI so that the visual of the camera will be shown in the scroll-area widget.
This is the code i used:
import urllib
import cv2
import numpy as np
url='http://192.168.0.100:8080/shot.jpg'
while True:
imgResp=urllib.urlopen(url)
imgNp=np.array(bytearray(imgResp.read()),dtype=np.uint8)
img=cv2.imdecode(imgNp,-1)
# all the opencv processing is done here
cv2.imshow('test',img)
if ord('q')==cv2.waitKey(10):
exit(0)
As #furas points out, a possible option is to use numpy and cv2 to convert it to QPixmap and display it in a QLabel, and so that it looks like streaming run it in a loop.
But instead of getting complicated with all of the above, the simplest thing is to use QtNetwork to get the bytes and convert it directly to QPixmap and send it through signals:
from PyQt4 import QtCore, QtGui, QtNetwork
class IPWebcam(QtCore.QObject):
pixmapChanged = QtCore.pyqtSignal(QtGui.QPixmap)
def __init__(self, url, parent=None):
super(IPWebcam, self).__init__(parent)
self._url = url
self.m_manager = QtNetwork.QNetworkAccessManager(self)
self.m_manager.finished.connect(self._on_finished)
self.m_stopped = True
def start(self):
self.m_stopped = False
self._launch_request()
def stop(self):
self.m_stopped = True
def _launch_request(self):
request = QtNetwork.QNetworkRequest(QtCore.QUrl(self._url))
self.m_manager.get(request)
#QtCore.pyqtSlot(QtNetwork.QNetworkReply)
def _on_finished(self, reply):
ba = reply.readAll()
pixmap = QtGui.QPixmap()
if pixmap.loadFromData(ba):
self.pixmapChanged.emit(pixmap)
if not self.m_stopped:
self._launch_request()
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.m_label = QtGui.QLabel()
self.m_button = QtGui.QPushButton(
"Start", clicked=self.onClicked, checkable=True
)
lay = QtGui.QVBoxLayout(self)
lay.addWidget(self.m_label)
lay.addWidget(self.m_button)
self.resize(640, 480)
url = "http://192.168.0.100:8080/shot.jpg"
self.m_webcam = IPWebcam(url, self)
self.m_webcam.pixmapChanged.connect(self.m_label.setPixmap)
#QtCore.pyqtSlot(bool)
def onClicked(self, checked):
if checked:
self.m_button.setText("Stop")
self.m_webcam.start()
else:
self.m_button.setText("Start")
self.m_webcam.stop()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Related
I am trying to display console output of a python script in a QplainTextEdit widget in PyQt5.
I am getting this error:
TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
I have defined my objects in the pyqt GUI file and I believe that I have all the imports.
Update
I have amended the code in this question:
from PyQt5.QtCore import QRectF, Qt
from PyQt5.QtWidgets import QFileDialog, QPlainTextEdit
from PyQt5 import QtCore, QtGui, QtWidgets
from PIL import Image, ImageQt, ImageEnhance
# from PyQt5.QtGui import Qt
from pyqtgraph.examples.text import text
from covid19gui_V3 import Ui_MainWindow
import os
import sys
input_img = Image.open("/home/ironmantis7x/Documents/Maverick_AI/Python/keras-covid-19/maverickAI30k.png")
text_edit = QPlainTextEdit()
class EmittingStream(QtCore.QObject):
textWritten = QtCore.pyqtSignal(str)
def write(self, text):
self.textWritten.emit(str(text))
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
textWritten = QtCore.pyqtSignal(str)
def __init__(self, parent=None, **kwargs):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.ShowIButton.clicked.connect(self.do_test)
self.chooseStudy.clicked.connect(self.do_choosestudy)
self.RunButton_3.clicked.connect(self.do_runstudy)
self.scene = QtWidgets.QGraphicsScene(self)
self.graphicsView.setScene(self.scene)
w, h = input_img.size
self.pixmap_item = self.scene.addPixmap(QtGui.QPixmap())
# self.graphicsView.fitInView(QRectF(0, 0, w, h), Qt.KeepAspectRatio)
self.graphicsView.update()
self.plainTextEdit.update()
self.level = 1
self.enhancer = None
self.timer = QtCore.QTimer(interval=500, timeout=self.on_timeout)
sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
def write(self, text):
self.textWritten.emit(str(text))
#QtCore.pyqtSlot()
def do_test(self):
# input_img = Image.open("/home/ironmantis7x/Documents/Maverick_AI/Python/keras-covid-19/maverickAI30k.png")
self.enhancer = ImageEnhance.Brightness(input_img)
self.timer.start()
self.ShowIButton.setDisabled(True)
#QtCore.pyqtSlot()
def on_timeout(self):
if self.enhancer is not None:
result_img = self.enhancer.enhance(self.level)
qimage = ImageQt.ImageQt(result_img)
self.pixmap_item.setPixmap(QtGui.QPixmap.fromImage(qimage))
if self.level > 7:
self.timer.stop()
self.enhancer = None
self.level = 0
self.ShowIButton.setDisabled(False)
self.level = 1
self.ShowIButton.setDisabled(False)
#QtCore.pyqtSlot()
def do_choosestudy(self):
dlg = QFileDialog()
dlg.setFileMode(QFileDialog.AnyFile)
if dlg.exec_():
filenames = dlg.selectedFiles()
f = open(filenames[0], 'r')
#QtCore.pyqtSlot()
def do_runstudy(self):
os.system("df -h")
# filetext = open('screenout.txt').read()
# filetext.close()
# textViewValue = self.plainTextEdit.toPlainText()
# QPlainTextEdit.appendPlainText(self, str(textViewValue))
# sys.stdout = self(textWritten=self.textWritten)
self.normalOutputWritten(text_edit)
def __del__(self):
# Restore sys.stdout
sys.stdout = sys.__stdout__
def normalOutputWritten(self, text_edit):
#cursor = self.plainTextEdit.textCursor()
#cursor.movePosition(QtGui.QTextCursor.End)
#cursor.insertText(text_edit)
self.plainTextEdit.appendPlainText(text_edit)
#self.plainTextEdit.ensureCursorVisible()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
How can I make this work correctly?
Update 2
I indeed DID do research into the topic and this is one of the main resources I used to try to solve the issue before I posted my question: How to capture output of Python's interpreter and show in a Text widget?
Update 3
I have revised my code in the post to reflect code suggestions in the link I used to help me with my issue.
I am still unable to get this to run correctly. I now get this error:
self.plainTextEdit.appendPlainText(text_edit) TypeError:
appendPlainText(self, str): argument 1 has unexpected type
'QPlainTextEdit'
I have a user interface, TableManagerWindow, that I've been maintaining and developing in Qt designer. After converting via pyuic to a *.py file, I was able to implement what Ferdinand Beyer had suggested in the link you provided above. Simple button to print text to terminal and it indeed does get appended to the QTextEdit widget via append(). Not sure this fits the bill for you for some reason, but I can vouch that it worked for me as well. I'm not savvy enough to get the nuance that is causing your issue, but figured I'd put this here just in case. Admins feel free to delete this if it's extraneous, but it works.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
# Define a stream, custom class, that reports data written to it, with a Qt signal
class EmittingStream(QtCore.QObject):
textWritten = QtCore.pyqtSignal(str)
def write(self, text):
self.textWritten.emit(str(text))
class Ui_TableManagerWindow(object):
def setupUi(self, TableManagerWindow):
#define all of my widgets, layout, etc here
.
.
.
# Install a custom output stream by connecting sys.stdout to instance of EmmittingStream.
sys.stdout = EmittingStream(textWritten=self.output_terminal_written)
# Create my signal/connections for custom method
self.source_dir_button.clicked.connect(self.sourceDirButtonClicked)
self.retranslateUi(TableManagerWindow)
QtCore.QMetaObject.connectSlotsByName(TableManagerWindow)
def retranslateUi(self, TableManagerWindow):
.
.
.
#custom method that prints to output terminal. The point is to have this emmitted out to my QTextEdit widget.
def sourceDirButtonClicked(self):
for i in range(10):
print("The Source DIR button has been clicked " + str(i) + " times")
#custom method to write anything printed out to console/terminal to my QTextEdit widget via append function.
def output_terminal_written(self, text):
self.output_terminal_textEdit.append(text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
TableManagerWindow = QtWidgets.QMainWindow()
ui = Ui_TableManagerWindow()
ui.setupUi(TableManagerWindow)
TableManagerWindow.show()
sys.exit(app.exec_())
I'm trying to get Maya's log(What it prints in script editor's output window) and add it to my custom PySide Qwidget.
Why this crashes Maya
QtWidgets, QtCore, QtGui
imoprt QtDesiner_UI
import maya.OpenMayaUI as OmUi
from shiboken2 import wrapInstance
import maya.OpenMaya as Om
def get_maya_window():
# Get Maya window
maya_main_window_ptr = OMUI.MQtUtil.mainWindow()
maya_main_window = wrapInstance(long(maya_main_window_ptr),
QtWidgets.QMainWindow)
return maya_main_window
class UiClass(QtWidgets.QMainWindow, QtDesiner_UI.MainWindow):
def __init__(self):
super(UiClass, self).__init__(get_maya_window())
OM.MCommandMessage.addCommandOutputFilterCallback(self.callback)
# some PySide Widgets here
self.console_widget = QtWidgets.QTextEdit()
self.main_form_layout.addRow(self.console_widget)
def callback(self, msg, mg, *args):
self.console_widget.append(msg)
def logic_stuff(self):
#maya commands here
import UI_Window
w = UI_Window.UiClass()
w.show()
And this doesn't
def callback(msg, mg ,*args):
console_widget.append(var)
OM.MCommandMessage.addCommandOutputFilterCallback(callback)
Here is the the working code that works partially. It should append log info into 'QtextEdit()' but after first operation Maya crashes(e.g. create sphere).
import maya.OpenMayaUI as OmUi
from shiboken2 import wrapInstance
from PySide2 import QtWidgets, QtCore, QtGui
import maya.OpenMaya as Om
def get_maya_window():
# Get Maya window
maya_main_window_ptr = OmUi.MQtUtil.mainWindow()
maya_main_window = wrapInstance(long(maya_main_window_ptr), QtWidgets.QMainWindow)
return maya_main_window
class MainWidget(QtWidgets.QMainWindow):
def __init__(self):
super(MainWidget, self).__init__(get_maya_window())
self.cent_ly = MW()
self.text_edit = QtWidgets.QTextEdit()
self.cent_ly.vlayout.addWidget(self.text_edit )
self.setCentralWidget(self.cent_ly )
self.callback_id = Om.MCommandMessage.addCommandOutputFilterCallback(self.callback)
def closeEvent(self, event):
Om.MMessage.removeCallback(self.callback_id)
def callback(self, message):
self.text_edit.append(message.strip())
class MW(QtWidgets.QWidget):
def __init__(self):
super(MW , self).__init__()
self.vlayout = QtWidgets.QVBoxLayout()
self.setLayout(self.vlayout)
w = MainWidget()
w.show()
And this one works without crashing Maya
import maya.OpenMayaUI as OmUi
from shiboken2 import wrapInstance
from PySide2 import QtWidgets, QtCore, QtGui
import maya.OpenMaya as Om
def get_maya_window():
# Get Maya window
maya_main_window_ptr = OmUi.MQtUtil.mainWindow()
maya_main_window = wrapInstance(long(maya_main_window_ptr), QtWidgets.QMainWindow)
return maya_main_window
class MainWidget(QtWidgets.QMainWindow):
def __init__(self):
super(MainWidget, self).__init__(get_maya_window())
self.cent_ly = MW()
self.text_edit = QtWidgets.QTextEdit()
self.cent_ly.vlayout.addWidget(self.text_edit)
self.setCentralWidget(self.cent_ly )
class MW(QtWidgets.QWidget):
def __init__(self):
super(MW , self).__init__()
self.vlayout = QtWidgets.QVBoxLayout()
self.setLayout(self.vlayout)
w = MainWidget()
w.show()
def callback(message, *args):
w.text_edit.append(message.strip())
callback_id = Om.MCommandMessage.addCommandOutputFilterCallback(callback)
# Om.MMessage.removeCallback(callback_id)
You need to remove the callback when you close the window. I was testing your code and it worked the first time, but subsequent times froze Maya.
class UiClass(QtWidgets.QMainWindow):
def __init__(self):
super(UiClass, self).__init__(get_maya_window())
self.callback_id = Om.MCommandMessage.addCommandOutputFilterCallback(self.callback)
def closeEvent(self, event):
Om.MMessage.removeCallback(self.callback_id)
Like #ababak said, the crashes happen because the object was destroyed, which happens when you close the window. So before that happens, you need to remove the callback.
You haven't shown the complete code of the first sample.
Those crashes happen when the callback is fired up but the original object has already been destroyed.
I assume you create the UiClass object but later it is garbage collected.
The second sample does not crash as you define your callback function in a global scope and it stays valid until you quit Maya.
I am working bulid a eye gaze visualization tool just like this by PyQt5, and I also checked this post.
here is the code by modifing the above links.
turn out it's worked, but the video always get stuck sometime (the audio is normal, the the frames stuck, both video content and ellipse,just like this video),anyone can help?
import os
import time
from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia, QtMultimediaWidgets
import tobii_research as tr
import numpy as np
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
#first window,just have a single button for play the video
self.resize(256, 256)
self.btn_play = QtWidgets.QPushButton(self)
self.btn_play.setGeometry(QtCore.QRect(100, 100, 28, 28))
self.btn_play.setObjectName("btn_open")
self.btn_play.setText("Play")
self.btn_play.clicked.connect(self.Play_video)#click to play video
#
self._scene = QtWidgets.QGraphicsScene(self)
self._gv = QtWidgets.QGraphicsView(self._scene)
#construct a videoitem for showing the video
self._videoitem = QtMultimediaWidgets.QGraphicsVideoItem()
#add it into the scene
self._scene.addItem(self._videoitem)
# assign _ellipse_item is the gaze data, and embed it into videoitem,so it can show above the video.
self._ellipse_item = QtWidgets.QGraphicsEllipseItem(QtCore.QRectF(0, 0, 40, 40), self._videoitem)
self._ellipse_item.setBrush(QtGui.QBrush(QtCore.Qt.black))
self._ellipse_item.setPen(QtGui.QPen(QtCore.Qt.red))
#self._scene.addItem(self._ellipse_item)
self._gv.fitInView(self._videoitem)
self._player = QtMultimedia.QMediaPlayer(self, QtMultimedia.QMediaPlayer.VideoSurface)
self._player.setVideoOutput(self._videoitem)
file = os.path.join(os.path.dirname(__file__), "video.mp4")#video.mp4 is under the same dirctory
self._player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file)))
print(f"self._videoitem::{self._videoitem.size()}")
#get eye tracker
self.eyetrackers = tr.find_all_eyetrackers()
self.my_eyetracker = self.eyetrackers[0]
def gaze_data_callback(self, gaze_data_):
#for now, I don't know the coordinate system,just randomly assign the gaze data to test the functionality
self._ellipse_item.setPos(float(np.random.choice(range(0, 300))), float(np.random.choice(range(0, 240))))
print("time.time()::{}".format(time.time()))
def Play_video(self):
self.my_eyetracker.subscribe_to(tr.EYETRACKER_GAZE_DATA, self.gaze_data_callback, as_dictionary=True)
#size = QtCore.QSizeF(1920.0, 1080.0)#I hope it can fullscreen the video
#self._videoitem.setSize(size)
#self._gv.showFullScreen()
self._gv.resize(720,720)
self._gv.show()
self._player.play()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
cmd printout information here
According to the warning message:
QObject::startTimer: Timers can only be used with threads started with QThread
it can be deduced that the callback associated with "my_eyetracker" is executed in a secondary thread, so the position of the item from a different thread to the main thread would be updated, which could generate the problem described by the OP.
The solution is to send the callback information to the guide through signals.
import os
import time
from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia, QtMultimediaWidgets
import tobii_research as tr
import numpy as np
class EyeTracker(QtCore.QObject):
positionChanged = QtCore.pyqtSignal(float, float)
def __init__(self, tracker, parent=None):
super(EyeTracker, self).__init__(parent)
self._tracker = tracker
#property
def tracker(self):
return self._tracker
def start(self):
self.tracker.subscribe_to(
tr.EYETRACKER_GAZE_DATA, self._callback, as_dictionary=True
)
def _callback(self, gaze_data_):
self.positionChanged.emit(
float(np.random.choice(range(0, 300))),
float(np.random.choice(range(0, 240))),
)
print("time.time()::{}".format(time.time()))
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
# first window,just have a single button for play the video
self.resize(256, 256)
self.btn_play = QtWidgets.QPushButton(self)
self.btn_play.setGeometry(QtCore.QRect(100, 100, 28, 28))
self.btn_play.setObjectName("btn_open")
self.btn_play.setText("Play")
self.btn_play.clicked.connect(self.Play_video) # click to play video
#
self._scene = QtWidgets.QGraphicsScene(self)
self._gv = QtWidgets.QGraphicsView(self._scene)
# construct a videoitem for showing the video
self._videoitem = QtMultimediaWidgets.QGraphicsVideoItem()
# add it into the scene
self._scene.addItem(self._videoitem)
# assign _ellipse_item is the gaze data, and embed it into videoitem,so it can show above the video.
self._ellipse_item = QtWidgets.QGraphicsEllipseItem(
QtCore.QRectF(0, 0, 40, 40), self._videoitem
)
self._ellipse_item.setBrush(QtGui.QBrush(QtCore.Qt.black))
self._ellipse_item.setPen(QtGui.QPen(QtCore.Qt.red))
# self._scene.addItem(self._ellipse_item)
self._gv.fitInView(self._videoitem)
self._player = QtMultimedia.QMediaPlayer(
self, QtMultimedia.QMediaPlayer.VideoSurface
)
self._player.setVideoOutput(self._videoitem)
file = os.path.join(
os.path.dirname(__file__), "video.mp4"
) # video.mp4 is under the same dirctory
self._player.setMedia(
QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file))
)
print(f"self._videoitem::{self._videoitem.size()}")
# get eye tracker
eyetrackers = tr.find_all_eyetrackers()
self.tracker = EyeTracker(eyetrackers[0])
self.tracker.positionChanged.connect(self._ellipse_item.setPos)
def Play_video(self):
self.tracker.start()
# size = QtCore.QSizeF(1920.0, 1080.0)#I hope it can fullscreen the video
# self._videoitem.setSize(size)
# self._gv.showFullScreen()
self._gv.resize(720, 720)
self._gv.show()
self._player.play()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
I am trying to create something like this (autocomplete places) in pyqt5 QLineEdit.
There is a class called QCompleter with which i can suggest the content, but it requires an already formed list, but this google places api is a suggestion based function, how can i send each keystroke to google api and get the suggestion back and load in Qtextedit, is there a better way to do it
For this case you can create a custom model that makes a request using Place Autocomplete, and set that model to a QCompleter:
import json
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
API_KEY = "<API_KEY>"
class SuggestionPlaceModel(QtGui.QStandardItemModel):
finished = QtCore.pyqtSignal()
error = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(SuggestionPlaceModel, self).__init__(parent)
self._manager = QtNetwork.QNetworkAccessManager(self)
self._reply = None
#QtCore.pyqtSlot(str)
def search(self, text):
self.clear()
if self._reply is not None:
self._reply.abort()
if text:
r = self.create_request(text)
self._reply = self._manager.get(r)
self._reply.finished.connect(self.on_finished)
loop = QtCore.QEventLoop()
self.finished.connect(loop.quit)
loop.exec_()
def create_request(self, text):
url = QtCore.QUrl("https://maps.googleapis.com/maps/api/place/autocomplete/json")
query = QtCore.QUrlQuery()
query.addQueryItem("key", API_KEY)
query.addQueryItem("input", text)
query.addQueryItem("types", "geocode")
query.addQueryItem("language", "en")
url.setQuery(query)
request = QtNetwork.QNetworkRequest(url)
return request
#QtCore.pyqtSlot()
def on_finished(self):
reply = self.sender()
if reply.error() == QtNetwork.QNetworkReply.NoError:
data = json.loads(reply.readAll().data())
if data['status'] == 'OK':
for prediction in data['predictions']:
self.appendRow(QtGui.QStandardItem(prediction['description']))
self.error.emit(data['status'])
self.finished.emit()
reply.deleteLater()
self._reply = None
class Completer(QtWidgets.QCompleter):
def splitPath(self, path):
self.model().search(path)
return super(Completer, self).splitPath(path)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self._model = SuggestionPlaceModel(self)
completer = Completer(self, caseSensitivity=QtCore.Qt.CaseInsensitive)
completer.setModel(self._model)
lineedit = QtWidgets.QLineEdit()
lineedit.setCompleter(completer)
label = QtWidgets.QLabel()
self._model.error.connect(label.setText)
lay = QtWidgets.QFormLayout(self)
lay.addRow("Location: ", lineedit)
lay.addRow("Error: ", label)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(400, w.sizeHint().height())
w.show()
sys.exit(app.exec_())
I faced the same issue, at first I tried #eyllanasec's answer. But for some reason, the performance is not so good (often stuck or hang) in the platform that I use (I was creating a plugin for Qt-based software using PyQt). It is running fine independently though, so perhaps it's specific to my platform.
In the end, I found a Qt example project for a similar case, Google Suggest. You can find it https://doc.qt.io/qt-5/qtnetwork-googlesuggest-example.html. It creates a custom class to handle the search and the pop-up window (using QTreeWidget).
Since the example is in Qt, I port it to PyQt with small modification https://github.com/ismailsunni/scripts/blob/master/autocomplete_from_url.py
I have a browser application written in python with PySide Qt. But now I want to add a button in the toolbar to print the website. How do I do this? Because CTRL + P is not working in the application.
Here is the code:
import sys
from PySide import QtCore, QtGui, QtWebKit, QtHelp, QtNetwork
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
Action1 = QtGui.QAction('Google', self)
Action1.setShortcut('Ctrl+M')
Action1.triggered.connect(self.load_message)
self.toolbar1 = self.addToolBar('Google')
self.toolbar1.addAction(Action1)
Action2 = QtGui.QAction('Yahoo', self)
Action2.setShortcut('Ctrl+H')
Action2.triggered.connect(self.load_list)
self.toolbar2 = self.addToolBar('Yahoo')
self.toolbar2.addAction(Action2)
exitAction = QtGui.QAction('Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.triggered.connect(self.on_exit)
self.toolbar3 = self.addToolBar('Exit')
self.toolbar3.addAction(exitAction)
self.resize(750, 750)
self.setWindowTitle('Browser')
self.web = QtWebKit.QWebView(self)
self.web.load(QtCore.QUrl('http://www.google.com'))
self.setCentralWidget(self.web)
def on_exit(self):
QtGui.qApp.quit
def load_message(self):
self.web.load(QtCore.QUrl('http://www.google.com'))
def load_list(self):
self.web.load(QtCore.QUrl('http://www.yahoo.com'))
app = QtGui.QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon('myicon.ico'))
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
In your __init__ method add a Print action:
printAction = QtGui.QAction('Print', self)
printAction.setShortcut('Ctrl+P')
printAction.triggered.connect(self.do_print)
self.toolbar4 = self.addToolBar('Print')
self.toolbar4.addAction(printAction)
And create a do_print method:
def do_print(self):
p = QtGui.QPrinter()
p.setPaperSize(QtGui.QPrinter.A4)
p.setFullPage(True)
p.setResolution(300)
p.setOrientation(QtGui.QPrinter.Portrait)
p.setOutputFileName('D:\\test.pdf')
self.web.print_(p)
This will print to a file D:\test.pdf.
To configure your printer differently see the QPrinter documentation. Also if you want a print preview dialog see the QPrintPreviewDialog docs.
If you want a standard print dialog the use:
def do_print(self):
p = QtGui.QPrinter()
dialog = QtGui.QPrintDialog(p)
dialog.exec_()
self.web.print_(p)