How to get imported class to change attribute of main.py label stylesheet [closed] - python-3.x

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am using PyQt5 to create a gui, defining a buttons class in a separate .py file and importing it, then trying to use a method from my buttons class to change the color of a label in my Ui_MainWindow which is my gui class in main.py
I have isolated this code from a larger project which outlines what I am attempting to accomplish.
Here is my buttons class which is saved and imported as buttons:
class buttons(object):
def __init__(self, Ui_MainWindow):
print('creating buttons object')
def func(self):
Ui_MainWindow.label.setStyleSheet("background-color: green;")
Here is my main.py with my Ui_MainWindow class which constructs the gui:
from PyQt5 import QtCore, QtGui, QtWidgets
import buttons
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(311, 228)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# Push button created
self.pushButton = QtWidgets.QPushButton(self.centralwidget, clicked = lambda: (btn_obj.func()))
self.pushButton.setGeometry(QtCore.QRect(0, 70, 131, 81))
self.pushButton.setObjectName("pushButton")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(180, 50, 121, 101))
self.label.setStyleSheet("background-color: rgb(255, 0, 4);")
self.label.setText("")
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 311, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# CREATE A BUTTONS OBJECT SO WE CAN CALL ITS METHOD
btn_obj = buttons.buttons(self)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
This is throwing the error:
Traceback (most recent call last):
File "c:\Users\Gaming\Google Drive\Code\Python\help\main.py", line 13, in <lambda>
self.pushButton = QtWidgets.QPushButton(self.centralwidget, clicked = lambda: (btn_obj.func()))
File "c:\Users\Gaming\Google Drive\Code\Python\help\buttons.py", line 6, in func
Ui_MainWindow.label.setStyleSheet("background-color: green;")
NameError: name 'Ui_MainWindow' is not defined
If I understand correctly, since the label in question is an attribute of a Ui_MainWindow object, and not the class itself it is unable to be changed with my current code. I am hoping someone could show/tell me the proper way to implement this sort of thing. Thank you in advance.

Change:
class buttons(object):
def __init__(self, Ui_MainWindow):
print('creating buttons object')
def func(self):
Ui_MainWindow.label.setStyleSheet("background-color: green;")
To:
class buttons(object):
def __init__(self, Ui_MainWindow):
print('creating buttons object')
self.Ui_MainWindow = Ui_MainWindow
def func(self):
self.Ui_MainWindow.label.setStyleSheet("background-color: green;")

Related

How to switch between tabs via pushbutton ? using pyqt

