Using vtkResliceImageViewer or vtkImageViewer2 with Python3+PyQt5 - python

I've written working example for vtkImageViewer:
But any image isn't rendered with vtkImageViewer2 or vtkResliceImageViewer. Have found example based on PyQt4+Python2.7 but wasn't able to get rendered images also (probably because of wrong versions of libraries).
Are there some examples in Python with these classes?
import sys
import vtk
from PyQt5 import QtCore, QtGui
from PyQt5 import QtWidgets
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent = None):
QtWidgets.QMainWindow.__init__(self, parent)
self.frame = QtWidgets.QFrame()
self.vl = QtWidgets.QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.vl.addWidget(self.vtkWidget)
pathDicomDir = "/path/to/dicom/data"
reader = vtk.vtkDICOMImageReader()
reader.SetDirectoryName(pathDicomDir)
reader.Update()
self.viewer = vtk.vtkImageViewer()
# self.viewer = vtk.vtkImageViewer2()
# self.viewer = vtk.vtkResliceImageViewer()
self.viewer.SetInputData(reader.GetOutput())
self.viewer.SetupInteractor(self.vtkWidget)
self.viewer.SetRenderWindow(self.vtkWidget.GetRenderWindow())
self.viewer.Render()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())

Just use
self.viewer = vtk.vtkImageViewer2()
and add
self.vtkWidget.Initialize()
after self.show()

Related

QCalendarWidget Renders Small

I am trying to use the QCalendarWidget but it doesn't render in the user interface as expected. The examples that I have seen show a calendar picker like object, but in my case I get a quite small rendering of a field. Here's what it looks like in the UI:
This is my first time using it so I am not sure if I am missing a step. Any thoughts on what I could be doing incorrectly? Here is the complete code being used:
from PyQt5.QtWidgets import QMainWindow, QCalendarWidget, QLabel
from PyQt5 import QtCore, QtWidgets, QtGui
import sys
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
cal = QCalendarWidget(self)
cal.setGridVisible(True)
cal.move(20, 20)
cal.clicked[QtCore.QDate].connect(self.showDate)
self.lbl = QLabel(self)
date = cal.selectedDate()
self.lbl.setText(date.toString())
self.lbl.move(20, 200)
self.setGeometry(100,100,300,300)
self.setWindowTitle('Calendar')
self.show()
def showDate(self, date):
self.lbl.setText(date.toString())
def main():
app = QtWidgets.QApplication(sys.argv)
mainWin = Example()
mainWin.show()
sys.exit( app.exec_() )
if __name__ == '__main__':
main()
Use a layout, for example a QVBoxLayout, in the centralWidget of QMainWindow:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
cal = QtWidgets.QCalendarWidget(gridVisible=True)
cal.clicked.connect(self.showDate)
self.lbl = QtWidgets.QLabel()
date = cal.selectedDate()
self.lbl.setText(date.toString())
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(cal)
lay.addWidget(self.lbl)
self.setGeometry(100, 100, 300, 300)
self.setWindowTitle("Calendar")
#QtCore.pyqtSlot(QtCore.QDate)
def showDate(self, date):
self.lbl.setText(date.toString())
def main():
app = QtWidgets.QApplication(sys.argv)
mainWin = Example()
mainWin.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

Why does this code in PyQt allow me to leave all radio buttons unchecked?

