how to get id of checked group radio from radio button in pyqt5 - pyqt5

Is there any way to get value of grouped radio buttons?
this code dont work for me:
self.pb1.clicked.connect(lambda : self.rbtn_1_state(self.rb1_1.ischecked(),self.rb1_2.ischecked()))
def rbtn_1_state(self, rb1_1_chk,rb1_2_chk):
print("radio button 1 function is called")
if rb1_1_chk:
rb1_state=[1,0]
if rb1_2_chk:
rb1_state = [0, 1]
else:
rb1_state = [0, 0]

Try it:
from PyQt5 import QtGui, QtCore, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.groupBox = QtWidgets.QGroupBox()
self.rb1_1 = QtWidgets.QRadioButton("rb1_1", self.groupBox)
self.rb1_1.setChecked(True)
self.rb1_2 = QtWidgets.QRadioButton("rb1_2", self.groupBox)
self.hLayout = QtWidgets.QHBoxLayout()
self.hLayout.addWidget(self.rb1_1)
self.hLayout.addWidget(self.rb1_2)
self.lb1 = QtWidgets.QLabel()
self.pb1 = QtWidgets.QPushButton("pb1")
self.pb1.clicked.connect(lambda : self.rbtn_1_state(
self.rb1_1.isChecked(),
self.rb1_2.isChecked()))
self.vLayout = QtWidgets.QVBoxLayout(self)
self.vLayout.addWidget(self.lb1)
self.vLayout.addLayout(self.hLayout)
self.vLayout.addWidget(self.pb1)
def rbtn_1_state(self, rb1_1_chk, rb1_2_chk):
self.lb1.setText("rb1_1-> {} , rb1_2-> {}".format(rb1_1_chk, rb1_2_chk))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
qt_app = Window()
qt_app.show()
sys.exit(app.exec_())

Related

PyQt, How to switch transparent-setting for subwindow

I want switch WindowTransparentForInput statement of sub-window.
At following code, I wrote, subwindow will close instead switch the statement.
Could you please to point the problem?
import sys
from PyQt5 import QtWidgets as qtw, QtGui as qtg, QtCore as qtc
class Main(qtw.QWidget):
def __init__(self):
super().__init__()
self.mainWindow = qtw.QWidget(self)
self.mainWindow.setGeometry(100,100,200,200)
label = qtw.QLabel('Main window', self)
self.switch = qtw.QCheckBox('Transparent for input on sub window', self)
self.switch.setChecked(False)
self.switch.stateChanged.connect(self.switchAction)
mainLayout = qtw.QVBoxLayout()
self.setLayout(mainLayout)
mainLayout.addWidget(label)
mainLayout.addWidget(self.switch)
self.subwindow = qtw.QWidget()
self.subwindow.setGeometry(150,100,200,200)
sublabel = qtw.QLabel('Sub window', self.subwindow)
self.show()
self.subwindow.show()
def switchAction(self):
if self.switch.isChecked:
self.subwindow.setWindowFlags(qtc.Qt.WindowTransparentForInput | qtc.Qt.FramelessWindowHint)
else:
self.subwindow.setWindowFlags(qtc.Qt.FramelessWindowHint)
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
mw = Main()
sys.exit(app.exec())
It was solved by modifying switchAction() as follow.
I'm sorry for your notation.
def switchAction(self):
if self.switch.isChecked():
self.subwindow.close()
self.subwindow.setWindowFlags(self.subwindow.windowFlags() | qtc.Qt.WindowTransparentForInput)
self.subwindow.show()
else:
self.subwindow.close()
self.subwindow.setWindowFlags(self.subwindow.windowFlags() & ~qtc.Qt.WindowTransparentForInput)
self.subwindow.show()

PyQt - not showing instance of FigureCanvasQTAgg on QtWidget of TabPane

