I want to write a notepad in python with PyQt5 for persian language.
how can I align the thext in QPlainTextEdit to right?
this is my code:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPlainTextEdit
from PyQt5.QtCore import Qt, QLocale
class TextBox(QPlainTextEdit):
def persian(self):
self.setFixedSize(640, 480)
self.setLayoutDirection(Qt.RightToLeft)
self.setLocale(QLocale(QLocale.Persian, QLocale.Iran))
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.GUI()
def GUI(self):
self.setWindowTitle("My title")
self.setFixedSize(640, 480)
self.text = TextBox(self)
self.text.persian()
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
You can use a QTextEdit instead of QPlainTextEdit and use setAlignment(Qt.AlignRight), e.g.
from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtCore import Qt
class TextBox(QTextEdit):
def persian(self):
self.setFixedSize(640, 480)
self.setLayoutDirection(Qt.RightToLeft)
self.setLocale(QLocale(QLocale.Persian, QLocale.Iran))
# set text alignment to AlignRight
self.setAlignment(Qt.AlignRight)
Related
I'm new to using PyQT for a class project and I'm having some issues with it.
I want to launch MainWindow and to have 2 buttons to launch 2 separate dialog boxes (Dialog and subdialog); however I am getting the following error:
sys.exit(mainwindowa.exec_())
AttributeError: 'MainWindow' object has no attribute 'exec_'
Here is my code. I've tried playing around with how I write the exec_ function like writing it in the MainWindow class but I get the same errors and I'm pretty confuse on what to do
from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog,
QDialogButtonBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout,
QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QSpinBox, QTextEdit,
QVBoxLayout, QMainWindow)
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("My App")
layout = QVBoxLayout()
self.mainwindowapp = QPushButton('Dialog')
self.subwindowapp = QPushButton('CustomDialog')
layout.addWidget(self.mainwindowapp)
layout.addWidget(self.subwindowapp)
self.setLayout(layout)
self.show()
self.mainwindowapp.clicked.connect(self.button_clicked)
def button_clicked(self):
run = Dialog()
run()
class Dialog(QDialog):
def __init__(self):
super(Dialog, self).__init__()
mainLayout = QVBoxLayout()
mainLayout.addWidget(self.formGroupBox)
mainLayout.addWidget(buttonBox)
self.setLayout(mainLayout)
class CustomDialog(QDialog):
def __init__(self):
super().__init__(CustomDialog, self)
self.layout = QVBoxLayout()
self.layout.addWidget(QLabel('e'))
self.setLayout(self.layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
mainwindowa = MainWindow()
sys.exit(mainwindowa.exec_())
You are drawing an incorrect conclusion, you think that if the QDialog class has an exec_() method, so will other widgets like QMainWindow and that is not correct. QDialog creates an internal eventloop that other widgets do not, so in your case use the show() method and use the exec_() method of the QApplication:
if __name__ == '__main__':
app = QApplication(sys.argv)
mainwindowa = MainWindow()
mainwindowa.show()
sys.exit(app.exec_())
I want to create a splash screen in PyQt5 using Python. I searched but I found in Pyqt4 and I have no understanding of PyQt4 so help me in this case I would be gratful
Splash screen in pyqt
I like to add it in just before i load my main widget with a slight fade - note this is only useful to show a logo, if your application has a long load time you can utilise the splash screen like #S. Nick has shown to allow load time whilst you show the splashscreen:
from PyQt5 import QtGui, QtCore, QtWidgets
import time
if __name__ == '__main__':
app = QtWidgets.QApplication([])
# Create splashscreen
splash_pix = QtGui.QPixmap('picture.png')
splash = QtWidgets.QSplashScreen(splash_pix, QtCore.Qt.WindowStaysOnTopHint)
# add fade to splashscreen
opaqueness = 0.0
step = 0.1
splash.setWindowOpacity(opaqueness)
splash.show()
while opaqueness < 1:
splash.setWindowOpacity(opaqueness)
time.sleep(step) # Gradually appears
opaqueness+=step
time.sleep(1) # hold image on screen for a while
splash.close() # close the splash screen
#widget = YourWidget()
#widget.show() # This is where you'd run the normal application
app.exec_()
Try it:
import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QDialog, QPushButton, QVBoxLayout, QApplication, QSplashScreen
from PyQt5.QtCore import QTimer
class Dialog(QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.b1 = QPushButton('Display screensaver')
self.b1.clicked.connect(self.flashSplash)
layout = QVBoxLayout()
self.setLayout(layout)
layout.addWidget(self.b1)
def flashSplash(self):
self.splash = QSplashScreen(QPixmap('D:/_Qt/img/pyqt.jpg'))
# By default, SplashScreen will be in the center of the screen.
# You can move it to a specific location if you want:
# self.splash.move(10,10)
self.splash.show()
# Close SplashScreen after 2 seconds (2000 ms)
QTimer.singleShot(2000, self.splash.close)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Dialog()
main.show()
sys.exit(app.exec_())
Example 2
import sys
from PyQt5 import QtCore, QtGui, QtWidgets # + QtWidgets
import sys
from PyQt5.QtWidgets import QApplication, QLabel
from PyQt5.QtCore import QTimer, Qt
if __name__ == '__main__':
app = QApplication(sys.argv)
label = QLabel("""
<font color=red size=128>
<b>Hello PyQt, The window will disappear after 5 seconds!</b>
</font>""")
# SplashScreen - Indicates that the window is a splash screen. This is the default type for .QSplashScreen
# FramelessWindowHint - Creates a borderless window. The user cannot move or resize the borderless window through the window system.
label.setWindowFlags(Qt.SplashScreen | Qt.FramelessWindowHint)
label.show()
# Automatically exit after 5 seconds
QTimer.singleShot(5000, app.quit)
sys.exit(app.exec_())
The simple and best example that I found.
https://www.youtube.com/watch?v=TsatZJfzb_Q&t=162s
from PyQt5.QtWidgets import QMainWindow, QApplication, QDialog
from PyQt5.QtWidgets import QGraphicsScene,QSplashScreen
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
class SplashScreen(QSplashScreen):
def __init__(self):
super(QSplashScreen, self).__init__()
loadUi("splash.ui", self)
self.setWindowFlag(Qt.FramelessWindowHint)
pixmap = QPixmap("any_image.jpg")
self.setPixmap(pixmap)
def progress(self):
for i in range(40):
time.sleep(0.1)
self.progressBar.setValue(i)
class MainScreen(QMainWindow):
def function1():
.......
def function2():
......
if __name__ == "__main__":
app = QApplication(sys.argv)
splash = SplashScreen()
splash.show()
splash.progress()
mainscreen = MainScreen()
mainscreen.show()
splash.finish(widget)
sys.exit(app.exec_())
This example draws an ellipse in the main window. I would like to draw the ellipse in the secondary window as soon as I click the pushbutton in the main window. This, however, without having to create another class. I tried but I can't.
Another question: Is it possible to insert a geometric figure in a Box Layout?
#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QDialog
from PyQt5 import QtGui
from PyQt5.QtGui import QPainter,QBrush,QPen
from PyQt5 import QtCore
class Window(QMainWindow):
def __init__(self):
super().__init__()
title = "Main Window";left=100;top=100;width=1200;height=800
self.setWindowTitle(title)
self.setGeometry(left,top,width,height)
self.Create_Button()
self.show()
def Create_Button(self):
button = QPushButton("Click", self)
button.setGeometry(30,100,200,80)
button.clicked.connect(self.SecondWin)
def paintEvent(self,event):
painter = QPainter(self)
painter.setPen(QPen(QtCore.Qt.red,6,QtCore.Qt.SolidLine))
painter.setBrush(QBrush(QtGui.QColor(45,171,200),QtCore.Qt.SolidPattern))
painter.drawEllipse(550,150,300,600)
def SecondWin(self,event):
mydialog = QDialog(self)
mydialog.setWindowTitle("Second Window")
mydialog.setGeometry(400,200,600,300)
mydialog.show()
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec_())
I am trying to create plots with a Python GUI and gnuplot.
I am generating the code in Python and send it to gnuplot.
This basically works with piping data to gnuplot, but:
Disadvantages:
the Python program is blocked until you close gnuplot
you have to load/start gnuplot again and again everytime you're making a plot which seems to take annoying extra time (on slow computers)
My questions:
how to keep the Python program responsive?
is there a way to start gnuplot once and keep it running?
how to just update the gnuplot terminal if there is a new plot?
Thank you for hints and links.
Here is my code:
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPlainTextEdit, QPushButton
import subprocess
class MyWindow(QWidget):
def __init__(self):
super(MyWindow,self).__init__()
self.setGeometry(100,100,400,200)
self.myTextEdit = QPlainTextEdit()
self.myTextEdit.setPlainText("plot sin(x)")
self.button = QPushButton('Plot code',self)
self.button.clicked.connect(self.on_button_click)
vbox = QVBoxLayout(self)
vbox.addWidget(self.myTextEdit)
vbox.addWidget(self.button)
self.setLayout(vbox)
#pyqtSlot()
def on_button_click(self):
gnuplot_str = self.myTextEdit.document().toPlainText() + "\n"
gnuplot_path = r'C:\Programs\gnuplot\bin\gnuplot.exe'
plot = subprocess.Popen([gnuplot_path,'-p'],stdin=subprocess.PIPE)
plot.communicate(gnuplot_str.encode())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
Instead of using subprocess you must use QProcess which is friendly to the Qt event loop as I show below:
import sys
from PyQt5.QtCore import QProcess, pyqtSlot
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPlainTextEdit, QPushButton
class MyWindow(QWidget):
def __init__(self):
super(MyWindow,self).__init__()
self.setGeometry(100,100,400,200)
self.myTextEdit = QPlainTextEdit()
self.myTextEdit.setPlainText("plot sin(x)")
self.button = QPushButton('Plot code',self)
self.button.clicked.connect(self.on_button_click)
vbox = QVBoxLayout(self)
vbox.addWidget(self.myTextEdit)
vbox.addWidget(self.button)
gnuplot_path = r'C:\Programs\gnuplot\bin\gnuplot.exe'
self.process = QProcess(self)
self.process.start(gnuplot_path, ["-p"])
#pyqtSlot()
def on_button_click(self):
gnuplot_str = self.myTextEdit.document().toPlainText() + "\n"
self.process.write(gnuplot_str.encode())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
Is it possible to remove the divider line between two widgets that were added to the status bar using .addPermanentWidget()? I suspect that it is possible, but I haven't really found any literature on how to proceed.
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QStatusBar, QLabel
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
statusBar = QStatusBar()
self.setStatusBar(statusBar)
statusBar.addPermanentWidget(QLabel("Label: "))
statusBar.addPermanentWidget(QLabel("Data"))
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
In order to remove the divider between the two elements you need to set the stylesheet for QStatusBar::item in either Qt Creator, or the project source.
Qt Creator Example:
Project Source Example:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QStatusBar, QLabel
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
statusBar = QStatusBar()
statusBar.setStyleSheet('QStatusBar::item {border: None;}')
self.setStatusBar(statusBar)
statusBar.addPermanentWidget(QLabel("Label: "))
statusBar.addPermanentWidget(QLabel("Data"))
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Another way is to combine several widgets into one to group them, something like the C++ below:
QWidget *widget = new QWidget;
QLayout* layout = new QHBoxLayout(widget);
layout->setMargin(0);
QLabel *label = new QLabel;
label->setText("Recording status");
layout->addWidget(label);
QLabel *m_RecordingStatus = new QLabel;
m_RecordingStatus->setFrameShape(QFrame::Shape::Box);
m_RecordingStatus->setFixedWidth(100);
layout->addWidget(m_RecordingStatus);
ui.m_statusBar->addPermanentWidget(widget);
You can group associated widgets to be together between dividers.