PyQT + VTK : QVTKRenderWindowInteractor is invisible - python

I've made a little program to visualize 3D data with pyqt and VTK. The QVTKRenderWindowInteractor is embed in a QMainWindow centralWidget.
Everything works fine but if I add :
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
I get a hole (the QVTKRenderWindowInteractor is 100% transparent). All the other widgets are displayed correctly (menuBar, statusBar, etc..)
I've tried several combinations and it seems like the issue doesn't comes from my stylesheet. I have absolutly no idea about what is going on here.
Any help is welcome :)
EDIT : Here is a sample (python 2.7 and vtk. I'm using python(x,y)) :
#!/usr/bin/env python
import sys
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt4 import Qt
from PyQt4 import QtGui, QtCore
class test(Qt.QMainWindow):
"""Test class"""
def __init__(self, parent=None):
Qt.QMainWindow.__init__(self, parent)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.setWindowTitle(self.tr("PyQt4 VTK test"))
self.workspace = Qt.QWorkspace()
self.setCentralWidget(self.workspace)
self.frame = QtGui.QFrame(self.workspace)
self.hbox = QtGui.QHBoxLayout()
# create the widget
self.widget = QVTKRenderWindowInteractor(self.frame)
self.widget.Initialize()
self.widget.Start()
# if you dont want the 'q' key to exit comment this.
self.widget.AddObserver("ExitEvent", lambda o, e, a=app: a.quit())
self.cone = vtk.vtkConeSource()
self.cone.SetResolution(8)
self.coneMapper = vtk.vtkPolyDataMapper()
self.coneMapper.SetInput(self.cone.GetOutput())
self.coneActor = vtk.vtkActor()
self.coneActor.SetMapper(self.coneMapper)
self.ren = vtk.vtkRenderer()
self.ren.AddActor(self.coneActor)
self.renWin=self.widget.GetRenderWindow()
self.renWin.AddRenderer(self.ren)
self.hbox.addWidget(self.widget)
self.frame.setLayout(self.hbox)
self.workspace.addWindow(self.frame)
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
mainwindow = test()
mainwindow.show()
sys.exit(app.exec_())

Related

pyqt5 / qtdesigner textbox default label

I am trying to create a GUI for my python program. One of the tools that I need is a text input box.
Now, I want a text label for this box saying "Please insert texts." Is there a function to add a label that shows inside the input textbox as default and disappear when user click the box to type?
I don't mind to use qt designer or pyqt5 coding.
Thank you guys.
placeholderText : QString
This property holds the line edit's placeholder text
import sys
from PyQt5.QtWidgets import QLineEdit, QVBoxLayout, QApplication, QWidget
class Test(QWidget):
def __init__(self):
super().__init__()
self.lineEdit = QLineEdit(placeholderText="Please insert texts.") # <---
vbox = QVBoxLayout(self)
vbox.addWidget(self.lineEdit)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec_())
I am begginer like you and my English is not so good. But I recommend you use Qt Designer. It's easier, fastter for you draw your app. I am using pyside2 project and recommend you read docummentatio each widgets you wanna use in PySide2 project and Qt Project. Try code below
enter image description here
import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog
from PySide2.QtWidgets import QTextEdit
from PySide2.QtWidgets import QVBoxLayout
from PySide2.QtCore import Qt
class MainDialog(QDialog):
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
# Create Widget TextEdit
self.text = QTextEdit()
# I think that you wanna this function in your program
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setPlaceholderText
# http://doc.qt.io/qt-5/qlineedit.html#placeholderText-prop
self.text.setPlaceholderText('''Yes! this is exactly what I want!
Thank you, what if you have a big text box (more than 10 lines) and
you want to scale up the place holder and align it in center?? ''')
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setAlignment
# http://doc.qt.io/qt-5/qlineedit.html#alignment-prop
self.text.setAlignment(Qt.AlignCenter)
# Layout
layout = QVBoxLayout()
layout.addWidget(self.text)
self.setLayout(layout)
def main():
app = QApplication()
mainDialog = MainDialog()
mainDialog.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Image not displaying after move from PySide to PyQt5