I'm continuing project described more in that question: PyQt - can't read Excel file
Basically my code looks like this right now:
# This is a sample Python script.
# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
import csv
import sys
import numpy as np
from PyQt6 import QtWidgets
from PyQt6.QtWidgets import QDialog, QApplication, QFileDialog, QTableWidget, QTableWidgetItem, QTabWidget, QWidget
from PySide6.QtCore import Slot, SIGNAL
from PyQt6.uic import loadUi
import pandas as pd
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=12, height=5, dpi=100):
fig = Figure(figsize=(width, height), dpi=100)
self.axes = fig.add_subplot(111)
super(MplCanvas, self).__init__(fig)
class MainWindow(QDialog):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent=parent)
self.initUI()
def initUI(self):
loadUi('gui.ui', self)
self.btnShow.setEnabled(False)
self.btnLoad.setEnabled(False)
self.btnBrowse.clicked.connect(self.browseFiles)
self.btnLoad.clicked.connect(self.loadExcelData)
self.btnClean.clicked.connect(self.cleanData)
self.btnShow.clicked.connect(self.showGraphs)
#Slot()
def browseFiles(self):
fname = QFileDialog.getOpenFileName(self, 'Open a file', 'C:\\', "Excel (*.xls *.xlsx)")
self.filename.setText(fname[0])
self.btnLoad.setEnabled(True)
#Slot()
def loadExcelData(self):
column_names = ["Action", "TimeOfFailure", "ReverseRankR", "S(i)", "Cdf", "Ppf", "LogTime"]
df = pd.read_excel(self.filename.text(), "Sheet1", names=column_names)
if df.size == 0:
return
self.tableExcelData.setRowCount(df.shape[0])
self.tableExcelData.setColumnCount(df.shape[1])
self.tableExcelData.setHorizontalHeaderLabels(df.columns)
for row in df.iterrows():
values = row[1]
for col_index, value in enumerate(values):
tableItem = QTableWidgetItem(str(value))
self.tableExcelData.setItem(row[0], col_index, tableItem)
self.btnLoad.setEnabled(False)
self.btnShow.setEnabled(True)
#Slot()
def cleanData(self):
self.btnLoad.setEnabled(True)
self.btnShow.setEnabled(False)
self.tableExcelData.setRowCount(0)
self.tableExcelData.setColumnCount(0)
#Slot()
def showGraphs(self):
timeOfDays = []
cdf = []
ppf = []
logTime = []
for row in range(self.tableExcelData.rowCount()):
isFailure = False
for column in range(self.tableExcelData.columnCount()):
value = self.tableExcelData.item(row, column)
if(column == 0 and str(value.text()) == 'F'):
isFailure = True
if isFailure == True:
if(column == 1): #TimeOfDays
value = int(value.text())
timeOfDays.append(value)
elif(column == 4): #CDF
value = float(value.text())
cdf.append(value)
elif(column == 5):
value = float(value.text())
ppf.append(value)
elif(column == 6):
value = float(value.text())
logTime.append(value)
print(timeOfDays)
print(cdf)
print(ppf)
print(logTime)
#fig = Figure(figsize=(12,5), dpi=100)
#firstSubplot = fig.add_subplot(111)
#firstSubplot.scatter(timeOfDays, ppf, '*')
#firstSubplot.plot(timeOfDays, ppf)
#fig.show()
#plt.plot(timeOfDays, ppf)
#plt.show()
try:
canvasFig = MplCanvas()
canvasFig.axes.scatter(timeOfDays, ppf, s=5, color='red')
canvasFig.axes.plot(timeOfDays, ppf)
canvasFig.draw()
self.tabFirstGraph.setCentralWidget(canvasFig)
except Exception as e:
print('Error: ' + str(e))
#canvas = FigureCanvasTkAgg(fig, master=self)
#canvas.get_tk_widget().pack()
#canvas.draw()
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWidget = QtWidgets.QStackedWidget()
mainWidget.addWidget(mainWindow)
mainWidget.show()
sys.exit(app.exec())
# See PyCharm help at https://www.jetbrains.com/help/pycharm/
I'm trying to generate two graphs (now it's code for only creation of one):
try:
canvasFig = MplCanvas()
canvasFig.axes.scatter(timeOfDays, ppf, s=5, color='red')
canvasFig.axes.plot(timeOfDays, ppf)
canvasFig.draw()
self.tabFirstGraph.setCentralWidget(canvasFig) #
except Exception as e:
print('Error: ' + str(e))
I tried to create another TabPane ("tabFirstGraph" as name of this object) and set canvas figure object to fill this QWidget instance. But I'm getting constantly this error:
Error: 'QWidget' object has no attribute 'setCentralWidget'
I assumed already that problem is with line above (QWidget, QTableWidget don't have this method). But how can I show my canvas figure graph on "First Graph" Tab Pane?
Thanks in advance for your all answers. :)