I am newbie and maybe this is silly question.
I want to activate tab by clicking on pushButton . If I click pushButton_1 then it shows/activates tab_1, on the clicking pushButton_2 switches to tab_2, and so on . Bellow there is pic how I tried it but without success. Help me solve this and write correct code down. Thank you in advance.
This is my code :
from spex import *
import sys
class speX (Ui_MainWindow):
def __init__(self, window):
self.setupUi(window)
self.systemButton.clicked.setCurrentIndex(self, 0)
self.cpuButton.clicked.setCurrentIndex(self, 1)
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = speX (MainWindow)
MainWindow.show()
app.exec_()
I want this - when I click systemButton, activate tab indexed as 0, when click cpuButton activate tab indexed as 1.
Error provided there -
Traceback (most recent call last):
File "d:\spex\main.py", line 17, in <module>
ui = speX (MainWindow)
File "d:\spex\main.py", line 9, in __init__
self.systemButton.clicked.setCurrentIndex(self, 0)
AttributeError: 'PyQt5.QtCore.pyqtBoundSignal' object has no attribute 'setCurrentIndex'
This is example of my project - pyuic5 ui to py code
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'D:/spex/example.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(763, 611)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
self.stackedWidget.setGeometry(QtCore.QRect(270, 70, 361, 361))
self.stackedWidget.setObjectName("stackedWidget")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.buttonBox = QtWidgets.QDialogButtonBox(self.page)
self.buttonBox.setGeometry(QtCore.QRect(50, 310, 193, 28))
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.commandLinkButton = QtWidgets.QCommandLinkButton(self.page_2)
self.commandLinkButton.setGeometry(QtCore.QRect(70, 190, 222, 48))
self.commandLinkButton.setObjectName("commandLinkButton")
self.stackedWidget.addWidget(self.page_2)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(50, 110, 93, 28))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(50, 190, 93, 28))
self.pushButton_2.setObjectName("pushButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 763, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.stackedWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.commandLinkButton.setText(_translate("MainWindow", "CommandLinkButton"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
self.pushButton_2.setText(_translate("MainWindow", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
In Qt, a signal is emitted when a particular event occurs: a button is clicked, some text is changed, etc.
Signals are then connected to slots, which are functions that can react in some way to those signals. For example, you can create a slot that changes the text in a label, and connect it to a clicked signal of a button: then, when you click on that button, the text is changed.
Why your code does not work?
Well, for instance, setCurrentIndex is a method of a QStackedWidget (similarly to a QTabWidget), so the following doesn't make much sense:
self.systemButton.clicked.setCurrentIndex(self, 0)
Where is the reference to the stacked widget?
In PyQt, you can connect signals and slots like this:
someObject.signal.connect(someFunction)
Note that someFunction is a reference to that function; the following will not work:
someObject.signal.connect(someFunction())
If you want to change the index of a stacked widget after clicking on a button, you have to create a function that changes that index, and connect it to the clicked signal.
class speX (Ui_MainWindow):
def __init__(self, window):
self.setupUi(window)
self.pushButton.clicked.connect(self.goToSecondPage)
def goToSecondPage(self):
self.stackedWidget.setCurrentIndex(1)
I strongly suggest you to carefully study how python classes work and, generally speaking, the Object Oriented programming paradigm.
The simplist solution would be to connect your buttons to a function that changes the tab index on click
tabs = QtWidget.QTabWidget()
tab1 = QtWidget.QWidget()
tabs.addTab(self.tab1, "Tab 1")
systemButton.clicked.connect(tabIndex0)
def tabIndex0():
tabs.setCurrentIndex(0)

Return a value from a new window in pyqt5

I wanted to open a new window by clicking on the pushbutton and type a number in the new window. After that when clicking on the "Ok" Button, the second window will be closed and the written number will be shown in the label, which was existed in the initial window. I wrote the following code but it writes 0 in the label and doesnt update.
The first Window:
from PyQt5 import QtCore, QtWidgets
from load3D import load3
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(316, 284)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(60, 60, 191, 121))
self.label.setStyleSheet("background-color: rgb(255, 255, 255);")
self.label.setText("")
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(60, 190, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 316, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.pushButton.clicked['bool'].connect(self.get_value)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def get_value(self):
length = self.load3load()
self.label.setText(str(length))
def load3load(self):
self.MainWindow = QtWidgets.QMainWindow()
self.x = 0
self.ui = load3(self.x)
self.ui.setupUi(self.MainWindow)
self.MainWindow.show()
return self.ui.x
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Click"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
And The second window:
from PyQt5 import QtCore, QtGui, QtWidgets
class load3(object):
def __init__(self, x):
self.x = 0
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(283, 340)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(20, 40, 71, 31))
font = QtGui.QFont()
font.setPointSize(18)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(90, 47, 113, 20))
self.lineEdit.setObjectName("lineEdit")
font = QtGui.QFont()
font.setPointSize(18)
self.buttonBox = QtWidgets.QDialogButtonBox(self.centralwidget)
self.buttonBox.setGeometry(QtCore.QRect(120, 260, 156, 23))
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 283, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.accepted.connect(MainWindow.close)
self.buttonBox.rejected.connect(MainWindow.close)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def accept(self):
self.x = self.lineEdit.text()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Image properties"))
self.label.setText(_translate("MainWindow", "X:"))
Any thoughts how to make it work ?
First of all, you should never edit the files generated with pyuic. They are intended to be used only as imported module. Read more about using Designer to understand how use them properly.
Second: if you need an input from the user from another window, you should use a QDialog, not a QMainWindow.
Then, if you only need a simple input value, use QInputDialog, possibly from one of its static methods, in your case getInt() will suffice.
Finally, the reason for which your code doesn't work is that after creating and showing the window you immediately get the x value, but after that the function returns immediately, since there's nothing "blocking" it (so it won't wait for any input from the user). That's what QDialogs are for: they wait from some input from the user before returning.
If you don't have the .ui files anymore, recreate them, then generate again the python files with pyuic and leave them there.
Supposing you've created a file named ui_mainwindow.py for the main window and ui_inpudialog.py for a dialog with a spinbox (not a line edit, since you need a numeric value) and a buttonbox:
from PyQt5 import QtWidgets
from ui_mainwindow import Ui_MainWindow
from ui_inputdialog import Ui_Dialog
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.get_value)
def get_value(self):
dialog = InputDialog(self)
# this will show the dialog and wait for the user to accept or reject it
if dialog.exec():
# get the value from the dialog
self.label.setText(str(dialog.getValue()))
class InputDialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
def getValue(self):
# return the current value of the spinbox
return self.spinBox.value()
Alternatively, if you don't need specific customization of the input dialog, just use QInputDialog as suggested before:
from PyQt5 import QtWidgets
from ui_mainwindow import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.get_value)
def get_value(self):
length = QtWidgets.QInputDialog.getInt(self, 'Insert value', 'Value',
min=0, max=100)
self.label.setText(str(length))