I went from PySide to PyQt5 because I want to use some older code I have written and Python 3.5 does not support PySide anymore and PySide2 or Python 3.4 does not work for me either.
The last line in the code below used to get me the Example.JPG displayed. Now it does not seem to do anything for me with PyQt5
self.scene = QtWidgets.QGraphicsScene()
self.view = QtWidgets.QGraphicsView(self.scene)
layout.addWidget(self.view, 1, 0, 1, 0)
self.view.scale(0.15,0.15)
self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.view.setTransformationAnchor(self.view.AnchorUnderMouse)
self.view.wheelEvent = self.scrollSelect
self.view.keyPressEvent = self.keypressed
self.fpimage = 'Example.JPG'
self.pixmap_item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap(self.fpimage), None, self.scene)
Giving a complete working set of code is a bit difficult since I can't use PySide anymore to confirm.
Is there a way to get the image show up again?
I found the solution, in stead of this (worked with PySide):
self.pixmap_item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap(self.fpimage), None, self.scene)
i now have:
self.pixmap_item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap(self.fpimage))
self.scene.addItem(self.pixmap_item)
And it is displaying the picture in my QGraphicsScene with PyQt5.
In your case you're missing below codelines for showing a picture in a label:
pixmap = QtGui.QPixmap(self.mainwindow_image).scaled(main_width, main_height, aspectRatioMode = 1)
self.label = QtWidgets.QLabel(self.widget_1)
self.label.setMinimumSize(QtCore.QSize(225, 200))
self.label.setMaximumSize(QtCore.QSize(225, 200))
self.label.setText("")
self.label.setObjectName("label")
self.label.setPixmap(pixmap)
As your code is incomplete I've added you an example from the Qt designer Mark Summers calculate (updated pyqt5 style) to learn from (read: skeleton structure of apyqt5 gui) and apply the above label code. Enjoy.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
from math import *
from PyQt5 import *
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QAction, QApplication, QDialog, QLineEdit, QTextBrowser, QVBoxLayout, QWidget
#from PyQt5.QtGui import
class Form(QDialog):
def __init__(self, parent = None):
super(Form, self).__init__(parent)
self.browser = QTextBrowser()
self.lineedit = QLineEdit("Lots of text here... type something and press Enter")
self.lineedit.selectAll()
layout = QVBoxLayout()
layout.addWidget(self.browser)
layout.addWidget(self.lineedit)
# starts at the lineEdit for the user to type straight away.
self.setLayout(layout)
self.lineedit.setFocus()
self.lineedit.returnPressed.connect(self.updateUi)
self.setWindowTitle("Calculate the shit out of your CPU")
def updateUi(self):
try:
text = unicode(self.lineedit.text())
self.browser.append("%s = <b>%s<b/>" % (text, eval(text)))
except:
self.browser.append("<font color=red> %s is invalid!</font>" % text)
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Form()
window.show()
sys.exit(app.exec_())

How to add custom button to a QMessageBox in PyQt4

I am coding a application which needs a custom buttons in QMessageBox. i managed to create an example in QT designer which is given below.
i wanted to do this in a QMessageBox.
I am using python 2.6.4 and PyQt4. please, can any one help.
Here is an example of building a custom message box from the ground up.
import sys
from PyQt4 import QtCore, QtGui
class Example(QtGui.QDialog):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
msgBox = QtGui.QMessageBox()
msgBox.setText('What to do?')
msgBox.addButton(QtGui.QPushButton('Accept'), QtGui.QMessageBox.YesRole)
msgBox.addButton(QtGui.QPushButton('Reject'), QtGui.QMessageBox.NoRole)
msgBox.addButton(QtGui.QPushButton('Cancel'), QtGui.QMessageBox.RejectRole)
ret = msgBox.exec_()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
manuel-gutierrez, why do you inherit from QDilaog? You can inherit from QMessageBox. It's much simpler and less code
import sys
from PyQt4.QtGui import QMessageBox, QPushButton, QApplication
from PyQt4.QtCore import Qt
class ErrorWindow(QMessageBox):
def __init__(self, parent=None):
QMessageBox.__init__(self, parent)
self.setWindowTitle("Example")
self.addButton(QPushButton("Yes"), QMessageBox.YesRole )
self.addButton(QPushButton("No"), QMessageBox.NoRole)
self.addButton(QPushButton("Cancel"), QMessageBox.RejectRole)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = ErrorWindow()
ex.setText("some error")
ex.show()
sys.exit(app.exec_())
The standard QMessageBox "impose an interpretation of the response", being accepted, rejected or canceled.
Here is a version that allows arbitrary buttons, as much as wanted, and leave the interpreatation up to the user.
And it simplifies the sourcecode a bit.
The argument "buttons" gives a text list, this makes the buttons.
The return value is the text of the clicked botton.
So the user can do what he want's with that.
Note: This might be against UI-Standards and therefore less robust, but hey.
Note2: Since it's 2021, i use PyQt5 and python 3.7
I just posted this in case someone prefer this more generic approach.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
""" A more generic, a bit simplified message box also known as 'popup' """
from PyQt5 import QtWidgets as QW
class Popup(QW.QMessageBox):
def __init__(
self,
title,
text,
buttons = ["Ok"]
):
super(Popup, self).__init__()
self.setWindowTitle(title)
self.setText(text)
self.buttons = buttons
for txt in self.buttons:
b = QW.QPushButton(txt)
self.addButton(b, QW.QMessageBox.NoRole)
def do(self):
answer = self.exec_()
text = self.buttons[answer]
return text
if __name__ == "__main__": # test
class Tester(QW.QWidget):
def __init__(self):
super(Tester, self).__init__()
btn = QW.QPushButton("do it")
btn.clicked.connect(self.klick)
layout = QW.QHBoxLayout(self)
layout.addWidget(btn)
def klick(self, text):
r = Popup(
"choose a letter",
"What is your favorite\nLetter\namong a to e ?",
buttons = "a,b,c,d,e".split(","))
print("result = ",r.do())
import sys
app = QW.QApplication(sys.argv)
widget = Tester()
widget.setGeometry(400,400,100,100)
widget.show()
sys.exit(app.exec_())