VTKWidget in Qt is not updated as expected

I would like to display a 3D-Animation in my Qt5-Gui. Everything works as expected, but unfortunately the scene is not getting updated when I don't interact with the vtkWidget. In other words: When I want to see the animation, I need to click continously with the mouse on the widget. I'd be greatful for any help.
import sys
import vtk
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import Qt
import numpy as np
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class mainWindow(Qt.QMainWindow):
def __init__(self, parent = None):
Qt.QMainWindow.__init__(self, parent)
self.frame = Qt.QFrame()
self.vl = Qt.QVBoxLayout()
self.button = QtWidgets.QPushButton("TestButton")
self.label = QtWidgets.QLabel("This is a label")
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
#Create Source
self.source = vtk.vtkCylinderSource()
self.source.SetCenter(0, 0, 0)
self.source.SetRadius(5.0)
#Create Mapper
self.mapper = vtk.vtkPolyDataMapper()
self.mapper.SetInputConnection(self.source.GetOutputPort())
#Create Actor
self.actor = vtk.vtkActor()
self.actor.SetMapper(self.mapper)
#Create poke matrix for cylinder
self.pMatrix = vtk.vtkMatrix4x4()
self.vl.addWidget(self.vtkWidget)
self.vl.addWidget(self.button)
self.vl.addWidget(self.label)
self.ren = vtk.vtkRenderer()
self.ren.AddActor(self.actor)
self.renWin = self.vtkWidget.GetRenderWindow()
self.renWin.AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
#Settings
self.ren.SetBackground(0.2, 0.2, 0.2)
self.timeStep = 20 #ms
self.total_t = 0
#Inititalize Window, Interactor, Renderer, Layout
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.ren.ResetCamera()
self.show()
self.iren.Initialize()
# Create Timer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.timerCallback)
self.timer.start(self.timeStep)
def timerCallback(self, *args):
self.total_t += self.timeStep / 1000
#Rotate Cylinder
angle = 2 * np.pi * self.total_t
rotMatrix = np.array([[np.cos(angle), -np.sin(angle), 0],
[np.sin(angle), np.cos(angle), 0],
[0, 0, 1]])
for i in range(3):
for j in range(3):
self.pMatrix.SetElement(i, j, rotMatrix[i, j])
self.actor.PokeMatrix(self.pMatrix)
self.ren.Render()
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
window = mainWindow()
sys.exit(app.exec_())
After reading the paintEvent()-Method of this file, I managed to find out, that one needs to call the Render()-Method of the Interactor-object. So instead of self.ren.Render() one needs to call self.iren.Render(). Then everything works.
Complete example code:
import sys
import vtk
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import Qt
import numpy as np
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class mainWindow(Qt.QMainWindow):
def __init__(self, parent = None):
Qt.QMainWindow.__init__(self, parent)
self.frame = Qt.QFrame()
self.vl = Qt.QVBoxLayout()
self.button = QtWidgets.QPushButton("TestButton")
self.label = QtWidgets.QLabel("This is a label")
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
#Create Source
self.source = vtk.vtkCylinderSource()
self.source.SetCenter(0, 0, 0)
self.source.SetRadius(5.0)
#Create Mapper
self.mapper = vtk.vtkPolyDataMapper()
self.mapper.SetInputConnection(self.source.GetOutputPort())
#Create Actor
self.actor = vtk.vtkActor()
self.actor.SetMapper(self.mapper)
#Create poke matrix for cylinder
self.pMatrix = vtk.vtkMatrix4x4()
self.vl.addWidget(self.vtkWidget)
self.vl.addWidget(self.button)
self.vl.addWidget(self.label)
self.ren = vtk.vtkRenderer()
self.ren.AddActor(self.actor)
self.renWin = self.vtkWidget.GetRenderWindow()
self.renWin.AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
#Settings
self.ren.SetBackground(0.2, 0.2, 0.2)
self.timeStep = 20 #ms
self.total_t = 0
#Inititalize Window, Interactor, Renderer, Layout
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.ren.ResetCamera()
self.show()
self.iren.Initialize()
# Create Timer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.timerCallback)
self.timer.start(self.timeStep)
def timerCallback(self, *args):
self.total_t += self.timeStep / 1000
#Rotate Cylinder
angle = 2 * np.pi * self.total_t
rotMatrix = np.array([[np.cos(angle), -np.sin(angle), 0],
[np.sin(angle), np.cos(angle), 0],
[0, 0, 1]])
for i in range(3):
for j in range(3):
self.pMatrix.SetElement(i, j, rotMatrix[i, j])
self.actor.PokeMatrix(self.pMatrix)
self.iren.Render() #NOT: self.ren.Render()
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
window = mainWindow()
sys.exit(app.exec_())
Thanks #cakelover, I was facing same issue but in C++, your solution helped me resolve it:
//PCLVisualizer pointer
pcl::visualization::PCLVisualizer::Ptr viewer_3D;
//Renderer method to update the visualizer
viewer_3D->getRenderWindow()->GetInteractor()->Render();