How get text from QTextEdit in Pyqt5? [duplicate]

This question already has an answer here:
Get text from qtextedit and assign it to a variable
(1 answer)
Closed 2 years ago.
I need get text from QTextEdit, but have such trouble: Traceback (most recent call last):
File "main.py", line 28, in otpravit_naz
textboxValue = self.textEdit.text()
AttributeError: 'MyWin' object has no attribute 'textEdit'
This is my code(main.py):
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from test import *
import socket
sock = socket.socket()
class MyWin(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.otpravit.clicked.connect(self.otpravit_naz)
def mbox(self, body, title='Error'):
dialog = QMessageBox(QMessageBox.Information, title, body)
dialog.exec_()
def otpravit_naz(self):
print("1")
textboxValue = self.textEdit.text()
print(textboxValue)
#sock.connect(('192.168.1.16', 9090))
sock.connect(("192.168.1.45", 9090))
sock.send(b'textboxValue')
sock.close()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = MyWin()
myapp.show()
sys.exit(app.exec_())
And ui form:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(517, 283)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(60, 20, 421, 201))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(23)
self.verticalLayout.setObjectName("verticalLayout")
self.textEdit = QtWidgets.QTextEdit(self.verticalLayoutWidget)
self.textEdit.setObjectName("textEdit")
self.verticalLayout.addWidget(self.textEdit)
self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
self.label.setLineWidth(0)
self.label.setMidLineWidth(0)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.list = QtWidgets.QComboBox(self.verticalLayoutWidget)
self.list.setObjectName("list")
self.list.addItem("")
self.list.addItem("")
self.list.addItem("")
self.verticalLayout.addWidget(self.list)
self.otpravit = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.otpravit.setObjectName("otpravit")
self.verticalLayout.addWidget(self.otpravit)
self.verticalLayout.setStretch(0, 20)
self.verticalLayout.setStretch(1, 20)
self.verticalLayout.setStretch(2, 20)
self.verticalLayout.setStretch(3, 20)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 517, 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.label.setText(_translate("MainWindow", "Предмет:"))
self.list.setItemText(0, _translate("MainWindow", "Русский"))
self.list.setItemText(1, _translate("MainWindow", "Литература"))
self.list.setItemText(2, _translate("MainWindow", "Английский"))
self.otpravit.setText(_translate("MainWindow", "Отправить"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
If it very stupid troble, pls don't kick me
You're "installing" the GUI on the self.ui object, so every widget that is on the ui is actually accessible as self.ui.someWidget.
Also, QTextEdit doesn't have a text() property, but toPlainText():
def otpravit_naz(self):
print("1")
textboxValue = self.ui.textEdit.toPlainText()
print(textboxValue)
I suggest you to never edit the files generated with pyuic, but always use them as imported modules; read more on using Designer; also, be careful to set the main layout on the central widget, not on its children, and add everything to that layout, otherwise the children widgets could be hidden whenever the window is resized.

Python PyQt5 Terminal Command execution problem on a button click

I'm trying to create an application, that can execute an embedded Terminal command when ever the button is clicked. The actual problem occurs when i click the button and nothing happens.
I have two scripts one has a terminal widget and the other has the main GUI. Any Help, would be highly appreciated.
That's first Script
import sys
from PyQt5 import QtCore, QtWidgets
class EmbTerminal(QtWidgets.QWidget):
def __init__(self, parent=None):
super(EmbTerminal, self).__init__(parent)
self._process = []
self.start_process('urxvt',['-embed', str(int(self.winId())),"-e","tmux"])
def start_process(self,prog,options):
child = QtCore.QProcess(self)
self._process.append(child)
child.start(prog,options)
def run_command(self, command = "ls" ):
program = "tmux"
options = []
options.extend(["send-keys"])
options.extend([command])
options.extend(["Enter"])
self.start_process(program, options)
That's Second Script
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(745, 496)
self.tabWidget = QtWidgets.QTabWidget(Dialog)
self.tabWidget.setGeometry(QtCore.QRect(100, 190, 561, 261))
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.tabWidget.addTab(EmbTerminal(), "Terminal")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(280, 70, 211, 71))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.pushButton.clicked.connect(lambda: EmbTerminal.run_command(EmbTerminal(), "ls"))
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Dialog", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Dialog", "Tab 2"))
self.pushButton.setText(_translate("Dialog", "ls"))
from terminal5 import EmbTerminal
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
You should consider the following:
You should not modify the code generated by Qt Designer (unless you understand its logic)
Do not implement the logic in the class generated by Qt Designer, it is advisable to create a new class that inherits from the appropriate widget and use the other class to fill it.
In your case the problem is that the EmbTerminal() object in lambda: EmbTerminal.run_command(EmbTerminal(), "ls") only exists while the lambda is running, but the lambda runs for a very short time causing the command not to be sent causing the error.
Considering the above, the solution is:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(745, 496)
self.tabWidget = QtWidgets.QTabWidget(Dialog)
self.tabWidget.setGeometry(QtCore.QRect(100, 190, 561, 261))
self.tabWidget.setObjectName("tabWidget")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(280, 70, 211, 71))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "ls"))
from terminal5 import EmbTerminal
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.terminal = EmbTerminal()
self.tabWidget.addTab(self.terminal, "Terminal")
self.pushButton.clicked.connect(self.on_clicked)
#QtCore.pyqtSlot()
def on_clicked(self):
self.terminal.run_command("ls")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
On the other hand if you are only going to send commands then it is not necessary to store the QProcess, instead use QProcess: startDetached and make run_command a classmethod:
class EmbTerminal(QtWidgets.QWidget):
# ...
#staticmethod
def run_command(command = "ls" ):
program = "tmux"
options = []
options.extend(["send-keys"])
options.extend([command])
options.extend(["Enter"])
QtCore.QProcess.startDetached(program, options)