I wrote a mini code using PyQt and I got surprised when I noticed that it allows me to leave all buttons on the left unchecked. I don't want this behaviour: one of them should always be selected. The right side of the window works, though. I don't really know why. Here's the code:
from PyQt5 import QtWidgets, QtGui, QtCore
class Win(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Win, self).__init__(parent)
top_layout = QtWidgets.QHBoxLayout()
top_layout_1 = QtWidgets.QHBoxLayout()
self.thresh_btns = [QtWidgets.QRadioButton('L1'),
QtWidgets.QRadioButton('L2'),
QtWidgets.QRadioButton('L3')]
self.thresh_btns[0].setChecked(True)
for btn in self.thresh_btns:
top_layout_1.addWidget(btn)
timestamp_groupbox = QtWidgets.QGroupBox('Timestamp')
top_layout_2 = QtWidgets.QVBoxLayout()
self.timestamp_current = QtWidgets.QRadioButton('Current')
self.timestamp_current.setChecked(True)
self.timestamp_target = QtWidgets.QRadioButton('Last')
top_layout_2.addWidget(self.timestamp_current)
top_layout_2.addWidget(self.timestamp_target)
timestamp_groupbox.setLayout(top_layout_2)
top_layout.addLayout(top_layout_1)
top_layout.addWidget(timestamp_groupbox)
self.setLayout(top_layout)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
ex = Win()
ex.show()
app.exec_()
If you want this behavior you have to use a QButtonGroup:
from PyQt5 import QtCore, QtGui, QtWidgets
class Win(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Win, self).__init__(parent)
top_layout = QtWidgets.QHBoxLayout()
top_layout_1 = QtWidgets.QHBoxLayout()
self.thresh_btns = [QtWidgets.QRadioButton('L1'),
QtWidgets.QRadioButton('L2'),
QtWidgets.QRadioButton('L3')]
group_button = QtWidgets.QButtonGroup(self) # <---
self.thresh_btns[0].setChecked(True)
for btn in self.thresh_btns:
top_layout_1.addWidget(btn)
group_button.addButton(btn) # <---
timestamp_groupbox = QtWidgets.QGroupBox('Timestamp')
top_layout_2 = QtWidgets.QVBoxLayout()
self.timestamp_current = QtWidgets.QRadioButton('Current')
self.timestamp_current.setChecked(True)
self.timestamp_target = QtWidgets.QRadioButton('Last')
top_layout_2.addWidget(self.timestamp_current)
top_layout_2.addWidget(self.timestamp_target)
timestamp_groupbox.setLayout(top_layout_2)
top_layout.addLayout(top_layout_1)
top_layout.addWidget(timestamp_groupbox)
self.setLayout(top_layout)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = Win()
ex.show()
sys.exit(app.exec_())

Trying to send image from QThread to main or other thread in PyQt