KIVY python: Slider inside ScrollView

I created a scroll view in which i put some labels and 2 sliders.
The scroll works perfectly, but I can't change the slider's value with my mouse...
Please run this code and see:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.slider import Slider
from kivy.uix.textinput import TextInput
class Home(BoxLayout):
def __init__(self, **kwargs):
super(Home, self).__init__(**kwargs)
self.layout = GridLayout(cols=1, padding=5, spacing=20, size_hint=(1, None))
self.layout.bind(minimum_height=self.layout.setter('height'))
for i in range(50):
if i%25==0:
btn = Slider(min=1, max=10, value=4)
else:
btn = Label(text=str(i), color=(0,0,0,1), size=(32, 32), size_hint=(1, None))
self.layout.add_widget(btn)
self.scrll = ScrollView(size_hint=(1, .6), pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)
self.scrll.add_widget(self.layout)
self.add_widget(self.scrll)
class MyAppli(App):
def build(self):
Window.clearcolor = (1,1,1,1)
return Home()
if __name__ == '__main__':
MyAppli().run()
Okay when you work with slider you shall redefine the on_touch_down, on_touch_up and on_touch_move method to handle those events:
-main.py :
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.properties import NumericProperty
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.slider import Slider
class Home(BoxLayout):
def __init__(self, **kwargs):
super(Home, self).__init__(**kwargs)
self.b = []
self.layout = GridLayout(cols=1, padding=5, spacing=20, size_hint=(1, None))
self.layout.bind(minimum_height=self.layout.setter('height'))
for i in range(50):
if i % 25 == 0:
self.b.append(MySlider(min=1, max=10, value=4, height=32, size_hint=(1, None)))
else:
self.b.append(Label(text=str(i), color=(0,0,0,1), height=32, size_hint=(1, None)))
self.layout.add_widget(self.b[i])
self.scrll = ScrollView(size_hint=(1, .6), pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)
self.scrll.add_widget(self.layout)
self.add_widget(self.scrll)
def update(self, *args):
for i in range(50):
if i % 25 == 0:
self.b[i].begin = self.b[i].pos[0]
self.b[i].len = self.b[i].size[0]
class MySlider(Slider):
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
super(MySlider, self).on_touch_down(touch)
def on_touch_up(self, touch):
if self.collide_point(*touch.pos):
super(MySlider, self).on_touch_up(touch)
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
super(MySlider, self).on_touch_move(touch)
class MyAppli(App):
def build(self):
Window.clearcolor = (1,1,1,1)
return Home()
if __name__ == '__main__':
MyAppli().run()
-some outputs :
I hope this helps !