How to send a signal from a QDialog to a QMainWindow class

I have made a UI which includes a mainwindow and a button that opens a dialog window. I want to send the current text changed signal from a line edit in the dialog window to the Mainwindow class as a variable. An example of the code I am making is below:
from PyQt5 import QtCore, QtGui, QtWidgets
from selenium import webdriver
import time
import threading
from bs4 import BeautifulSoup as soup
import requests
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(388, 179)
self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
self.lineEdit_2.setGeometry(QtCore.QRect(100, 100, 271, 21))
font = QtGui.QFont()
font.setFamily("Yu Gothic")
self.lineEdit_2.setFont(font)
self.lineEdit_2.setStyleSheet("background-color: transparent;\n"
"color: rgb(255, 255, 255);")
self.lineEdit_2.setObjectName("lineEdit_2")
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.setupUi(self)
# self.pushButton.pressed.connect(self.textEdit.clear)
# self.pushButton.pressed.connect(self.sejd)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
self.keyworddict = {}
self.count = {}
MainWindow.setObjectName("MainWindow")
MainWindow.resize(803, 538)
MainWindow.setMinimumSize(QtCore.QSize(0, 0))
MainWindow.setMaximumSize(QtCore.QSize(10000, 10000))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.pushButton = QtWidgets.QPushButton(self.centralWidget)
self.pushButton.setGeometry(QtCore.QRect(180, 210, 75, 23))
font = QtGui.QFont()
font.setFamily("Yu Gothic")
font.setBold(True)
font.setWeight(75)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralWidget)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.pushButton.pressed.connect(self.on_Button_clicked)
def on_Button_clicked(self):
dialog = QtWidgets.QDialog()
dialog.ui = Ui_Dialog()
dialog.ui.setupUi(dialog)
dialog.setWindowTitle("Login")
dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
dialog.exec_()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.setWindowTitle("ui")
w.show()
sys.exit(app.exec_())
All help appreciated. I would preferably like an example using the code above.
There are at least two simple ways to do this. You can either connect a signal when the dialog is created, or just retrieve the text after the dialog closes:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
...
def dialogTextChanged(self, text):
print(text)
def on_Button_clicked(self):
dialog = QtWidgets.QDialog()
dialog.ui = Ui_Dialog()
dialog.ui.setupUi(dialog)
# connect signal to slot
dialog.ui.lineEdit_2.textChanged.connect(self.dialogTextChanged)
dialog.setWindowTitle("Login")
# this is not needed
# dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
dialog.exec_()
# or retrieve text after dialog closes
print(dialog.ui.lineEdit_2.text())
dialog.deleteLater()
If this is a login dialog, you should probably have an accept button which is connected to the dialog's accept() slot. Then you can check the exit status of the dialog like this:
if dialog.exec_() == QtWidgets.QDialog.Accepted:
text = dialog.ui.lineEdit_2.text()
# do sothing with text ...
dialog.deleteLater()

Resources