I'm using pyqtgraph and trying to recover the properties for my TextItem class objects added to a given graph.
Although it looks like it's a simple task, I can't figure out how to extract this and the documentation didn't help much.
Here's a snippet:
import sys
from PyQt5.QtWidgets import QApplication, QWidget
import pyqtgraph as pg
import numpy as np
def refreshScreen(AnnotationsList):
for i in range(len(AnnotationsList)):
c = AnnotationsList[i]
# Now I need to extract information from the annotations:
x = c.x()
print(x)
y = c.y()
print(y)
text = c.text()
print(text)
OtherProperties = c.getProperty()
print(OtherProperties)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
w.resize(250, 150)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
AnnotationsList = []
c = pg.TextItem(anchor=(0,0), border=pg.mkPen(200, 200, 200))
c.setText(text='my_annotation', color=(0,0,0))
# coordinates for annotation
x = 5
y = 10
c.setPos(x,y)
AnnotationsList = np.append(AnnotationsList, c)
refreshScreen(AnnotationsList)
sys.exit(app.exec_())
I guessed the .x() and .y() and got them right, but knowing how to extract other features would also be important! In the current form, it raises:
AttributeError: 'TextItem' object has no attribute 'text'
If you check the source code you see that TextItem has a QGraphicsTextItem that stores the information, so if you want to get the text information you should use that object:
text = c.textItem.toPlainText()
print(text)
Related
I want to make GUI application which asks the user for the champion they want to check and then their role (e.g Middle, Jungle, Top, ADC, Support) and then it will display the "Most Frequent Runes" and some other data on the website. I believe PyQt5 would be the best python GUI for this as it has embedded webpages but please suggest alternatives.
With this code:
from PyQt5.QtCore import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWidgets import QApplication
import sys
#champion = input("What champion would you like to check? ")
champions = "Katarina"
#role = input("What role are you playing (Middle, Jungle, Top, ADC, Support)? ")
roles = "Middle"
URL = f"https://champion.gg/champion/{champions.capitalize()}/{roles.capitalize()}?"
app = QApplication(sys.argv)
web = QWebEngineView()
web.load(QUrl(URL))
web.show()
sys.exit(app.exec_())
It displays the whole webpage but I only want the "Most frequent Runes" section shown like it is like this:
and then hold it as a variable (QLabel?) that can then be placed wherever I want it. I have tried to look over how to do this but i couldn't find a solution. I would rather have done it using tkinter but it seems that isn't possible (or as far as I have been able to gather - if their is a way please explain as much as you can how).
I tried scraping the website using bs4 and requests with this code:
from PyQt5.QtCore import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import *
from bs4 import BeautifulSoup
import requests
import time
import sys
#champion = input("What champion would you like to check? ")
champions = "Katarina"
#role = input("What role are you playing (Middle, Jungle, Top, ADC, Support)? ")
roles = "Middle"
URL = f"https://champion.gg/champion/{champions.capitalize()}/{roles.capitalize()}?"
app = QApplication(sys.argv)
page = requests.get('https://champion.gg/champion/Katarina/Middle?')
soup = BeautifulSoup(page.text, 'lxml')
championData = soup.find('div', 'summoner-text')
window = QWidget()
window.setWindowTitle("League of Legends helper")
window.setGeometry(100, 100, 550, 250)
runes = QLabel(championData, parent=window)
but it just produces errors which I haven't fully been able to understand.
Error:
Traceback (most recent call last):
File "(FILEPATH)", line 32, in <module>
runes = QLabel(championData, parent=window)
TypeError: arguments did not match any overloaded call:
QLabel(parent: QWidget = None, flags: Union[Qt.WindowFlags, Qt.WindowType] = Qt.WindowFlags()): argument 1 has unexpected type 'Tag'
QLabel(str, parent: QWidget = None, flags: Union[Qt.WindowFlags, Qt.WindowType] = Qt.WindowFlags()): argument 1 has unexpected type 'Tag'
BeautifulSoup's is an HTML parser so each node of the DOM has a wrapper that allows access to its properties, so championData is not a string causing the error.
Even so, you would extract the HTML from the node, it would be useless because the "requests" library does not obtain the HTML generated dynamically by javascript, in addition, the styles would not be kept as they depend on other files.
A possible solution for this case is to extract the HTML from that node and place it in the same document using javascript:
import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
def main(*, champions, roles):
url = f"https://champion.gg/champion/{champions.capitalize()}/{roles.capitalize()}?"
app = QtWidgets.QApplication(sys.argv)
web = QtWebEngineWidgets.QWebEngineView()
web.resize(640, 480)
progress_dialog = QtWidgets.QProgressDialog()
progress_dialog.setLabelText(
"""""<p><span style=" font-size:20pt; font-weight:600;">Loadding ...</span></p>"""
)
progress_dialog.resize(640, 480)
progress_dialog.show()
web.loadProgress.connect(progress_dialog.setValue)
button = progress_dialog.findChild(QtWidgets.QPushButton)
if button is not None:
button.clicked.connect(QtCore.QCoreApplication.quit)
def on_load_finished():
codes = [
"""var iterator = document.evaluate("/html[1]/body[1]/div[1]/div[2]/div[3]/div[2]/div[2]/div[1]/div[1]/div[2]/div[1]/div[3]", document, null, XPathResult.ANY_TYPE, null)""",
"""var e = iterator.iterateNext() """,
"""document.body.innerHTML = e.innerHTML""",
"""document.body.children[0].style.marginTop = "10px" """,
]
for code in codes:
web.page().runJavaScript(code)
web.move(progress_dialog.pos())
web.show()
progress_dialog.close()
web.loadFinished.connect(on_load_finished)
web.load(QtCore.QUrl(url))
sys.exit(app.exec_())
if __name__ == "__main__":
main(champions="Katarina", roles="Middle")
Update:
import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self._champion_le = QtWidgets.QLineEdit(placeholderText=self.tr("champion"))
self._role_cb = QtWidgets.QComboBox()
self._web = QtWebEngineWidgets.QWebEngineView()
self._search_btn = QtWidgets.QPushButton(self.tr("Search"))
self._stacked = QtWidgets.QStackedWidget()
self._progress_bar = QtWidgets.QProgressBar()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QGridLayout(central_widget)
lay.addWidget(self._champion_le, 0, 0)
lay.addWidget(self._role_cb, 0, 1)
lay.addWidget(self._search_btn, 0, 2)
lay.addWidget(self._stacked, 1, 0, 1, 3)
container = QtWidgets.QWidget()
lay = QtWidgets.QVBoxLayout(container)
lay.addWidget(
QtWidgets.QLabel(
self.tr(
"""<p><span style="font-size:20pt; font-weight:600;">Loadding ...</span></p>"""
)
)
)
lay.addWidget(self._progress_bar)
self._stacked.addWidget(QtWidgets.QWidget())
self._stacked.addWidget(container)
self._stacked.addWidget(self._web)
self._role_cb.addItems(["Top", "Jungle", "Middle", "ADC", "Support"])
self._search_btn.clicked.connect(self.on_clicked)
self._web.loadFinished.connect(self.on_load_finished)
self._web.loadProgress.connect(self._progress_bar.setValue)
self.resize(640, 480)
self._champion_le.setText("Aatrox")
self._role_cb.setCurrentText("Top")
#QtCore.pyqtSlot()
def on_clicked(self):
champion = self._champion_le.text()
role = self._role_cb.currentText()
if champion:
self._stacked.setCurrentIndex(1)
self.change(champion, role)
def change(self, champion, role):
url = f"https://champion.gg/champion/{champion.capitalize()}/{role}?"
self._web.load(QtCore.QUrl(url))
#QtCore.pyqtSlot(bool)
def on_load_finished(self, ok):
if ok:
codes = [
"""var iterator = document.evaluate("/html[1]/body[1]/div[1]/div[2]/div[3]/div[2]/div[2]/div[1]/div[1]/div[2]/div[1]/div[3]", document, null, XPathResult.ANY_TYPE, null)""",
"""var e = iterator.iterateNext() """,
"""document.body.innerHTML = e.innerHTML""",
"""document.body.children[0].style.marginTop = "10px" """,
]
for code in codes:
self._web.page().runJavaScript(code)
self._stacked.setCurrentIndex(2)
def main():
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I am trying to test my highlight_word function (below). However, I can't figure out how to access the formatting. I essentially just want to show that it is non-default. I have tried QPlainTextEdit.extraSelections(), but it apparently refers to destroyed objects. I have also tried QTextCursor.charFormat().background.color() with an appropriately positioned cursor, but only ever get rgbf(0,0,0,1).
def highlight_word(self, cursor: QTextCursor):
selection = QTextEdit.ExtraSelection()
color = QColor(Qt.yellow).lighter()
selection.format.setBackground(color)
selection.cursor = cursor
self.setExtraSelections([selection])
UPDATE
First, I am using PySide2, if that affects what follows.
The accepted solution works. My problem was I was writing self.editor.extraSelections()[0].format.background().color().getRgb(), which leads to RuntimeError: Internal C++ object (PySide2.QtGui.QTextCharFormat) already deleted.. This strikes me as bizarre.
QTextCursor.charFormat().background().color() is not returning the color is because the QTextCharFormat is applied to the QTextEdit.ExtraSelection. You could add the line selection.cursor.setCharFormat(selection.format), but it's not necessary. It should work if you just access the selection from extraSelections() and get the selection format.
Here is an example, highlight a word and then click the "Highlight" button, it will print the background RGBA. After click the "Get Selection" button, it will print the highlighted word and the background color.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Template(QWidget):
def __init__(self):
super().__init__()
self.textbox = QPlainTextEdit()
btn = QPushButton('Highlight')
btn.clicked.connect(self.highlight_word)
btn2 = QPushButton('Get Selection')
btn2.clicked.connect(self.get_selections)
grid = QGridLayout(self)
grid.addWidget(btn, 0, 0)
grid.addWidget(btn2, 0, 1)
grid.addWidget(self.textbox, 1, 0, 1, 2)
def highlight_word(self):
selection = QTextEdit.ExtraSelection()
color = QColor(Qt.yellow).lighter()
selection.format.setBackground(color)
selection.cursor = self.textbox.textCursor()
self.textbox.setExtraSelections([selection])
print(selection.format.background().color().getRgb())
def get_selections(self):
selection = self.textbox.extraSelections()[0]
print(selection.cursor.selectedText(), selection.format.background().color().getRgb())
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = Template()
gui.show()
sys.exit(app.exec_())
I'm using pyqtgraph to plot tracks of a robot (the path that the bot drove). Now I want to add a marker to the plot to indicate the bots current position and heading. I thought ArrowItem would be the right choice, because it is scale invariant and can be rotated easily. However the local origin of the arrow is at its tip like this
but I want it to be in the center like this
How can I do that? I would also appreciate different solutions to this problem.
Update
After applying eyllansec's code I get some rendering problems. A minimal example (one has to zoom or move the view to disable the auto scaling):
import pyqtgraph as pg
import numpy as np
import time
class CenteredArrowItem(pg.ArrowItem):
def paint(self, p, *args):
p.translate(-self.boundingRect().center())
pg.ArrowItem.paint(self, p, *args)
if __name__ == '__main__':
app = pg.QtGui.QApplication([])
window = pg.GraphicsWindow(size=(1280, 720))
window.setAntialiasing(True)
tracker = window.addPlot(title='Tracker')
while True:
for i in range(300):
arrow = CenteredArrowItem(angle=i, headLen=40, tipAngle=45, baseAngle=30)
arrow.setPos(i / 300, i / 300)
tracker.addItem(arrow)
app.processEvents()
time.sleep(0.02)
tracker.removeItem(arrow)
As you may noticed I'm adding and removing the arrow each iteration. This is because arrow.setStyle(angle=i) is not working as it does not update the rotation of the arrow (probably a bug).
A possible solution is to overwrite the paint method of ArrowItem and move the QPainter:
import numpy as np
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
class MyArrowItem(pg.ArrowItem):
def paint(self, p, *args):
p.translate(-self.boundingRect().center())
pg.ArrowItem.paint(self, p, *args)
app = QtGui.QApplication([])
w = QtGui.QMainWindow()
p = pg.PlotWidget()
p.showGrid(x = True, y = True, alpha = 0.3)
w.show()
w.resize(640, 480)
w.setCentralWidget(p)
w.setWindowTitle('pyqtgraph example: Arrow')
a = pg.ArrowItem(angle=-160, tipAngle=60, headLen=40, tailLen=40, tailWidth=20, pen={'color': 'w', 'width': 3}, brush='r')
b = MyArrowItem(angle=-160, tipAngle=60, headLen=40, tailLen=40, tailWidth=20, pen={'color': 'w', 'width': 3})
a.setPos(10,0)
b.setPos(10,0)
p.addItem(a)
p.addItem(b)
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
As shown in the following figure, the red arrow is the default ArrowItem, and the blue is the offset, both are located in the same position with respect to the plot.
Update:
The problem is caused by the method that rotates the item used as the center of coordinates using the center of transformations by default, that is to say the (0, 0), we must move it:
import pyqtgraph as pg
import numpy as np
import time
from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph import functions as fn
class CenteredArrowItem(pg.ArrowItem):
def setStyle(self, **opts):
# http://www.pyqtgraph.org/documentation/_modules/pyqtgraph/graphicsItems/ArrowItem.html#ArrowItem.setStyle
self.opts.update(opts)
opt = dict([(k,self.opts[k]) for k in ['headLen', 'tipAngle', 'baseAngle', 'tailLen', 'tailWidth']])
tr = QtGui.QTransform()
path = fn.makeArrowPath(**opt)
tr.rotate(self.opts['angle'])
p = -path.boundingRect().center()
tr.translate(p.x(), p.y())
self.path = tr.map(path)
self.setPath(self.path)
self.setPen(fn.mkPen(self.opts['pen']))
self.setBrush(fn.mkBrush(self.opts['brush']))
if self.opts['pxMode']:
self.setFlags(self.flags() | self.ItemIgnoresTransformations)
else:
self.setFlags(self.flags() & ~self.ItemIgnoresTransformations)
if __name__ == '__main__':
app = pg.QtGui.QApplication([])
window = pg.GraphicsWindow(size=(1280, 720))
window.setAntialiasing(True)
tracker = window.addPlot(title='Tracker')
while True:
for i in range(300):
arrow = CenteredArrowItem(angle=i, headLen=40, tipAngle=45, baseAngle=30)
arrow.setPos(i / 300, i / 300)
tracker.addItem(arrow)
app.processEvents()
time.sleep(0.02)
tracker.removeItem(arrow)
After digging through the source code of pyqtgraph I ended up with a special function that suits my needs. I apply the translation when creating the arrow path, instead when rendering it. Fortunately this also solves the roation bug (for whatever reason).
Example:
import pyqtgraph as pg
import numpy as np
import time
import pyqtgraph.functions
class CenteredArrowItem(pg.ArrowItem):
def setData(self, x, y, angle):
self.opts['angle'] = angle
opt = dict([(k, self.opts[k]) for k in ['headLen', 'tipAngle', 'baseAngle', 'tailLen', 'tailWidth']])
path = pg.functions.makeArrowPath(**opt)
b = path.boundingRect()
tr = pg.QtGui.QTransform()
tr.rotate(angle)
tr.translate(-b.x() - b.width() / 2, -b.y() - b.height() / 2)
self.path = tr.map(path)
self.setPath(self.path)
self.setPos(x, y)
if __name__ == '__main__':
app = pg.QtGui.QApplication([])
window = pg.GraphicsWindow(size=(1280, 720))
window.setAntialiasing(True)
tracker = window.addPlot(title='Tracker')
arrow = CenteredArrowItem(headLen=40, tipAngle=45, baseAngle=30)
tracker.addItem(arrow)
tracker.addItem(pg.InfiniteLine(pos=(0,0), angle=45))
center = pg.ScatterPlotItem([], [], brush='r')
tracker.addItem(center)
while True:
for i in range(300):
arrow.setData(i, i, i)
center.setData([i], [i])
app.processEvents()
time.sleep(0.02)
I'm running into a bit of a problem and could use some help.
I have here a small pyqt app that displays a pixmap.
import sys
import qtcompress
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def window():
str_image = 'AAASDHicnVdlUBSO076DOySlUzqkuxuU7pRG8hAE6QY5uhvkaCXlSEGk4TyPUvBoCQlJT+CkO/7+Pr/f3mfm2Zjd2f2wszuzyUYGmiSEDIQAAIBEW0vN5J9W+Y/4eP8k3N135Z8C+T/RNsP/hwh8l6R/PoGPlpU/AEBE+R+BgKISun85D9zNLAMs9fXknL29hBxdvJ1chUK8fABAgLmZhqAM4P9GXkTvF4+/qtegGj4PJUQtfzRxvGj5zKoX8LL2HPJLSsdk2UW2jN6TyoFnbX60PnBS8w9/AN5NNEmGwGmQKZOLzaHszv296JfCQ08KW28/PXvL6rEF9u9Df1aj7qr5RJnqVxPEnd8YzovdXdm3JJ4/Zxm9Jjp8H8ZkD34UlbvNW9/Sqp3bcCLtTG2q5NZ/YZOQDZ/hmv1meStA+XV6z6DwIIb36fJkkrtNyi5me6JNI7ac6psIkwtxFsa9Zj/1B8LoUwGDfTL67dvsKOVb11TK1aE/rXA/lnenYY3NXqW0RGznCi6WI60Sxu/yva3ipa2fvfbQC1IyfZbD/r0e5pZyk7ETYZ5ufqrjbrfkW33JnJcfpqhRekDl5ZOht6zipta2MNwqsW/+Znb85emH1oiIb/TdblzPqeOWe1sbrmbc1EdXuJ9Taysq57G+aTHT0vnlerbypH+TWrjgZqzzHNNW2bzO8+fH1zEr+iWUm4vY9AgyVogsd8+QMIHfXsGvLE6/YHn/lWGhnosFyem7oy8dMpURdnd0b02Ny1mKU4J5PjZBiCWmQyWIF7KfGorbropYP9bfSh7WC1AepO5Hbb0/m0mclgnrGdkyCt0TLb7ssLL6lday5M6DE8Zouhpgt945Nue5rrHIw0A2zhHwduENZSGHswoHBzw9c4tpl5ebf0GH/YdA5NfkllXpJO+2kbJMAZs2AYufvaO2JKT68PSGrmTFR8Uum3sqgm0Pf3ew08hTGlhL+gmYITT8Y4vefJYYpuu2Rm1abp9pPQqROBKpPp5E/GQL85R73+zLa70hqPAHHYYOcYhi1AxO5mw6z2Kk5crV9W/AztUskmvp96Ei9TaxlDnd6S+gGRU7rr7nvvZSYKbL0KGw0dZM6ybzwJWqTeP2IfB1L5l45MLiHmUQhFHS9I5FIYVi4K7nge9C91W5QhIuVMD3k4OEmvwvIZ+FtpcVw/UvO5x66kXfojJDstf50kx7HXjQNEA5kE1+YuQLJKV9kn5OfBD0CtkHXxrdbFozLmlp6b0/avMLF/fVQ/tK6EovSTV2v8m8qcuVz4DJ23bkTAQ41Z4attrlmpf6Cz61Hckrt3GXj+SLvLO8uok+ybpSTK2fWNQxQArm3yi+gvxVZWQqZFx0//3xSmilZdOdITWyI+98jfhT0bRa88FlyUEXh+diXSDipUHmi/AIKm6Lj8rdZ5Kn5wMAHDIoAMQKAOKr/H/My+9Z9Q736LcClc6BjfaJ94B2C/KKAsJo2X/3pFhbTdUspGS/WD/N3i1wOGqnhJ++2onayTFtg95QgMvY0fibaIwdzUIVRToFbZ06HwGeOi84WZ3qHX5+K1R9nisbIeNebQaO0bV8q2NVtWw0WzeGQxNIvUf/0ukx0uUpZ1x1OBazftnbPDDUzJQO3xSCrJyv7Cidy977f7+P+LmTn7TWF/HbQNihNvMcOI8B750cKgHk+6ClSivHAOK/25vKl6MDKXWF8H3RaWXTtsz6xWWp3/C6fcnZpXHPApid2GzH+F4MvKkYQ29+XV10i1TrUBskZVa4aEK97JoNRegK93HCPSCfhseYRWavZ/dyIZ8q4DASGK9HQt27xzB6viGHFJgjHMbg1O1Yc+9e0Vy3UA/vdvXoj3K9F7Q5EcRduzjcqKjpwXv0zHzfUfyWSFw+L46JLkcFxgBJMQdIACvoYdiSundFCJPJachVCrzMrD3QvCtgpzR45WTdmwCAVry/cYCHj+0Jj++9L2SatDfSjZlBQ4jb/K0OIjIh/Fo/2stoRcdO8uD9DXBlsbbGyOuzdOm2s+J1qFv/MRP9jNJ7yLljBPmm6poUFF9lSoZXOomVHbqmkoWn3kGWXUWWHGQoAnyLp8cIVMJjBPZ3dHVddr/vP57sCy+Y2pwCRFzbrNJI9n355cjJTC1TAvLazRJVVgU9JQOhpwjVjTQ5fWI80owhfM4UoCc4c7+koiuB/JRHFYhRaWHbzk5ifF3gQbr3TeyiAwtzEho3E8i/5h6vHqu+X2YwStYJiiYHwwTMpBJv9KeUy9GU42lGhUeCfnQ3D9mUOH3WkfFE3vvLPcHd5Fav6KC15a+t9fa/sB92cHz5AAwSziAA2bZkQe6d37ArTyqmE4N2sZSI4bdlDUKsWi4LnC/e1PCnRGijlFVQ/rQrvS3t55VLHXGPcNZGucupxHtwLxSYh3GCiHDZYrRqA1OEcOkFiXI/jywWgCl5n2vGAGGEzzmr4Gu/QpvweaCsPWDFhEGWZEyP9PpDaRD0+kR1zTFrGLoczfqLLNpZDSFCddiW8YRCJUTUxyfJZ2yRQZFVYHnHBBtPJ8eMTxZb58Ctuq6pGrccooB3YxAbhfc6Shd40SMcFSrSzvFEgQ+p82GygsyW75hU1dq9C7tQzUV/mzVb2qDRzfNLknAGmM/Cqubwx/2ZuxKNwyeK6ROer83S0tL3kfJsfjYAhbuLjQp4OOoCycNYk2M5624Xi58GxMWRGkgAxXHZjCwKr3i6lv3eOePz+muvvbECTQpaYX8oHwGUafs36+3+yOsmDOESDmI5OJox8PDBYQMVrYCoTdnj5gm2ChuHZMJL63Uc7iqCZfIIOQ2H32LxCppqOAok0/Ao8ug6hWGjQuaStQHoTrTyChWg/LoYnVzYiLygp3u126wNtZzKowISPuRKC2VlO9YqQGn/cHXsZxOzJCnJwMtdykMj8o5TN58Xhsct4Sjh3ixdHu+g91ajThd/dQMuNhNQHCM+5SNJSVvm3yJsRbdF6OQShO+5KOgzPpIlcjt44HGmbx0jUPTqfwVRmh8IyXOqLdkn9VJA59oH+AeCOfqCBNBr5rVpddj7Xe9y+LauwAk5koY1BmGKZwn24KCgf+x3KNePMGMcP5q/7OXNhdF8B+ceYGDrLNHj9aPB+gBm2TCzsT3gmhG3unXEm3s/Gx6iLHasp8pUpxmLZpqYnd8FOebNLLToKIKo/cuW3rwyNitB0edsb4F2bm6u6TfeD5CDn3T0dTKsEjteTsQ1DhmYqvR8bdVaVAmZMHm6LXAmupNholS9pLuoYBEzZu6njFT2pZbufAxQumRWVVKH0oIgVdSdXOmWtOhHG7jksh259A758+w7+I9Hm6uBi2hZG1rZ5e8bJjJau0klrzWTCZG1MBdSC9/YXUtEwAvU+SNji5LWgVdZF67WL65y5TQIS4eTXNvKEweys9jME7mejjFPNQjW/rj14lSfOcSfxieO4bSfJ/V7wQuIKFKa05ajzKooBd8noMbeUEZZfYxMVQsBbrAeg0MyCBshHu4fJnSQWVjnIDQvpU9dcZ8CmdZtrMW/LR29xVbswxHYMDWDM6dX78mz/Ss3Pwz91GTiFqhGMQ+W0CI9RKYDxT7ywwo5d4Q0phveWYF9zmddesvAjFDWqul16hmhAPDrmoDsJ6bJs7mP5ZnJfc73dl1aaJ7UchJwDl+xZ6vRcmnUbduza4xIFDvF4OoCRS4vyJFN79kwnmyBoTlduoVz/EpQyoc0qVISuZT0INpCXPCFTIwVWBlJL8dOiCagG6Tzb6Fiq0lWvRgxAXQadkxvrWIuSZIWnigqP4uLVlouThydk+6MWUDrpFoedPk5y2FWynUdT46SsoeR+//1+8iPtn9mntqdEZOdbUtJJTAFwCDte56t8Th+KE97OKb1p4G6evNJ6vZBqBBB/Sf7qQBMzgOChXaqf7Plak2Mdov2oxDTeOnNFpdmib5IQ8kg1rpq2hZ+fh5REXEiHhmrhjuox31Fvfmuu2pUpR5vQgyuizkJ8EZUbwEOMF5rhpA5BiYMWqc3wBEy/6sThJooeTFUniyiyK1awK20UKZQGEIUbx9OCi5+b8xulSfPq6oTvbFfDYA9vk/HD5bqMPT6Zv0hX32OAk1PZGyOV9nEzolI/5Znh7SRIR7ji36ldjd9qItVJJ7qodX6KHppPGBFAcWUJEXg6IizC6q4jowtd8ulA4vKU8fGldKzXHiJ0qjLrN3Zq735tPCCsn+mSObL/nQuY5w01oQ7fxcEQ3vKtf1RMXOM3RYeTNLCVPqNhvNp8gOAbC0vcXLIqeqzDUvjUjf6ffyfiUp0bk+LNBupZDbHTAAoiVuPHIMOwT9kg0xfN6oIJgdoYlVs6ZxdXhAIra+NFtAlq70lgjP3qQ86EQnG4WRjQd1S4e4tLru6fR3PBcEIGf1aku+aLcrJUwSPeavN/fqx2Ze9Pxm1flxqx4Q9rGGi3y6x08K8whbMVMbPAj9Tks11JRRYvOIQnd/rZ6RAJ/qE8QKcjhoJXj/ca+bEMpm61eqGqnhYhaidDubczZWp5nWWT++COzzCcvHMyGuQRqC8ZzxcxMWFc7xMyRey83MmgAsJWbZmgiOL6Np1MT/NmhwnzHj1il1KQqRIgAZBgufDNh5jmEf2VsUp2YNk+gdUNSzV5G6lSNPX2RSVOjnNbG39f86AMsfKbutl4dhQ6h2JF16p+R1dm3FVfUdl3fNLWzuh0Vw5Mz6z3NBlHZCJNL1Pwp+wNphYENaY48GCZLyPZtI0+dGfp6SKAYNB84FAgM+5YFq5mC/PlfmDy8PIywVJ7R5Si0yKSyXRKrW0BZDdlGntX9h8z+FkIIt10cG0Qy/80psIyot0LXrNiCrHPR9vphFJ4eXW5Xk5zgzUCmN6bEe/ymFcEUdC3dp/v8pcACDHIJo0M3QbG8+6EZmj7ktTgJurdOn1ph6stfReoqlelM5iyQSN2YolegXjekxS5+09JKqZrOCZ5tASWu8iwEftdsLqBEu10tkruRg7bgB9/+2QFpVF9/o38up51FmbheS9FxAgom7rdFTw9ALkQyVXrTnpu/QVZ4yuv/Xyd1XHViFRiga/LifEu2a5YyYsfASsPR709ZLi6UXhhrC4fR8+3/AngEzwmWcDk0yLJO9wNHXclz6H7Egj2tybnC3tJlwQLCX3o2YtPLhK1ih3OpHdkT/gT7ChdubsiTXg7pHMQ08m+aC9osVVKQDADV36iPRfHS5KYQMkEz7/+uA3/xFe7MSt16lyXUXbTeQ7OrIcojy2U496n6xJv9V3SxZT7asH8y0ttNGmhgqHqE9BmcsTeMmwmmBb2VFOFpz+uK9YHt/mwdgus82ATxThARNVRtZn+Jw8pmhvqq607ZTavJMOE0jOfQeZMJmfidrKQpOeNAhxdaXR0NBgCzIARQBk8PZo3JG653UbIwsPs2oGZuyze9vV/Icosou4QnsI7LCFhA0RNb0N9PGrDBEsMmwXg80RW/U/JG+rAYD5+fmk/Nn8DlBZ8VTP+TDiWVpdYJXY08caryLomBzzZ+oSNFg+vJgIWWHhVDMI3TkTwemk/DzE2qvi82StsbYszGMJKQwGIIauhj52d7eCj+zWghGViF9Xm4zXJm1yi8+YPTa6v1M7f8MBt2KCGQYEZD0SuZHhk4oGFF8GmyNvd6U5FX6iNEZPT9Mt7az6tBazThIQtNzrqrzy6vXw9jnSU8uswT43Mm/W/CInznZkIgPuHfRAfC0csYuQX73ZXl1tOfDJtXH9IT2He3G7uLgYBbiv99HJqlRj1M53ZrCQEqJqPV780G1bv4XvcHDEIBc/0euMNWMVJh3JFPlUFrpdWLzIH/EtKLW5sTEZjjVpN5eMnOfcp/nx+kHICqPiKqg0OJ3U3T9gUc3Ly6aPT4oulqTW/JRaXN4dsgsJwiy4lfdhBlePVokYFUKMZmb0vDLhSm89zotHuc291HeDLvFiMFAaVS/YPQSRcBIOnP0RQGcv2S74aMYw4h7136vw4K0ytu/c3nj2LJW8PbMYswzvhkPC9feDxJerb4U1xub0T9OKbv2MruNJPrnC74SVLz73tE4EU0PvSYfD7zRN/+K2TBPNYzYiAUFhQPnIG5axlCmO0mvWRsA/aKsbqDU9cYj5Hz3VwP4='
app = QApplication(sys.argv)
win = QWidget()
l1 = QLabel()
image = qtcompress.decode_thumbnail(str_image)
l1.setPixmap(QPixmap.fromImage(image))
vbox = QVBoxLayout()
vbox.addWidget(l1)
win.setLayout(vbox)
win.setWindowTitle("QPixmap Demo")
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
Here is the decode_thumbnail function
def decode_thumbnail(str_image):
bytearray = QtCore.QByteArray.fromBase64(str_image)
bytearray = QtCore.qUncompress(bytearray)
image = QtGui.QImage()
image.fromData(bytearray, 'PNG')
I've looked around a lot and can't seem to find any examples of anyone unpacking a string from base64 and then using qUncompress. Python is not my forte in any way, so I apologize if this is a simple question.
The problem is in your decode_thumbnail function. It isn't returning anything.
Change the last line from
image.fromData(bytearray, 'PNG')
to
return image.fromData(bytearray, 'PNG')
Alternatively, as QImage.fromData is a static method, you don't need an image object, so you can just write
def decode_thumbnail(str_image):
bytearray = QByteArray.fromBase64(str_image)
bytearray = qUncompress(bytearray)
return QImage.fromData(bytearray, 'PNG')
I'm starting with PyQt4 and I'm making a program for practice. In that program I have QDateTimeEdit, QTimeEdit and QCheckBox.
How would I pull values from them into a string using signals and slots.
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class main_frame(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.initUI()
def initUI(self):
# A push buttnon
btn_get = QPushButton("Get Time", self)
btn_get.move(100, 250)
#
time = QTime()
# Find what is the local/system time
curent_t = time.currentTime()
# Convert it to a str
# The output shoud be HH:MM:SS , eg 10:45:28
curent_t_str = curent_t.toString()
# Create a timeEdit widget
time_widget = QTimeEdit(time, self)
time_widget.setTime(curent_t)
def get_time():
print(curent_t_str)
btn_get.clicked.connect(get_time)
### At the end of the day you got curent_t_str variable
### which you can use it in your code down the road
### so I belive that`s helpful for your needs
### implement this may vary, depending your needs ...
# Set a costom size for the mainWindow
self.setFixedSize(300, 300)
def main():
app = QApplication(sys.argv)
myapp = main_frame()
myapp.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Does that help you out ? Note that for QDateTimeEdit the procedure is the same, after you got your value into format like 10:45:28 is up to you how you gonna format the string or for what you gonna use