pyqt5 videowidget not showing in layout

I am writing a program with pyqt5 where pressing a button first cycles through some pictures then cycles through some videos.
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
import glob
import argparse
import sys
class MainWindow(QMainWindow):
def __init__(self,args):
super(MainWindow, self).__init__()
self.setWindowTitle('Navon test')
self.setWindowFlags(Qt.FramelessWindowHint)
# exit option for the menu bar File menu
self.exit = QAction('Exit', self)
self.exit.setShortcut('Ctrl+q')
# message for the status bar if mouse is over Exit
self.exit.setStatusTip('Exit program')
# newer connect style (PySide/PyQT 4.5 and higher)
self.exit.triggered.connect(app.quit)
self.setWindowIcon(QIcon('icon.ico'))
self.centralwidget = CentralWidget(args)
self.setCentralWidget(self.centralwidget)
def keyPressEvent(self, QKeyEvent):
if QKeyEvent.key() == Qt.Key_Escape:
QCoreApplication.instance().quit()
self.centralwidget.startvid()
class CentralWidget(QWidget):
def __init__(self,args):
super(CentralWidget, self).__init__()
self.layout = QVBoxLayout()
self.layout.setAlignment(Qt.AlignCenter)
self.setLayout(self.layout)
self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.vw = QVideoWidget()
self.player.setVideoOutput(self.vw)
def startvid(self):
self.layout.addWidget(self.vw)
url= QUrl.fromLocalFile(glob.glob("videos/*")[0])
content= QMediaContent(url)
self.player.setMedia(content)
self.player.setVideoOutput(self.vw)
self.player.play()
if __name__== "__main__":
parser = argparse.ArgumentParser()
#~ parser.add_argument("-nb","--nobox",action="store_true", help="do not wait for the box connection")
args = parser.parse_args()
app = QApplication(sys.argv)
mainwindow = MainWindow(args)
#~ mainwindow.showFullScreen()
mainwindow.show()
sys.exit(app.exec_())
I tried to paste the minimal code. The thing is, I press the button nothing shows, although I used examples like this one PyQt5 - Can't play video using QVideoWidget to test if playing the video is ok, and these work. It's as if it is not adding the widget to the layout or something. Any idea what might be wrong?
I had to use QGraphicsView to achieve what I wanted, here is a fix:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
import glob
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle('Navon test')
self.setWindowFlags(Qt.FramelessWindowHint)
# exit option for the menu bar File menu
self.exit = QAction('Exit', self)
self.exit.setShortcut('Ctrl+q')
# message for the status bar if mouse is over Exit
self.exit.setStatusTip('Exit program')
# newer connect style (PySide/PyQT 4.5 and higher)
self.exit.triggered.connect(app.quit)
self.setWindowIcon(QIcon('icon.ico'))
self.centralwidget = VideoPlayer()
self.setCentralWidget(self.centralwidget)
def keyPressEvent(self, QKeyEvent):
if QKeyEvent.key() == Qt.Key_Escape:
self.centralwidget.phaseQuit(2)
self.centralwidget.play()
class VideoPlayer(QWidget):
def __init__(self, parent=None):
super(VideoPlayer, self).__init__(parent)
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.videoItem = QGraphicsVideoItem()
self.videoItem.setSize(QSizeF(640, 480))
scene = QGraphicsScene(self)
graphicsView = QGraphicsView(scene)
scene.addItem(self.videoItem)
layout = QVBoxLayout()
layout.addWidget(graphicsView)
self.setLayout(layout)
self.mediaPlayer.setVideoOutput(self.videoItem)
self.counter = 0
def play(self):
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
pass
else:
self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(glob.glob("videos/*")[self.counter])))
self.mediaPlayer.play()
self.counter += 1
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
player = MainWindow()
player.show()
sys.exit(app.exec_())