SVG icons with PyQt on Windows and Linux - python

I have a PyQt user interface as follows
import sys
from PyQt4 import QtGui
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.setWindowTitle('Example')
self.setWindowIcon(QtGui.QIcon('note_add.svg'))
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
It works fine on Linux but it doesn't work well on Windows, because the SVG icon doesn't appear. I have two questions:
What is the proper way to use SVG icons with PyQt on Windows?
Is there a way to change the color fill of an SVG icon on the fly? This should work fine on both operating systems.

I know this is a few years late. But, better late than never. :)
For me, Qt works best when I define a specific directory. So, I'd implement this as so:
import sys
import os
from PyQt4 import QtGui
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
### Newly added code ###
self.current_directory = os.path.dirname(__file__)
self.note_icon = os.path.join( self.current_directory, 'note_add.svg' )
### ### ### ###
self.setWindowTitle('Example')
self.setWindowIcon(QtGui.QIcon(self.note_icon))
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Related

Why is my gif appearing only after my function finishes running [duplicate]

I have got this problem. I´m trying to set text on a lineEdit object on pyqt4, then wait for a few seconds and changing the text of the same lineEdit. For this I´m using the time.sleep() function given on the python Time module. But my problem is that instead of setting the text, then waiting and finally rewrite the text on the lineEdit, it just waits the time it´s supposed to sleep and only shows the final text. My code is as follows:
from PyQt4 import QtGui
from gui import *
class Ventana(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
self.button.clicked.connect(self.testSleep)
def testSleep(self):
import time
self.lineEdit.setText('Start')
time.sleep(2)
self.lineEdit.setText('Stop')
def mainLoop(self, app ):
sys.exit( app.exec_())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Ventana()
window.show()
sys.exit(app.exec_())
You can't use time.sleep here because that freezes the GUI thread, so the GUI will be completely frozen during this time.
You should probably use a QTimer and use it's timeout signal to schedule a signal for deferred delivery, or it's singleShot method.
For example (adapted your code to make it run without dependencies):
from PyQt4 import QtGui, QtCore
class Ventana(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setLayout(QtGui.QVBoxLayout())
self.lineEdit = QtGui.QLineEdit(self)
self.button = QtGui.QPushButton('clickme', self)
self.layout().addWidget(self.lineEdit)
self.layout().addWidget(self.button)
self.button.clicked.connect(self.testSleep)
def testSleep(self):
self.lineEdit.setText('Start')
QtCore.QTimer.singleShot(2000, lambda: self.lineEdit.setText('End'))
def mainLoop(self, app ):
sys.exit( app.exec_())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Ventana()
window.show()
sys.exit(app.exec_())
Also, take a look at the QThread sleep() function, it puts the current thread to sleep and allows other threads to run. https://doc.qt.io/qt-5/qthread.html#sleep
You can't use time.sleep here because that freezes the GUI thread, so the GUI will be completely frozen during this time.You can use QtTest module rather than time.sleep().
from PyQt4 import QtTest
QtTest.QTest.qWait(msecs)
So your code should look like:
from PyQt4 import QtGui,QtTest
from gui import *
class Ventana(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
self.button.clicked.connect(self.testSleep)
def testSleep(self):
import time
self.lineEdit.setText('Start')
QtTest.QTest.qWait(2000)
self.lineEdit.setText('Stop')
def mainLoop(self, app ):
sys.exit( app.exec_())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Ventana()
window.show()
sys.exit(app.exec_())

Can't use fcitx with self-written Qt app

I am learning pyqt5 and somehow I can't use fcitx in the text box created by QTextEdit or QLineEdit although fcitx works normally with other Qt apps like goldendict or kate. But later I found out that fcitx also doesn't work with another Qt app named Retext which uses Qt 5.10. Maybe this has something to do with the latest version of Qt or so I think.
Here's my code, just a simple textbox and nothing else:
import PyQt5.QtWidgets as QtWidgets
import sys
class App(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.text = QtWidgets.QTextEdit()
self.initUI()
def initUI(self):
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(self.text)
self.setLayout(vbox)
self.show()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Thanks to #ekhumoro, I know how to fix this. Just enable input method by adding this line to the __init__ function:
self.setAttribute(Qt.WA_InputMethodEnabled)
Then do this:
cp /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/fcitxplatforminputcontextplugin.so ~/.local/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforminputcontexts
sudo chmod +x ~/.local/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforminputcontexts/fcitxplatforminputcontextplugin.so

SetRootPath doesn't set work as expected

I have used part of a code (PyQt5) from this post
from PyQt5.QtWidgets import QTreeView,QFileSystemModel,QApplication
class Main(QTreeView):
def __init__(self):
QTreeView.__init__(self)
model = QFileSystemModel()
model.setRootPath('C:\\')
self.setModel(model)
self.doubleClicked.connect(self.test)
def test(self, signal):
file_path=self.model().filePath(signal)
print(file_path)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
And i have a problem with this line
model.setRootPath('C:\')
When i run the program it always shows drives like C: D: just not the content of C:\ or even if i type "C:\Users\" or a path that doesn't even exists, it always just shows, see attached image, What am i doing wrong?
Image of PyQt Program showing file manager
I am using:
Windows 10,
PyCharm,
Python 3.5,
PyQt5,
Thanks for your help.
You must indicate to the QTreeView what is your root item with setRootIndex():
from PyQt5.QtCore import QDir
from PyQt5.QtWidgets import QTreeView,QFileSystemModel,QApplication
class Main(QTreeView):
def __init__(self):
QTreeView.__init__(self)
model = QFileSystemModel()
self.setModel(model)
model.setRootPath(QDir.rootPath())
self.setRootIndex(model.index("C:"))
self.doubleClicked.connect(self.test)
def test(self, signal):
file_path=self.model().filePath(signal)
print(file_path)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())

PyQt: how to load multiple .ui Files from Qt Designer

I want to add startup window that when I click button, it will open another window and close current window. For each window, it has seperated UI which created from Qt Designer in .ui form.
I load both .ui file via uic.loadUiType(). The first window(first UI) can normally show its UI but when I click button to go to another window, another UI (second UI) doesn't work. It likes open blank window.
Another problem is if I load first UI and then change to second UI (delete that Class and change to another Class, also delete uic.loadUiType()), the second UI still doesn't work (show blank window)
Please help... I research before create this question but can't find the answer.
Here's my code. How can I fix it?
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
from PyQt5 import uic
#load both ui file
uifile_1 = 'UI/openPage.ui'
form_1, base_1 = uic.loadUiType(uifile_1)
uifile_2 = 'UI/mainPage.ui'
form_2, base_2 = uic.loadUiType(uifile_2)
class Example(base_1, form_1):
def __init__(self):
super(base_1,self).__init__()
self.setupUi(self)
self.startButton.clicked.connect(self.change)
def change(self):
self.main = MainPage()
self.main.show()
class MainPage(base_2, form_2):
def __int__(self):
super(base_2, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
First you have an error, you must change __int__ to __init__. To close the window call the close() method.
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
from PyQt5 import uic
#load both ui file
uifile_1 = 'UI/openPage.ui'
form_1, base_1 = uic.loadUiType(uifile_1)
uifile_2 = 'UI/mainPage.ui'
form_2, base_2 = uic.loadUiType(uifile_2)
class Example(base_1, form_1):
def __init__(self):
super(base_1,self).__init__()
self.setupUi(self)
self.startButton.clicked.connect(self.change)
def change(self):
self.main = MainPage()
self.main.show()
self.close()
class MainPage(base_2, form_2):
def __init__(self):
super(base_2, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

PYQT Adding extra menu items to an existing UI before it opens

Hi I have designed a basic GUI in QT and created a .py file from it.
When the window starts up I want to add another menu item. I have tried a few pieces of code I found on google but nothing seems to work. The code will need to go in the method addAdminMenu()
from PyQt4 import QtGui
import sys
from supplypy.core.windows.main_window import Ui_MainWindow
class SRM(QtGui.QWidget):
def __init__(self):
self.app = QtGui.QApplication(sys.argv)
self.MainWindow = QtGui.QMainWindow()
self.ui = Ui_MainWindow()
self.ui.setupUi(self.MainWindow)
self.MainWindow.show()
sys.exit(self.app.exec_())
def addAdminMenu(self):
pass
#####Add code here to create a Admin menu####
if __name__ == '__main__':
srm = SRM()
It should be as simple as accessing the menuBar() of the QMainWindow and adding an item, for example: (I removed the Ui_MainWindow lines just because I don't know what it's for -- a Windows requirement?)
from PyQt4 import QtGui
import sys
class SRM(QtGui.QWidget):
def __init__(self):
self.app = QtGui.QApplication(sys.argv)
self.MainWindow = QtGui.QMainWindow()
self.menubar = self.MainWindow.menuBar()
self.MainWindow.show()
self.addAdminMenu()
sys.exit(self.app.exec_())
def addAdminMenu(self):
self.menubar.addMenu('&Admin');
if __name__ == '__main__':
srm = SRM()

Categories

Resources