I refer to the article1 to build my GUI by PyQt5,The difference between the program of the article and mine is the module <img_controller.py>. When I initilize my img_controller instance,I only need the parameter ui(the class I got from Qtdesigner)and my program ,img_controller. will revise the attributes of ui. Initialize the parameters of img_controller.py according to 1 are directed inputted attributes of ui.
When I run the program got from 1, it can work normally; but I run my program, I can't get the mainwindow and the wrong message hints that "AttributeError: 'Img_controller' object has no attribute 'ui'".I don't know where is my problem, because in the function __ init __ of Img_controller(class), I state that "self.ui = ui",anyone can tell me the problem, thank you very much.
The following is my program:
UI.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1085, 857)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(110, 20, 861, 491))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.scrollArea = QtWidgets.QScrollArea(self.verticalLayoutWidget)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
# self.scrollAreaWidgetContents = QtWidgets.QWidget()
# self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 857, 487))
# self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.image_label = QtWidgets.QLabel(self.scrollArea) #此處有更動
self.image_label.setGeometry(QtCore.QRect(10, 10, 841, 471))
self.image_label.setObjectName("image_label")
self.scrollArea.setWidget(self.image_label) #此處有更動
self.verticalLayout.addWidget(self.scrollArea)
self.btn_zoomin = QtWidgets.QPushButton(self.centralwidget)
self.btn_zoomin.setGeometry(QtCore.QRect(330, 530, 75, 23))
self.btn_zoomin.setObjectName("btn_zoomin")
self.btn_zoomout = QtWidgets.QPushButton(self.centralwidget)
self.btn_zoomout.setGeometry(QtCore.QRect(640, 530, 75, 23))
self.btn_zoomout.setObjectName("btn_zoomout")
self.slider = QtWidgets.QSlider(self.centralwidget)
self.slider.setGeometry(QtCore.QRect(440, 530, 160, 22))
self.slider.setOrientation(QtCore.Qt.Horizontal)
self.slider.setObjectName("slider")
self.btn_open = QtWidgets.QPushButton(self.centralwidget)
self.btn_open.setGeometry(QtCore.QRect(140, 530, 75, 23))
self.btn_open.setObjectName("btn_open")
self.label_resolution = QtWidgets.QLabel(self.centralwidget)
self.label_resolution.setGeometry(QtCore.QRect(770, 530, 75, 15))
self.label_resolution.setObjectName("label_resolution")
self.label_filename = QtWidgets.QLabel(self.centralwidget)
self.label_filename.setGeometry(QtCore.QRect(130, 660, 111, 41))
self.label_filename.setObjectName("label_filename")
self.label_img_shape = QtWidgets.QLabel(self.centralwidget)
self.label_img_shape.setGeometry(QtCore.QRect(540, 620, 411, 51))
self.label_img_shape.setObjectName("label_img_shape")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1085, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.image_label.setText(_translate("MainWindow", "image"))
self.btn_zoomin.setText(_translate("MainWindow", "zoom_in"))
self.btn_zoomout.setText(_translate("MainWindow", "zoom_out"))
self.btn_open.setText(_translate("MainWindow", "open file"))
self.label_resolution.setText(_translate("MainWindow", "TextLabel"))
self.label_filename.setText(_translate("MainWindow", "file_name"))
self.label_img_shape.setText(_translate("MainWindow", "TextLabel"))
img_controller.py
from PyQt5 import QtCore, QtGui
import cv2
from UI import Ui_MainWindow
class Img_controller(object):
def __init__(self, ui:Ui_MainWindow, img_ratio:int = 50):
super(Img_controller, self).__init__()
self.img_path = 'sad.jpg'
self.img_ratio = img_ratio
self.read_img(self.img_path)
self.ui = ui
def read_img(self,img_path):
try:
self.img = cv2.imread(img_path)
self.orig_h, self.orig_w, self.orig_c = self.img.shape
self.img_path = img_path
except:
self.img = cv2.imread(self.img_path)
self.orig_h, self.orig_w, self.orig_c = self.img.shape
bytesPerline = self.orig_h*self.orig_c
self.qimg = QtGui.QImage(self.img, self.orig_w, self.orig_h, bytesPerline, QtGui.QImage.Format_RGB888).rgbSwapped()
self.origin_qpixmap = QtGui.QPixmap.fromImage(self.qimg)
self.img_ratio = 50
self.set_img_ratio()
def set_img_ratio(self):
self.img_ratio = pow(10, (self.img_ratio - 50)/50)
qpixmap_height = self.orig_h * self.img_ratio
self.qpixmap = self.origin_qpixmap.scaledToHeight(qpixmap_height)
#更新UI介面上的顯示
self.__update_img()
self.__update_text_ratio()
self.__update_text_img_shape()
self.__update_text_file_path()
def __update_img(self):
self.ui.image_label.setPixmap(self.qpixmap)
self.ui.image_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
def __update_text_file_path(self):
self.ui.label_filename.setText(f"File path = {self.img_path}")
def __update_text_ratio(self):
self.ui.label_resolution.setText(f"{int(100*self.img_ratio)} %")
def __update_text_img_shape(self):
current_text = f"Current img shape = ({self.qpixmap.width()}, {self.qpixmap.height()})"
origin_text = f"Origin img shape = ({self.origin_width}, {self.origin_height})"
self.ui.label_img_shape.setText(current_text+"\t"+origin_text)
def set_zoom_in(self):
self.img_ratio = max(0, self.img_ratio - 1)
self.set_img_ratio()
def set_zoom_out(self):
self.img_ratio = min(100, self.img_ratio + 1)
self.set_img_ratio()
def set_slider_value(self, value):
self.img_ratio = value
self.set_img_ratio()
controller.py
from PyQt5 import QtCore,QtWidgets,QtGui
from PyQt5.QtWidgets import QMainWindow,QFileDialog
from img_controller import Img_controller
from UI import Ui_MainWindow
class Ui_controller(QMainWindow):
def __init__(self):
super(Ui_controller,self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.setup_control()
def setup_control(self):
self.img_controller = Img_controller(ui = self.ui)
self.ui.btn_open.clicked.connect(self.open_file)
self.ui.btn_zoomin.clicked.connect(self.img_controller.set_zoom_in)
self.ui.btn_zoomout.clicked.connect(self.img_controller.set_zoom_out)
self.ui.slider.valueChanged.connect(self.getslidervalue)
def open_file(self):
filename, filetype = QFileDialog.getOpenFileName(self, "Open file", "./") # start path
self.init_new_picture(filename)
def init_new_picture(self, filename):
self.ui.slider.setProperty("value", 50)
self.img_controller.read_img(filename)
def getslidervalue(self):
self.img_controller.set_slider_value(self.ui.slider.value()+1)
What you DIDN'T say was the key piece of information -- the rest of the traceback. Notice that Img_controller.__init__ calls self.read_img, which calls self.set_img_ratio, which calls self.__update_img, which uses self.ui, and that all happens BEFORE you set self.ui. You need to swap the order of that initialization.
Related
I'm having this problem and I have no ideea why is not working.
I'm pretty new to python so I will appreciate if you can help me
It's a very simple GUI, first page open another page when clicking on a button and on a second page I need to open a browse window and take the path as string
Thats the Main Page
from PyQt5 import QtCore, QtGui, QtWidgets
from testGui import Ui_Test
class Ui_PragrammingGUI(object):
def open_test_window(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_Test()
self.ui.setupUi(self.window)
self.ui.get_all_serials()
self.window.show()
def setupUi(self, PragrammingGUI):
PragrammingGUI.setObjectName("PragrammingGUI")
PragrammingGUI.resize(237, 177)
self.centralwidget = QtWidgets.QWidget(PragrammingGUI)
self.centralwidget.setObjectName("centralwidget")
self.test_2 = QtWidgets.QPushButton(self.centralwidget)
self.test_2.setGeometry(QtCore.QRect(60, 100, 121, 31))
self.test_2.setObjectName("test_2")
self.test_2.clicked.connect(self.open_test_window)
PragrammingGUI.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(PragrammingGUI)
self.menubar.setGeometry(QtCore.QRect(0, 0, 237, 20))
self.menubar.setObjectName("menubar")
PragrammingGUI.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(PragrammingGUI)
self.statusbar.setObjectName("statusbar")
PragrammingGUI.setStatusBar(self.statusbar)
self.retranslateUi(PragrammingGUI)
QtCore.QMetaObject.connectSlotsByName(PragrammingGUI)
def retranslateUi(self, PragrammingGUI):
_translate = QtCore.QCoreApplication.translate
PragrammingGUI.setWindowTitle(_translate("PragrammingGUI", "Programming"))
self.test_2.setText(_translate("PragrammingGUI", "TEST"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
PragrammingGUI = QtWidgets.QMainWindow()
ui = Ui_PragrammingGUI()
ui.setupUi(PragrammingGUI)
PragrammingGUI.show()
sys.exit(app.exec_())
and the one which have browse in it is (ignore the get_all_serials method):
import sys
import os
from cameraID import CameraID
from PyQt5.QtWidgets import QFileDialog, QDialog
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Test(QDialog):
def browse_file_src(self):
print('in the function')
file_name = QFileDialog.getOpenFileName(self, 'Open file', '/home/qauser/')
self.lineEdit.setText(file_name[0])
def get_all_serials(self):
self.serial = CameraID()
self.serial.getAllSerial()
return_list = self.serial.getAllSerial()
if len(return_list) > 0:
for i in return_list:
self.comboBox.addItem(i)
else:
self.comboBox.addItem("None")
def setupUi(self, Test):
Test.setObjectName("Test")
Test.resize(397, 108)
self.centralwidget = QtWidgets.QWidget(Test)
self.centralwidget.setObjectName("centralwidget")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(10, 10, 291, 21))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setPlaceholderText("Chose file")
self.browseBtn = QtWidgets.QPushButton(self.centralwidget)#, clicked=lambda: self.browseBtn)
self.browseBtn.setGeometry(QtCore.QRect(310, 10, 80, 23))
self.browseBtn.setObjectName("browseBtn")
self.browseBtn.clicked.connect(self.browseBtn)
self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
self.radioButton.setGeometry(QtCore.QRect(10, 40, 51, 21))
self.radioButton.setObjectName("radioButton")
self.radioButton_2 = QtWidgets.QRadioButton(self.centralwidget)
self.radioButton_2.setGeometry(QtCore.QRect(60, 40, 71, 21))
self.radioButton_2.setObjectName("radioButton_2")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(310, 40, 80, 23))
self.pushButton.setObjectName("pushButton")
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setGeometry(QtCore.QRect(120, 40, 181, 23))
self.comboBox.setObjectName("comboBox")
Test.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(Test)
self.menubar.setGeometry(QtCore.QRect(0, 0, 397, 20))
self.menubar.setObjectName("menubar")
Test.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(Test)
self.statusbar.setObjectName("statusbar")
Test.setStatusBar(self.statusbar)
self.retranslateUi(Test)
QtCore.QMetaObject.connectSlotsByName(Test)
def retranslateUi(self, Test):
_translate = QtCore.QCoreApplication.translate
Test.setWindowTitle(_translate("Test", "MainWindow"))
self.browseBtn.setText(_translate("Test", "Browse"))
self.radioButton.setText(_translate("Test", "Ok"))
self.radioButton_2.setText(_translate("Test", "Failed"))
self.pushButton.setText(_translate("Test", "Start"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Test = QtWidgets.QMainWindow()
ui = Ui_Test()
ui.setupUi(Test)
Test.show()
sys.exit(app.exec_())
I think the issue is this: self.browseBtn.clicked.connect(self.browseBtn).
You are trying to connect the click event to the button itself.
You probably want to do something like: self.browseBtn.clicked.connect(self.method_to_call_when_clicked) where method_to_call_when_clicked is replaced by the name of the method you wish to call when it is clicked.
An example already in your code is:
self.test_2.clicked.connect(self.open_test_window)
I wrote a program that adds two numbers entered by the user into QLineEdit.
The result of the addition is output to the console in Pycharm.
How to make the result output to the application itself? (so that the user can see the answer).
I guess that there is some special method for this, but what is it?
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Probnei(object):
def setupUi(self, Probnei):
Probnei.setObjectName("Probnei")
Probnei.resize(439, 309)
self.centralwidget = QtWidgets.QWidget(Probnei)
self.centralwidget.setObjectName("centralwidget")
self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget.setGeometry(QtCore.QRect(90, 140, 214, 22))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_2 = QtWidgets.QLabel(self.layoutWidget)
self.label_2.setObjectName("label_2")
self.horizontalLayout_2.addWidget(self.label_2)
self.Second_n = QtWidgets.QLineEdit(self.layoutWidget)
self.Second_n.setObjectName("Second_n")
self.horizontalLayout_2.addWidget(self.Second_n)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(360, 210, 75, 23))
self.pushButton.setObjectName("pushButton")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(90, 60, 214, 22))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.First_n = QtWidgets.QLineEdit(self.widget)
self.First_n.setObjectName("First_n")
self.horizontalLayout.addWidget(self.First_n)
Probnei.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(Probnei)
self.menubar.setGeometry(QtCore.QRect(0, 0, 439, 21))
self.menubar.setObjectName("menubar")
Probnei.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(Probnei)
self.statusbar.setObjectName("statusbar")
Probnei.setStatusBar(self.statusbar)
self.retranslateUi(Probnei)
QtCore.QMetaObject.connectSlotsByName(Probnei)
def retranslateUi(self, Probnei):
_translate = QtCore.QCoreApplication.translate
Probnei.setWindowTitle(_translate("Probnei", "MainWindow"))
self.label_2.setText(_translate("Probnei", "Второе число:"))
self.pushButton.setText(_translate("Probnei", "Посчитать"))
self.label.setText(_translate("Probnei", "Первое число:"))
self.pushButton.clicked.connect(self.cal)
def cal(self, Probnei):
val_1 = self.First_n.text()
val_2 = self.Second_n.text()
res = int(val_1) + int(val_2)
print(res)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Probnei = QtWidgets.QMainWindow()
ui = Ui_Probnei()
ui.setupUi(Probnei)
Probnei.show()
sys.exit(app.exec_())
How to make the result output to the application itself?
It's not magic. You just have to create a widget that will display the answer. Then set the text on that widget when you do the calculation.
self.answerLabel = QtWidgets.QLabel(self.widget)
def cal(self, Probnei):
val_1 = self.First_n.text()
val_2 = self.Second_n.text()
res = int(val_1) + int(val_2)
self.answerLabel.setText(res)
I have two windows, first window is 'FirstWindow' and second is 'Calendar'. first window has one push button (pbSelectDate) and one label (lbDate). calendar window has calendar (CalendarBox) and one push button (pbSelect).
when i click select (pbSelectDate) from first window, calendar window pops up. I select the date and press select button (pbSelect) in the calendar window. i want to print the selected date to the label (lbDate) in the first window.
thanks in advance. :)
this is the first window script.
from PyQt5 import QtCore, QtGui, QtWidgets
from Calendar import Ui_CalendarWindow
class Ui_FirstWindow(object):
def Open_Calendar(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_CalendarWindow()
self.ui.setupUi(self.window)
self.window.show()
def setupUi(self, FirstWindow):
FirstWindow.setObjectName("FirstWindow")
FirstWindow.resize(654, 242)
self.centralwidget = QtWidgets.QWidget(FirstWindow)
self.centralwidget.setObjectName("centralwidget")
self.lbDate = QtWidgets.QLabel(self.centralwidget)
self.lbDate.setGeometry(QtCore.QRect(330, 70, 281, 131))
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.lbDate.setFont(font)
self.lbDate.setLayoutDirection(QtCore.Qt.LeftToRight)
self.lbDate.setObjectName("lbDate")
self.pbSelectDate = QtWidgets.QPushButton(self.centralwidget)
self.pbSelectDate.setGeometry(QtCore.QRect(80, 100, 191, 61))
self.pbSelectDate.setObjectName("pbSelectDate")
self.pbSelectDate.clicked.connect(self.Open_Calendar)
FirstWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(FirstWindow)
self.statusbar.setObjectName("statusbar")
FirstWindow.setStatusBar(self.statusbar)
self.retranslateUi(FirstWindow)
QtCore.QMetaObject.connectSlotsByName(FirstWindow)
def retranslateUi(self, FirstWindow):
_translate = QtCore.QCoreApplication.translate
FirstWindow.setWindowTitle(_translate("FirstWindow", "MainWindow"))
self.lbDate.setText(_translate("FirstWindow", "Sep"))
self.pbSelectDate.setText(_translate("FirstWindow", "Select Date"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
FirstWindow = QtWidgets.QMainWindow()
ui = Ui_FirstWindow()
ui.setupUi(FirstWindow)
FirstWindow.show()
sys.exit(app.exec_())
this is the Calendar window script..
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_CalendarWindow(object):
def PickedDate(self,var):
self.selecteddate = self.CalendarBox.selectedDate()
#print(self.selecteddate.toString('MMM')+'-'+self.selecteddate.toString('yyyy'))
def setupUi(self, CalendarWindow):
CalendarWindow.setObjectName("CalendarWindow")
CalendarWindow.resize(512, 458)
self.centralwidget = QtWidgets.QWidget(CalendarWindow)
self.centralwidget.setObjectName("centralwidget")
self.CalendarBox = QtWidgets.QCalendarWidget(self.centralwidget)
self.CalendarBox.setGeometry(QtCore.QRect(20, 20, 464, 289))
self.CalendarBox.setObjectName("CalendarBox")
self.pbSelect = QtWidgets.QPushButton(self.centralwidget)
self.pbSelect.setGeometry(QtCore.QRect(160, 330, 181, 60))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.pbSelect.setFont(font)
self.pbSelect.setObjectName("pbSelect")
self.pbSelect.clicked.connect(self.PickedDate)
CalendarWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(CalendarWindow)
self.statusbar.setObjectName("statusbar")
CalendarWindow.setStatusBar(self.statusbar)
self.retranslateUi(CalendarWindow)
QtCore.QMetaObject.connectSlotsByName(CalendarWindow)
def retranslateUi(self, CalendarWindow):
_translate = QtCore.QCoreApplication.translate
CalendarWindow.setWindowTitle(_translate("CalendarWindow", "MainWindow"))
self.pbSelect.setText(_translate("CalendarWindow", "Select"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
CalendarWindow = QtWidgets.QMainWindow()
ui = Ui_CalendarWindow()
ui.setupUi(CalendarWindow)
CalendarWindow.show()
sys.exit(app.exec_())
Do not modify the code generated by Qt Designer but create another class that inherits from the appropriate widget and use the initial class to fill it.
QLabel.setText(const QString )
Setting the text clears any previous content.
from PyQt5 import QtCore, QtGui, QtWidgets
#from Calendar import Ui_CalendarWindow
class Ui_CalendarWindow(object):
def setupUi(self, CalendarWindow):
CalendarWindow.setObjectName("CalendarWindow")
CalendarWindow.resize(512, 458)
self.centralwidget = QtWidgets.QWidget(CalendarWindow)
self.centralwidget.setObjectName("centralwidget")
self.CalendarBox = QtWidgets.QCalendarWidget(self.centralwidget)
self.CalendarBox.setGeometry(QtCore.QRect(20, 20, 464, 289))
self.CalendarBox.setObjectName("CalendarBox")
self.pbSelect = QtWidgets.QPushButton(self.centralwidget)
self.pbSelect.setGeometry(QtCore.QRect(160, 330, 181, 60))
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.pbSelect.setFont(font)
self.pbSelect.setObjectName("pbSelect")
# self.pbSelect.clicked.connect(self.PickedDate)
CalendarWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(CalendarWindow)
self.statusbar.setObjectName("statusbar")
CalendarWindow.setStatusBar(self.statusbar)
self.retranslateUi(CalendarWindow)
QtCore.QMetaObject.connectSlotsByName(CalendarWindow)
def retranslateUi(self, CalendarWindow):
_translate = QtCore.QCoreApplication.translate
CalendarWindow.setWindowTitle(_translate("CalendarWindow", "MainWindow"))
self.pbSelect.setText(_translate("CalendarWindow", "Select"))
class Ui_FirstWindow(object):
def setupUi(self, FirstWindow):
FirstWindow.setObjectName("FirstWindow")
FirstWindow.resize(654, 242)
self.centralwidget = QtWidgets.QWidget(FirstWindow)
self.centralwidget.setObjectName("centralwidget")
self.lbDate = QtWidgets.QLabel(self.centralwidget)
self.lbDate.setGeometry(QtCore.QRect(330, 70, 281, 131))
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.lbDate.setFont(font)
self.lbDate.setLayoutDirection(QtCore.Qt.LeftToRight)
self.lbDate.setObjectName("lbDate")
self.pbSelectDate = QtWidgets.QPushButton(self.centralwidget)
self.pbSelectDate.setGeometry(QtCore.QRect(80, 100, 191, 61))
self.pbSelectDate.setObjectName("pbSelectDate")
# self.pbSelectDate.clicked.connect(self.Open_Calendar)
FirstWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(FirstWindow)
self.statusbar.setObjectName("statusbar")
FirstWindow.setStatusBar(self.statusbar)
self.retranslateUi(FirstWindow)
QtCore.QMetaObject.connectSlotsByName(FirstWindow)
def retranslateUi(self, FirstWindow):
_translate = QtCore.QCoreApplication.translate
FirstWindow.setWindowTitle(_translate("FirstWindow", "MainWindow"))
self.lbDate.setText(_translate("FirstWindow", "Sep"))
self.pbSelectDate.setText(_translate("FirstWindow", "Select Date"))
class CalendarWindow(QtWidgets.QMainWindow, Ui_CalendarWindow): # +
def __init__(self):
super(CalendarWindow, self).__init__()
self.setupUi(self)
class FirstWindow(QtWidgets.QMainWindow, Ui_FirstWindow): # +
def __init__(self):
super(FirstWindow, self).__init__()
self.setupUi(self)
self.pbSelectDate.clicked.connect(self.Open_Calendar)
def Open_Calendar(self):
self.window = CalendarWindow()
self.window.setupUi(self.window)
self.window.show()
self.window.pbSelect.clicked.connect(self.PickedDate)
def PickedDate(self): # , var
self.selecteddate = self.window.CalendarBox.selectedDate()
# print(self.selecteddate.toString('MMM')+'-'+self.selecteddate.toString('yyyy'))
self.lbDate.setText(self.selecteddate.toString('ddd-MMM-yyyy')) # <---
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = FirstWindow()
w.show()
sys.exit(app.exec_())
I'm currently coding a GUI for a surveillance System I made with OpenCV. I'd like to see the live video input in a QLabel next to the settings box but I'm quite new on the emit/signal/slot topic so I'm a bit overwhelmed by the code order.
The GUI is converted from QtCreator, just to get the Layout right. The buttons don't have any functions yet.
Here's my code so far:
import sys
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
#getting the live vid
class Thread(QThread):
changePixmap = pyqtSignal(QImage)
def run(self):
cap1 = cv2.VideoCapture('single.mp4')
while True:
ret, frame = cap1.read()
rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cvt2qt = QImage(rgb_image.data, rgb_image.shape[1], rgb_image.shape[0], QImage.Format_RGB888)
self.changePixmap.emit(cvt2qt) # I don't really understand this yet
class Ui_MainWindow(object):
def setImage(self, image):
self.label.setPixmap(QPixmap.fromImage(image))
#pyqtSlot(QImage) # I'm not sure about this function
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 779)
MainWindow.setMinimumSize(QtCore.QSize(920, 405))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setMinimumSize(QtCore.QSize(400, 400))
self.centralWidget.setBaseSize(QtCore.QSize(800, 600))
self.centralWidget.setObjectName("centralWidget")
# here is where I want to put the image.
self.label = QtWidgets.QLabel(self.centralWidget)
self.label.setGeometry(QtCore.QRect(10, 10, 881, 671))
self.label.setScaledContents(True)
self.label.setObjectName("label")
th = Thread(self) # Here is, where I struggle
th.changePixmap.connect(self.setImage)
th.start()
MainWindow.setCentralWidget(self.centralWidget)
self.dockWidget = QtWidgets.QDockWidget(MainWindow)
self.dockWidget.setMinimumSize(QtCore.QSize(200, 0))
self.dockWidget.setLayoutDirection(QtCore.Qt.LeftToRight)
self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable)
self.dockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea|QtCore.Qt.RightDockWidgetArea)
self.dockWidget.setObjectName("dockWidget")
self.dockWidgetContents = QtWidgets.QWidget()
self.dockWidgetContents.setObjectName("dockWidgetContents")
self.groupBox = QtWidgets.QGroupBox(self.dockWidgetContents)
self.groupBox.setGeometry(QtCore.QRect(0, 30, 141, 281))
self.groupBox.setMinimumSize(QtCore.QSize(90, 0))
self.groupBox.setObjectName("groupBox")
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(10, 20, 121, 32))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_2.setGeometry(QtCore.QRect(10, 50, 121, 32))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_3.setGeometry(QtCore.QRect(10, 80, 121, 32))
self.pushButton_3.setObjectName("pushButton_3")
self.radioButton = QtWidgets.QRadioButton(self.groupBox)
self.radioButton.setGeometry(QtCore.QRect(20, 120, 100, 20))
self.radioButton.setObjectName("radioButton")
self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_2.setGeometry(QtCore.QRect(20, 150, 100, 20))
self.radioButton_2.setObjectName("radioButton_2")
self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_3.setGeometry(QtCore.QRect(20, 180, 100, 20))
self.radioButton_3.setObjectName("radioButton_3")
self.dockWidget.setWidget(self.dockWidgetContents)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "ARCV"))
self.groupBox.setTitle(_translate("MainWindow", "Settings"))
self.pushButton.setText(_translate("MainWindow", "Start Recording"))
self.pushButton_2.setText(_translate("MainWindow", "Stop Recording"))
self.pushButton_3.setText(_translate("MainWindow", "Quit GUI"))
self.radioButton.setText(_translate("MainWindow", "Camera 1"))
self.radioButton_2.setText(_translate("MainWindow", "Camera 2"))
self.radioButton_3.setText(_translate("MainWindow", "Camera 3"))
class Prog(QMainWindow):
def __init__(self):
super().__init__();
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__=='__main__':
Program = QApplication(sys.argv)
MyProg = Prog()
MyProg.show()
sys.exit(Program.exec_())
I hope, you can help me. Thanks.
Aaroknight
QThread waits as a parameter for a parent that must be a QObject, in your case self is an object of the Ui_MainWindow class that does not inherit from QObject causing the problem.
I see that you are implementing a class called Prog, there you must do the logic and not modify the code generated by Qt Designer.
So if we move the logic to that class there should be no problems.
On the other hand the decorator #pyqtSlot must be used in the function that is connected to the signal, you place it in the constructor which does not make sense, it must be on top of setImage().
import sys
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 779)
MainWindow.setMinimumSize(QtCore.QSize(920, 405))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setMinimumSize(QtCore.QSize(400, 400))
self.centralWidget.setBaseSize(QtCore.QSize(800, 600))
self.centralWidget.setObjectName("centralWidget")
# here is where I want to put the image.
self.label = QtWidgets.QLabel(self.centralWidget)
self.label.setGeometry(QtCore.QRect(10, 10, 881, 671))
self.label.setScaledContents(True)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralWidget)
self.dockWidget = QtWidgets.QDockWidget(MainWindow)
self.dockWidget.setMinimumSize(QtCore.QSize(200, 0))
self.dockWidget.setLayoutDirection(QtCore.Qt.LeftToRight)
self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable)
self.dockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea|QtCore.Qt.RightDockWidgetArea)
self.dockWidget.setObjectName("dockWidget")
self.dockWidgetContents = QtWidgets.QWidget()
self.dockWidgetContents.setObjectName("dockWidgetContents")
self.groupBox = QtWidgets.QGroupBox(self.dockWidgetContents)
self.groupBox.setGeometry(QtCore.QRect(0, 30, 141, 281))
self.groupBox.setMinimumSize(QtCore.QSize(90, 0))
self.groupBox.setObjectName("groupBox")
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(10, 20, 121, 32))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_2.setGeometry(QtCore.QRect(10, 50, 121, 32))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_3.setGeometry(QtCore.QRect(10, 80, 121, 32))
self.pushButton_3.setObjectName("pushButton_3")
self.radioButton = QtWidgets.QRadioButton(self.groupBox)
self.radioButton.setGeometry(QtCore.QRect(20, 120, 100, 20))
self.radioButton.setObjectName("radioButton")
self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_2.setGeometry(QtCore.QRect(20, 150, 100, 20))
self.radioButton_2.setObjectName("radioButton_2")
self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_3.setGeometry(QtCore.QRect(20, 180, 100, 20))
self.radioButton_3.setObjectName("radioButton_3")
self.dockWidget.setWidget(self.dockWidgetContents)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "ARCV"))
self.groupBox.setTitle(_translate("MainWindow", "Settings"))
self.pushButton.setText(_translate("MainWindow", "Start Recording"))
self.pushButton_2.setText(_translate("MainWindow", "Stop Recording"))
self.pushButton_3.setText(_translate("MainWindow", "Quit GUI"))
self.radioButton.setText(_translate("MainWindow", "Camera 1"))
self.radioButton_2.setText(_translate("MainWindow", "Camera 2"))
self.radioButton_3.setText(_translate("MainWindow", "Camera 3"))
#getting the live vid
class Thread(QtCore.QThread):
changePixmap = QtCore.pyqtSignal(QtGui.QImage)
def __init__(self, *args, **kwargs):
QtCore.QThread.__init__(self, *args, **kwargs)
self.flag = False
def run(self):
cap1 = cv2.VideoCapture('single.mp4')
self.flag = True
while self.flag:
ret, frame = cap1.read()
if ret:
rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cvt2qt = QtGui.QImage(rgb_image.data, rgb_image.shape[1], rgb_image.shape[0], QtGui.QImage.Format_RGB888)
self.changePixmap.emit(cvt2qt) # I don't really understand this yet
def stop(self):
self.flag = False
class Prog(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.th = Thread(self)
self.th.changePixmap.connect(self.setImage)
self.th.start()
#QtCore.pyqtSlot(QtGui.QImage)
def setImage(self, image):
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
def closeEvent(self, event):
self.th.stop()
self.th.wait()
super().closeEvent(event)
if __name__=='__main__':
Program = QtWidgets.QApplication(sys.argv)
MyProg = Prog()
MyProg.show()
sys.exit(Program.exec_())
I tried to follow just the first part of this guide:
http://talk.maemo.org/archive/index.php/t-39879.html
to make only the hello world part work. It doesn't
here is the error
Traceback (most recent call last):
File "helloworld2.py", line 69, in <module>
mainWindow = MainWin(None, "main window")
File "helloworld2.py", line 49, in __init__
self.setupUi(rootWidget)
File "helloworld2.py", line 25, in setupUi
MainWindow.setCentralWidget(self.centralwidget)
AttributeError: 'QWidget' object has no attribute 'setCentralWidget'
Should this be working(after tweaking), or should I go a whole different route?
If it should be working, what are the things to do to troubleshoot?
Here are the ingredients of the .py file. I'm not sure I have it entered into here correctly, I'm not sure I understand the correct way to enter it, so it will appear the same as in the file. If this doesn't look right I'll try again.
from PyKDE4 import kdecore
from PyKDE4 import kdeui
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(800, 400)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.label = QtGui.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(80, 110, 271, 51))
font = QtGui.QFont()
font.setPointSize(24)
self.label.setFont(font)
self.label.setObjectName(_fromUtf8("label"))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 20))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(kdecore.i18n(_fromUtf8("MainWindow")))
self.label.setText(kdecore.i18n(_fromUtf8("Hello World!")))
if __name__ == '__main__':
import sys
global app
class MainWin(kdeui.KMainWindow, Ui_MainWindow):
def __init__ (self, *args):
kdeui.KMainWindow.__init__ (self)
rootWidget = QtGui.QWidget(self)
self.setupUi(rootWidget)
self.resize(640, 480)
self.setCentralWidget(rootWidget)
appName = "default"
catalog = ""
programName = kdecore.ki18n("default")
version = "1.0"
description = kdecore.ki18n("Default Example")
license = kdecore.KAboutData.License_GPL
copyright = kdecore.ki18n("unknown")
text = kdecore.ki18n("none")
homePage = ""
bugEmail = "email"
aboutData = kdecore.KAboutData(appName, catalog, programName, version, description,
license, copyright, text, homePage, bugEmail)
kdecore.KCmdLineArgs.init(sys.argv, aboutData)
app = kdeui.KApplication()
mainWindow = MainWin(None, "main window")
mainWindow.show()
app.lastWindowClosed.connect(app.quit)
app.exec_ ()
Looks like your code is a little messed up, see if this is working for you and take it on from there:
#!/usr/bin/env python
from PyKDE4 import kdecore, kdeui
from PyQt4 import QtCore, QtGui
appName = "default"
catalog = ""
programName = kdecore.ki18n("default")
version = "1.0"
description = kdecore.ki18n("Default Example")
license = kdecore.KAboutData.License_GPL
copyright = kdecore.ki18n("unknown")
text = kdecore.ki18n("none")
homePage = ""
bugEmail = "email"
aboutData = kdecore.KAboutData(appName, catalog, programName, version, description,
license, copyright, text, homePage, bugEmail)
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(800, 400)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.label = QtGui.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(80, 110, 271, 51))
font = QtGui.QFont()
font.setPointSize(24)
self.label.setFont(font)
self.label.setObjectName(_fromUtf8("label"))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 20))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(kdecore.i18n(_fromUtf8("MainWindow")))
self.label.setText(kdecore.i18n(_fromUtf8("Hello World!")))
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
if __name__ == "__main__":
import sys
kdecore.KCmdLineArgs.init(sys.argv, aboutData)
app = kdeui.KApplication()
main = MainWindow()
main.resize(640, 480)
main.show()
app.lastWindowClosed.connect(app.quit)
app.exec_()