I am trying to display an image from another thread in the main thread or possibly even a new thread. The problem is I cannot get the image to show anywhere else. I am using the thread _thread to download the image so it won't freeze the gui but I can't seem to get it out of there properly using QImage or QPixmap.
I know how to use strings and such in signals as shown in the example below but I am not sure how to send the image in a signal properly. I have tried using requests to grab an image url and send it to the main which works but I wasn't able to fetch the string in the main and then just download it there real fast either. That also is not a good option due to freezing the GUI momentarily.
This code is an example that shows that I can do all of the work and download the image in the main if I want to but would rather not.
import urllib2
from PyQt4 import QtGui
from PyQt4.QtCore import QThread, pyqtSignal
from PyQt4.QtGui import QApplication, QPixmap
import sys
class MainWindow(QtGui.QWidget):
def __init__(self):
super(self.__class__, self).__init__()
layout = QtGui.QVBoxLayout(self)
self._Button = QtGui.QPushButton()
self._Button.setObjectName("_Button")
self.line_edit = QtGui.QLineEdit()
self.line_edit.setObjectName("line_edit")
self.txt_box = QtGui.QTextEdit()
self.txt_box.setObjectName("txt_Box")
self.img_label = QtGui.QLabel()
self.img_label.setObjectName("img_label")
layout.addWidget(self._Button)
layout.addWidget(self.line_edit)
layout.addWidget(self.img_label)
layout.addWidget(self.txt_box)
self.pixmap = QPixmap()
self._thread = test_thread()
self._Button.clicked.connect(self.start_thread)
self.get_Text = self._thread.test_Signal.connect(self.line_edit.setText)
self.urls = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png'
data = urllib2.urlopen(self.urls).read()
self.pixmap.loadFromData(data)
self.img_label.setPixmap(self.pixmap)
def start_thread(self):
self._thread.start()
self._thread.test_Signal.connect(self.txt_box.setText)
class test_thread(QThread):
test_Signal = pyqtSignal(str)
def __init__(self):
super(test_thread, self).__init__()
def run(self):
string = 'This is a test string.'
self.test_Signal.emit(string)
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
And this code shows more of what I am looking to do.
import urllib2
from PyQt4 import QtGui
from PyQt4.QtCore import QThread, pyqtSignal
from PyQt4.QtGui import QApplication, QPixmap
import sys
class MainWindow(QtGui.QWidget):
def __init__(self):
super(self.__class__, self).__init__()
layout = QtGui.QVBoxLayout(self)
self._Button = QtGui.QPushButton()
self._Button.setObjectName("_Button")
self.line_edit = QtGui.QLineEdit()
self.line_edit.setObjectName("line_edit")
self.txt_box = QtGui.QTextEdit()
self.txt_box.setObjectName("txt_Box")
self.img_label = QtGui.QLabel()
self.img_label.setObjectName("img_label")
layout.addWidget(self._Button)
layout.addWidget(self.line_edit)
layout.addWidget(self.img_label)
layout.addWidget(self.txt_box)
self.pixmap = QPixmap()
self._thread = test_thread()
self._Button.clicked.connect(self.start_thread)
self.get_Text = self._thread.test_Signal.connect(self.line_edit.setText)
"...Send signal here and show image. EX:"
"...self._thread.image_Signal.connect(self.img_label.setPixmap)...."
"...or...."
def show_image_here(self):
"....Send image here after downloaded in thread...."
def start_thread(self):
self._thread.start()
self._thread.test_Signal.connect(self.txt_box.setText)
class test_thread(QThread):
test_Signal = pyqtSignal(str)
"....Example image signal...."
"....image_Signal = pyqtSignal()...."
def __init__(self):
super(test_thread, self).__init__()
self.pixmap = QPixmap()
def run(self):
string = 'This is a test string.'
self.test_Signal.emit(string)
self.urls = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png'
data = urllib2.urlopen(self.urls).read()
self.pixmap.loadFromData(data)
"....Not sure what to do here...."
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
Can somebody help me out? Thanks.
After looking around some more I came across this thread PySide threading and http downloading
I wish I had found it sooner because I did a lot of searching before my post. The person who answered that thread reclosedev also posted this in the comments:
https://pastebin.com/b4MD5jKh
Which helped me immensely to understand some things better. I used his code and slightly altered it to fit mine and it will work great for what I would like to do.
Here is my full working code using my original example for anyone out there that may find it useful.
import urllib2
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QThread, pyqtSignal
from PyQt4.QtGui import QApplication
import sys
class MainWindow(QtGui.QWidget):
def __init__(self):
super(self.__class__, self).__init__()
layout = QtGui.QVBoxLayout(self)
self._Button = QtGui.QPushButton()
self._Button.setObjectName("_Button")
self.line_edit = QtGui.QLineEdit()
self.line_edit.setObjectName("line_edit")
self.txt_box = QtGui.QTextEdit()
self.txt_box.setObjectName("txt_Box")
self.img_label = QtGui.QLabel()
self.img_label.setObjectName("img_label")
self.imagepreview = ImagePreview()
layout.addWidget(self._Button)
layout.addWidget(self.line_edit)
layout.addWidget(self.img_label)
layout.addWidget(self.txt_box)
layout.addWidget(self.imagepreview)
self._thread = test_thread()
self._Button.clicked.connect(self.start_thread)
self._Button.clicked.connect(self.imagepreview.startDownload)
self.get_Text = self._thread.test_Signal.connect(self.line_edit.setText)
def start_thread(self):
self._thread.start()
self._thread.test_Signal.connect(self.txt_box.setText)
class test_thread(QThread):
test_Signal = pyqtSignal(str)
def __init__(self):
super(test_thread, self).__init__()
def run(self):
string = 'This is a test string.'
self.test_Signal.emit(string)
class DownloadThread(QtCore.QThread):
data_downloaded = pyqtSignal()
def __init__(self, url):
QtCore.QThread.__init__(self)
self.url = url
self._data = None
def run(self):
self._data = urllib2.urlopen(self.url).read()
self.data_downloaded.emit()
def get_data(self):
return self._data
class ImagePreview(QtGui.QWidget):
def __init__(self, parent=None):
super(ImagePreview, self).__init__(parent)
self.setMinimumSize(50, 50)
self.pixmap = None
def paintEvent(self, paintEvent):
painter = QtGui.QPainter(self)
if (self.pixmap):
painter.drawPixmap(0, 0, self.pixmap)
def startDownload(self):
self.download_thread = DownloadThread('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png')
self.download_thread.start()
self.download_thread.data_downloaded.connect(self.ondownloadFinished)
def ondownloadFinished(self):
self.paintImage()
print("download finished")
def paintImage(self):
print("Painting")
pixmap = QtGui.QPixmap()
pixmap.loadFromData(self.download_thread.get_data())
self.setPixmap(pixmap)
def setPixmap(self, pixmap):
self.pixmap = pixmap
self.setMinimumSize(pixmap.width(), pixmap.height())
self.update()
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())

