I am making a very simple browser with a search box using PyQt5 WebKit. This is the code I'm using:
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow, QGridLayout)
from PyQt5.QtWebKitWidgets import QWebView
class App(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.searchbox = QLineEdit("", self)
self.go = QPushButton('Go', self)
self.go.clicked.connect(self.gourl)
self.webview = Browser()
self.grid = QGridLayout(centralWidget)
self.grid.addWidget(self.webview, 0, 0, 1, 4)
self.grid.addWidget(self.searchbox, 1, 0)
self.grid.addWidget(self.go, 1, 1)
def gourl(self):
url = self.searchbox.text()
self.webview.load(QUrl(url))
class Browser(QWebView): #(QWebView):
windowList = []
def createWindow(self, QWebEnginePage_WebWindowType):
App.setCentralWidget(Browser())
#new_window.show()
self.windowList.append(App())
return Browser()
if __name__ == "__main__":
app = QApplication(sys.argv)
box = App()
box.setWindowTitle('Browser')
box.resize(600, 500)
box.show()
sys.exit(app.exec_())
I want to keep the URL in the box updated with whatever current URL the user is on. I have no idea how to go about this, any help would be appreciated.
Below is a re-write of your example which should do what you want.
The Browser class has been fixed so that it creates a new instance of App when a new window is requested. You can test this by right-clicking on a link and selecting Open in New Window. The search box will automatically update with the new url whenever it changes.
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow, QGridLayout)
from PyQt5.QtWebKitWidgets import QWebView
class App(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.searchbox = QLineEdit("", self)
self.go = QPushButton('Go', self)
self.go.clicked.connect(self.gourl)
self.webview = Browser()
self.webview.urlChanged.connect(self.handleUrlChanged)
self.grid = QGridLayout(centralWidget)
self.grid.addWidget(self.webview, 0, 0, 1, 4)
self.grid.addWidget(self.searchbox, 1, 0)
self.grid.addWidget(self.go, 1, 1)
def gourl(self):
url = self.searchbox.text()
self.webview.load(QUrl(url))
def handleUrlChanged(self, url):
self.searchbox.setText(url.toString())
class Browser(QWebView):
windowList = []
def createWindow(self, wintype):
window = App()
self.windowList.append(window)
window.show()
return window.webview
def closeEvent(self, event):
self.windowList.remove(self)
super().closeEvent(event)
if __name__ == "__main__":
app = QApplication(sys.argv)
box = App()
box.setWindowTitle('Browser')
box.resize(600, 500)
box.show()
sys.exit(app.exec_())
Related
Here's my attempt at making this work:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QTextEdit
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.on_click()
def initUI(self):
button = QPushButton('PyQt5 button', self)
button.move(100,200)
button.clicked.connect(self.on_click)
def on_click(self):
text = QTextEdit(self)
insideText = "Text"
text.document().setPlainText(insideText)
text.resize(100,25)
print('PyQt5 button click')
position = text.pos()
text.move(position.x()+50,position.y()+0)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
Maybe I need to make the QTextEdit go somewhere in the initUI() method, instead of being defined in on_click(). I already tried this but I get "text is not defined", and I'm not sure how to reference it inside another function/method. Any help is appreciated.
Edit: Here's the working code:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton,QTextEdit
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.on_click()
def initUI(self):
self.button = QPushButton('PyQt5 button', self)
self.button.move(100,200)
self.button.clicked.connect(self.on_click)
self.text = QTextEdit(self)
insideText = "Text"
self.text.document().setPlainText(insideText)
self.text.resize(100,25)
def on_click(self):
print('PyQt5 button click')
position = self.text.pos()
self.text.move(position.x()+50,position.y()+0)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
I am trying to display an image from a URL in pyside6, but can't get anything to work.
def getIcon(data):
iconID = data['weather'][0]['icon']
icon = QPixmap("http://openweathermap.org/img/w/" + iconID + ".png");
return icon
And
self.temperatureIcon = QtWidgets.QLabel(self).setPixmap(getIcon(self.weatherData))
is the code I have.
QPixmap does not download the image from a url so you must download it for example using QNetworkAccessManager:
import sys
from functools import cached_property
from PySide6.QtCore import Signal, QObject, Qt, QUrl
from PySide6.QtGui import QImage, QPixmap
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
from PySide6.QtWidgets import (
QApplication,
QGridLayout,
QLabel,
QLineEdit,
QPushButton,
QWidget,
)
class ImageDownloader(QObject):
finished = Signal(QImage)
def __init__(self, parent=None):
super().__init__(parent)
self.manager.finished.connect(self.handle_finished)
#cached_property
def manager(self):
return QNetworkAccessManager()
def start_download(self, url):
self.manager.get(QNetworkRequest(url))
def handle_finished(self, reply):
if reply.error() != QNetworkReply.NoError:
print("error: ", reply.errorString())
return
image = QImage()
image.loadFromData(reply.readAll())
self.finished.emit(image)
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.lineedit = QLineEdit()
self.button = QPushButton("Start")
self.label = QLabel(alignment=Qt.AlignCenter)
lay = QGridLayout(self)
lay.addWidget(self.lineedit, 0, 0)
lay.addWidget(self.button, 0, 1)
lay.addWidget(self.label, 1, 0, 1, 2)
self.downloader = ImageDownloader()
self.downloader.finished.connect(self.handle_finished)
self.button.clicked.connect(self.handle_clicked)
self.lineedit.setText("http://openweathermap.org/img/wn/01d#2x.png")
self.resize(640, 480)
def handle_finished(self, image):
pixmap = QPixmap.fromImage(image)
self.label.setPixmap(pixmap)
def handle_clicked(self):
url = QUrl.fromUserInput(self.lineedit.text())
self.downloader.start_download(url)
def main():
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Here's another simple solution\example:
import sys
import requests
from PySide6.QtGui import QPixmap, QScreen
from PySide6.QtWidgets import QApplication, QWidget, QLabel
URL = 'https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_(test_image).png'
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('getAndSetImageFromURL()')
self.label = QLabel(self)
self.pixmap = QPixmap()
self.getAndSetImageFromURL(URL)
self.resize(self.pixmap.width(),self.pixmap.height())
screenSize = QScreen.availableGeometry(QApplication.primaryScreen())
frmX = (screenSize.width () - self.width ())/2
frmY = (screenSize.height() - self.height())/2
self.move(frmX, frmY)
self.show()
def getAndSetImageFromURL(self,imageURL):
request = requests.get(imageURL)
self.pixmap.loadFromData(request.content)
self.label.setPixmap(self.pixmap)
#QApplication.processEvents() # uncoment if executed on loop
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = App()
sys.exit(app.exec())
which outputs:
import sys
import requests
import PySide6
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PySide6.QtWidgets import QTableView, QWidget, QApplication, QGridLayout, QHeaderView
from PySide6.QtCore import Qt, QAbstractTableModel, QObject, Signal, QUrl
from PySide6.QtGui import QColor, QIcon, QPixmap, QImage
from datetime import datetime
class MagicIcon():
def __init__(self, link):
self.link = link
self.icon = QIcon()
try:
response = requests.get(self.link)
pixmap = QPixmap()
pixmap.loadFromData(response.content)
self.icon = QIcon(pixmap)
except:
pass
class MainWindow(QWidget):
def __init__():
super().__init__()
self.setWindowIcon(MagicIcon(
"https://img.icons8.com/external-flatarticons-blue-flatarticons/65/000000/external-analysis-digital-marketing-flatarticons-blue-flatarticons-1.png"
).icon)
if __name__ == "__main__":
app = QApplication(sys.argv)
wid = MainWindow()
wid.show()
sys.exit(app.exec())
Use requests module to fetch image and store them.
I need it to be not continuously printing but instead it only change the QLabel,
I dont need to add more, just whenever you write in Line edit it should replace the existing text. I need it like a stocks
This is the code:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.hbox = QHBoxLayout()
self.game_name = QLabel("Stocks:", self)
self.game_line_edit = QLineEdit(self)
self.search_button = QPushButton("Print", self)
self.search_button.clicked.connect(self.on_click)
self.hbox.addWidget(self.game_name)
self.hbox.addWidget(self.game_line_edit)
self.hbox.addWidget(self.search_button)
self.setLayout(self.hbox)
self.show()
#pyqtSlot()
def on_click(self):
game = QLabel(self.game_line_edit.text(), self)
self.hbox.addWidget(game)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
You have to create a QLabel, set it in the layout and only update the text with setText():
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.game_name = QLabel("Stocks:")
self.game_line_edit = QLineEdit()
self.search_button = QPushButton("Print")
self.search_button.clicked.connect(self.on_click)
self.game = QLabel()
hbox = QHBoxLayout(self)
hbox.addWidget(self.game_name)
hbox.addWidget(self.game_line_edit)
hbox.addWidget(self.search_button)
hbox.addWidget(self.game)
self.show()
#pyqtSlot()
def on_click(self):
self.game.setText(self.game_line_edit.text())
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
I'm trying to capture Text with a click on a QPushButton and Display it in a QLabel with pyqt5
I really new to this stuff so go easy on me !
here is the code I have so far:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
game_name = QLabel("Game Name:", self)
game_line_edit = QLineEdit(self)
search_button = QPushButton("Search", self)
search_button.clicked.connect(self.on_click)
hbox.addWidget(game_name)
hbox.addWidget(game_line_edit)
hbox.addWidget(search_button)
self.setLayout(hbox)
self.show()
#pyqtSlot()
def on_click(self):
game = QLabel(game_line_edit.text(), self)
hbox.addWidget(game)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
I keep getting this error:
game = QLabel(game_line_edit.text(), self)
NameError: name 'game_line_edit' is not defined
I am not sure why game_line_edit is not defined but have a feeling it's because it not is the same "class" as my on_click class but am not sure
any help would be appreciated
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.hbox = QHBoxLayout()
self.game_name = QLabel("Game Name:", self)
self.game_line_edit = QLineEdit(self)
self.search_button = QPushButton("Search", self)
self.search_button.clicked.connect(self.on_click)
self.hbox.addWidget(self.game_name)
self.hbox.addWidget(self.game_line_edit)
self.hbox.addWidget(self.search_button)
self.setLayout(self.hbox)
self.show()
#pyqtSlot()
def on_click(self):
game = QLabel(self.game_line_edit.text(), self)
self.hbox.addWidget(game)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
One day old in terms of experience with PyQT, I followed sample code HERE to do this, but I am clueless as to how I could separate the start download part from the start GUI part, so that I can instead start that when I press the OK (startBtn)button. Also, know the command I do doesn't do anything but give you an error, but I know that works.
Any help appreciated!
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QAction, qApp, QDesktopWidget, QPushButton, QHBoxLayout, QVBoxLayout, QTextEdit
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QThread, QProcess
import sys
class GUI(QProcess):
def __init__(self):
super().__init__()
# Create an instance variable here (of type QTextEdit)
startBtn = QPushButton('OK')
stopBtn = QPushButton('Cancel')
#startBtn.clicked.connect()
stopBtn.clicked.connect(qApp.exit)
self.hbox = QHBoxLayout()
self.hbox.addStretch(1)
self.hbox.addWidget(startBtn)
self.hbox.addWidget(stopBtn)
self.edit = QTextEdit()
self.edit.setWindowTitle("QTextEdit Standard Output Redirection")
self.vbox = QVBoxLayout()
self.vbox.addStretch(1)
self.vbox.addWidget(self.edit)
self.vbox.addLayout(self.hbox)
#setLayout(self.vbox)
self.central=QWidget()
#self.vbox.addWidget(self.edit)
self.central.setLayout(self.vbox)
self.central.show()
def readStdOutput(self):
self.edit.append(str(self.readAllStandardOutput()))
def main():
app = QApplication(sys.argv)
qProcess = GUI()
qProcess.setProcessChannelMode(QProcess.MergedChannels);
qProcess.start("youtube-dl")
qProcess.readyReadStandardOutput.connect(qProcess.readStdOutput);
return app.exec_()
if __name__ == '__main__':
main()
2 notes:
If you also know how to disable the OK button when you press it, until the process is finished, then I'd love to know.
Not all imports are used, but I can clean that later. PyCharm show which is used and not. Cleanup is for later.
To do what you ask you have to have some considerations:
youtube-dl requires parameters, like the url, for this I have placed a QLineEdit.
To know when the process starts and ends, we use the signal: stateChanged(newState)
Complete code:
import sys
from PyQt5.QtCore import QProcess
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QTextEdit, QLabel, QLineEdit
class GUI(QProcess):
def __init__(self, parent=None):
super(GUI, self).__init__(parent=parent)
# Create an instance variable here (of type QTextEdit)
self.startBtn = QPushButton('OK')
self.stopBtn = QPushButton('Cancel')
self.hbox = QHBoxLayout()
self.hbox.addStretch(1)
self.hbox.addWidget(self.startBtn)
self.hbox.addWidget(self.stopBtn)
self.label = QLabel("Url: ")
self.lineEdit = QLineEdit()
self.lineEdit.textChanged.connect(self.EnableStart)
self.hbox2 = QHBoxLayout()
self.hbox2.addWidget(self.label)
self.hbox2.addWidget(self.lineEdit)
self.edit = QTextEdit()
self.edit.setWindowTitle("QTextEdit Standard Output Redirection")
self.vbox = QVBoxLayout()
self.vbox.addStretch(1)
self.vbox.addLayout(self.hbox2)
self.vbox.addWidget(self.edit)
self.vbox.addLayout(self.hbox)
self.central = QWidget()
self.central.setLayout(self.vbox)
self.central.show()
self.startBtn.clicked.connect(self.startDownload)
self.stopBtn.clicked.connect(self.kill)
self.stateChanged.connect(self.slotChanged)
self.EnableStart()
def slotChanged(self, newState):
if newState == QProcess.NotRunning:
self.startBtn.setDisabled(False)
elif newState == QProcess.Running:
self.startBtn.setDisabled(True)
def startDownload(self):
self.start("youtube-dl", [self.lineEdit.text()])
def readStdOutput(self):
self.edit.append(str(self.readAllStandardOutput()))
def EnableStart(self):
self.startBtn.setDisabled(self.lineEdit.text() == "")
def main():
app = QApplication(sys.argv)
qProcess = GUI()
qProcess.setProcessChannelMode(QProcess.MergedChannels)
qProcess.readyReadStandardOutput.connect(qProcess.readStdOutput)
return app.exec_()
if __name__ == '__main__':
main()
Screenshot: