Adding Button and Separate Window to Python QProcess Example - python

I'm trying to use QProcess and read the stdout to a QTextEdit initiated by a button. How can I adapt this example to do so? Do I have to call a separate class for the QProcess?
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
class MyQProcess(QProcess):
def __init__(self):
#Call base class method
QProcess.__init__(self)
#Create an instance variable here (of type QTextEdit)
self.edit = QTextEdit()
self.edit.setWindowTitle("QTextEdit Standard Output Redirection")
self.edit.show()
#Define Slot Here
#pyqtSlot()
def readStdOutput(self):
self.edit.append(QString(self.readAllStandardOutput()))
def main():
app = QApplication(sys.argv)
qProcess = MyQProcess()
qProcess.setProcessChannelMode(QProcess.MergedChannels);
qProcess.start("ldconfig -v")
QObject.connect(qProcess,SIGNAL("readyReadStandardOutput()"),qProcess,SLOT("readStdOutput()"));
return app.exec_()
if __name__ == '__main__':
main()

Use QPushButton to make a button.
Use QPushButton.clicked.connect to bind event.
For example:
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
self.edit = QTextEdit()
self.edit.setWindowTitle("QTextEdit Standard Output Redirection")
self.button = QPushButton('Run ldconfig')
self.button.clicked.connect(self.onClick)
layout = QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.button)
#pyqtSlot()
def readStdOutput(self):
self.edit.append(QString(self.proc.readAllStandardOutput()))
def onClick(self):
self.proc = QProcess()
self.proc.start("echo hello")
self.proc.setProcessChannelMode(QProcess.MergedChannels);
QObject.connect(self.proc, SIGNAL("readyReadStandardOutput()"), self, SLOT("readStdOutput()"));
def main():
app = QApplication(sys.argv)
win = MyWindow()
win.show()
return app.exec_()
if __name__ == '__main__':
main()

Related

How to create a two or more Color Custom QPushButton in PyQt5?

How to Create a Custom Button with two or More color text and as well as in With double or single underline(in a particular letter)? I tried my level best. But the Blank button (no text) only appears.
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class MyButton(QPushButton):
def __init__ (self, mytext,parent=None):
super(MyButton,self).__init__()
self.mytext = mytext
def paintEvent(self, event):
document = QTextDocument()
document.setDocumentMargin(0)
document.setHtml(mytext)
mypixmap=QPixmap(document.size().tosize())
mypixmap.fill(Qt.transparent)
painter = QPainter(mypixmap)
document.drawContents(painter)
painter.end()
class CustomButton(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Grid layout Example")
self.setGeometry(100,100,400,400)
self.widget()
self.show()
def widget(self):
self.btn_sample = MyButton(QIcon("<h2><i>My sample</i> <font color=red>Button!</font></h2>"))
self.btn_sample.resize(20,20)
self.layout = QVBoxLayout()
self.layout.addWidget(self.btn_sample)
self.setLayout(self.layout)
def main():
app = QApplication(sys.argv)
mainwindow = CustomButton()
mainwindow.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class MyButton(QPushButton):
def __init__(self, Text, parent = None):
super(MyButton, self).__init__()
mydocument = QTextDocument()
mydocument.setDocumentMargin(0)
mydocument.setHtml(Text)
mypixmap = QPixmap(mydocument.size().toSize())
mypixmap.fill(Qt.transparent)
mypainter = QPainter(mypixmap)
mydocument.drawContents(mypainter)
mypainter.end()
myicon = QIcon(mypixmap)
self.setIcon(myicon)
self.setIconSize(mypixmap.size())
class mainwindow(QWidget):
def __init__(self , parent = None):
super(mainwindow, self).__init__()
self.setupgui()
def setupgui(self):
self.resize(800,600)
self.setWindowTitle('Custom Button With two Color Text')
newLayout = QHBoxLayout()
self.dashboard = MyButton("<h2><i>Dash Board</i> <font color=red>Qt!</font></h2>",self)
self.transcation = MyButton('<font color="red"><u>T</u></font><font color="black">ranscation</font>',self)
newLayout.addWidget(self.dashboard)
newLayout.addWidget(self.transcation)
self.setLayout(newLayout)
self.show()
def main():
app = QApplication(sys.argv)
ex = mainwindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Exit when Python gui button is clicked

I want to show the results by clicking on the button, but if I press this code, the program will end in two seconds.
And 'pursent.ui' is just a widget that hasn't been set up.
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
form_class = uic.loadUiType("pursent.ui")[0]
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.btneve)
def btneve(self):
self.statusbar.showMessage((int(self.lineEdit_2.text())-int(self.lineEdit.text()))/int(self.lineEdit.text())*100)
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
void QStatusBar::showMessage(const QString &message, int timeout = 0)
Hides the normal status indications and displays the given message for the specified number of milli-seconds (timeout).
import sys
from PyQt5.QtWidgets import *
#from PyQt5 import uic
#form_class = uic.loadUiType("pursent.ui")[0]
class MyWindow(QMainWindow): #, form_class):
def __init__(self):
super().__init__()
# self.setupUi(self)
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.lineEdit = QLineEdit()
self.lineEdit_2 = QLineEdit()
self.pushButton = QPushButton('Button')
self.pushButton.clicked.connect(self.btneve)
self.statusbar = self.statusBar() # = StatusBar(self)
grid = QGridLayout(centralWidget)
grid.addWidget(self.lineEdit)
grid.addWidget(self.lineEdit_2)
grid.addWidget(self.pushButton)
def btneve(self):
self.statusbar.showMessage(str( # + str
(int(self.lineEdit_2.text())-int(self.lineEdit.text()))/int(self.lineEdit.text())*100)
)
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()

How to create a Widget using .ui file?

I'd like to create a widget inside a MainWindow that gets its design from a file created with QtDesigner.
the .ui file I created is test.ui
I have a MainWindow instance inheriting from QMainWindow that will create a stacked widget with many widgets inside it. For simplicity in this example, it will create just a widget as central widget.
The My Widget instance inside the MainWindow is the one that has to grab its design from the .ui file
As it is, the application shows a blank window
Here is the code:
from PySide2.QtWidgets import QMainWindow, QApplication, QDesktopWidget, QWidget
from PySide2.QtCore import QCoreApplication, Qt
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile
class MyWidget(QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
ui_file = QFile("test.ui")
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui_dim_percentage = 70/100
self.initUI()
def initUI(self):
self.center()
self.home_widget = MyWidget(self)
self.setCentralWidget(self.home_widget)
self.show()
def center(self): # resizes the UI to a percentage of the screen and centers the widget
screen_size = QDesktopWidget().screenGeometry()
self.resize(screen_size.width()*self.ui_dim_percentage, screen_size.height()*self.ui_dim_percentage)
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
How should I correct the code?
The problem is that you are confusing concepts, when you use QUiLoader you are creating the window that in this case is the window variable that is a local variable, that is, the .ui does not fill in MyWidget.
The solution is not to create the MyWidget class, just use the window variable.
from PySide2.QtWidgets import QMainWindow, QApplication, QDesktopWidget
from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
def create_widget():
ui_file = QFile("test.ui")
if ui_file.open(QFile.ReadOnly):
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
return window
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui_dim_percentage = 70 / 100
self.initUI()
def initUI(self):
self.center()
self.home_widget = create_widget()
self.setCentralWidget(self.home_widget)
self.show()
# resizes the UI to a percentage of the screen and centers the widget
def center(self):
screen_size = QDesktopWidget().screenGeometry()
self.resize(
screen_size.width() * self.ui_dim_percentage,
screen_size.height() * self.ui_dim_percentage,
)
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
import sys
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Have you tried to convert your ui-file?
You can use pyuic4 command on shell:
pyuic4 test.ui -o test.py

QThread can not be called in PyQt

I have implement a subclass about the QThread, but the run can not be called:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class MyThread(QThread):
def __init__(self):
super(MyThread,self).__init__()
def run(self):
for i in range(1000):
print(i)
if __name__ == '__main__':
import sys
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(500,500)
self.label = QLabel()
self.setCentralWidget(self.label)
layout = QHBoxLayout()
self.label.setLayout(layout)
btn = QPushButton('start')
layout.addWidget(btn)
btn.clicked.connect(self.BTNClick)
def BTNClick(self):
thread = MyThread()
thread.start()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
When I debug the code, I find the MyThread is normally run. But when I directly run the code, the function 'run' would not be called.
A local variable is deleted when you finish executing the function, in your case thread is a local variable of BTNClick, so when you start it is eliminated, if you want the thread to persist even after executing BTNClick you must do it an attribute using self:
def BTNClick(self):
self.thread = MyThread()
self.thread.start()

Unittesting PyQt app

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

Categories