Not able to display Qlabel on PyQt4

Hi i have posted the code below through which i'm unable to display label in pyqt4. Any suggestions would be helpful .
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys
class Entry_view(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(25, 25, 800, 480)
label = QtGui.QLabel()
label.setText("Welcome To Python GUI")
label.resize(100, 50)
# label.show(self)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = Entry_view()
sys.exit(app.exec_())
You did not keep a reference to the label, so it got garbage-collected before it could be shown. Try this instead:
self.label = QtGui.QLabel(self)
self.label.setText("Welcome To Python GUI")
self.label.resize(100, 50)
Why did you set the text but don't process the app using thus:
app.processEvents() # On the QApplication.
Or just do:
label = QtGui.QLabel(text="Welcome to Python GUI!")
Or:
label = QtGui.QLabel("Welcomme To Python GUI!")
Or another way is:
label.show() # No widgets on it.
code below is the solution ,
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys
class Entry_view(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(25, 25, 800, 480)
label = QtGui.QLabel()
label.setText("Swipe The Card")
vbox = QtGui.QVBoxLayout()
label.setAlignment(Qt.AlignCenter)
vbox.addWidget(label)
vbox.addStretch()
self.setLayout(vbox)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = Entry_view()
sys.exit(app.exec_())

Unittesting PyQt app

I am trying to test my PyQt app. I need to view results of my unittest in PyQt widget but when I run unittesting the app closes.
This is my code:
validation_test_app.py:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
import sys
import unittest
def get_size(url):
manager = QNetworkAccessManager()
response = manager.get(QNetworkRequest(QtCore.QUrl(r"https://" + url)))
event = QtCore.QEventLoop()
response.finished.connect(event.quit)
event.exec()
html = response.readAll()
size = html.size()
return size
class MainWindow(QtWidgets.QWidget):
def __init__(self, parent = None):
super(MainWindow, self).__init__()
self.layout = QtWidgets.QVBoxLayout()
self.label = QtWidgets.QLabel("Checking tests...")
self.btn = QtWidgets.QPushButton("push")
self.btn.clicked.connect(self.btn_clicked)
self.layout.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
self.layout.addWidget(self.btn)
self.setLayout(self.layout)
def btn_clicked(self):
unittest.main(module="validation_test")
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
validation_test.py:
import unittest
from validation_test_app import get_size
class TestUrls(unittest.TestCase):
def test_1(self):
size = get_size("apps4all.ru")
self.assertEqual(size, 0)
def test_2(self):
size = get_size("google.com")
self.assertNotEqual(size, 0)
I want to view results of testing in QLabel, for example. Is it real to implement ?
This is a very late response, but since I had the same problem I figured I'd post. I think the solution is to add exit=False to the main call.
unittest.main(module="validation_test", exit=False)

Categories