How to make a window that occupies the full screen without maximising?

I'm writing in python using Qt
I want to create the application window (with decorations) to occupy the full screen size. Currently this is the code I have:
avGeom = QtGui.QDesktopWidget().availableGeometry()
self.setGeometry(avGeom)
the problem is that it ignores window decorations so the frame is larger... I googled and what not, found this:
http://harmattan-dev.nokia.com/docs/library/html/qt4/application-windows.html#window-geometry
which seems to indicate I need to set the frameGeometry to the avGeom however I haven't found a way to do that. Also, in the comments in the above link it says what I'm after may not be even possible as the programme can't set the frameGeometry before running... If that is the case I just want confirmation that my problem is not solvable.
EDIT:
So I played around with the code a bit and this gives what I want... however the number 24 is basically through trial and error until the window title is visible.... I want some better way to do this... which is window manager independent..
avGeom = QtGui.QDesktopWidget().availableGeometry()
avGeom.setTop(24)
self.setGeometry(avGeom)
Now I can do what I want but purely out of trial and error
Running Ubuntu, using Spyder as an IDE
thanks
Use QtGui.QApplication().desktop().availableGeometry() for the size of the window:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtGui, QtCore
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonClose = QtGui.QPushButton(self)
self.pushButtonClose.setText("Close")
self.pushButtonClose.clicked.connect(self.on_pushButtonClose_clicked)
self.layoutVertical = QtGui.QVBoxLayout(self)
self.layoutVertical.addWidget(self.pushButtonClose)
titleBarHeight = self.style().pixelMetric(
QtGui.QStyle.PM_TitleBarHeight,
QtGui.QStyleOptionTitleBar(),
self
)
geometry = app.desktop().availableGeometry()
geometry.setHeight(geometry.height() - (titleBarHeight*2))
self.setGeometry(geometry)
#QtCore.pyqtSlot()
def on_pushButtonClose_clicked(self):
QtGui.QApplication.instance().quit()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
I've always found inheritting from the QMainWindow class to be particularly useful. Like this:
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class Some_APP(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
### this line here is what you'd be looking for
self.setWindowState(Qt.WindowMaximized)
###
self.show()
def main():
app = QApplication(sys.argv)
some_app = Some_APP()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

Qt QGraphicsDropShadowEffect is not showing

I am creating a custom widget my_widget inheriting from QWidget.
Here, I have a label to which I would like to apply QGraphicsDropShadowEffect however it does not seem to be working since I don't see any shadows.
My code is in Python and it's:
eff = QGraphicsDropShadowEffect()
self.my_widget_label.setGraphicsEffect(eff)
I tried various alterations to this code to no avail.
After doing a through search on Google, I came across many similar questions without answers.
What might be the cause? How can I get the shadow?
Works for me in C++. I did the following in a QDialog containing a QLabel object named titleLabel. I'm using Qt 4.8.4 on a Windows XP computer.
QGraphicsDropShadowEffect* eff = new QGraphicsDropShadowEffect(this);
eff->setBlurRadius(5);
titleLabel->setGraphicsEffect(eff);
See if this works for you:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class testShadow(QWidget):
def __init__(self, parent=None):
super(testShadow, self).__init__(parent)
self.resize(94, 35)
self.verticalLayout = QVBoxLayout(self)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QLabel(self)
self.label.setText("Text Label")
self.shadow = QGraphicsDropShadowEffect(self)
self.shadow.setBlurRadius(5)
self.label.setGraphicsEffect(self.shadow)
self.verticalLayout.addWidget(self.label)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = testShadow()
main.show()
sys.exit(app.exec_())
I have only every tried to use this (and used it successfully) in QGraphicsScene situations. This works for me, while trying to set it on a normal QWidget actually crashes the entire application:
from PyQt4 import QtGui
class Graphics(QtGui.QWidget):
def __init__(self):
super(Graphics, self).__init__()
layout = QtGui.QVBoxLayout(self)
layout.setMargin(0)
shad = QtGui.QGraphicsDropShadowEffect(self)
shad.setBlurRadius(5)
self.scene = QtGui.QGraphicsScene(self)
self.view = QtGui.QGraphicsView(self)
self.view.setScene(self.scene)
text = self.scene.addText("Drop Shadow!")
text.setGraphicsEffect(shad)
layout.addWidget(self.view)
if __name__ == "__main__":
app = QtGui.QApplication([])
main = Graphics()
main.show()
main.raise_()
app.exec_()

Categories