I'm trying to set my tabs "Closable", however I can't see the close button icon on individual tabs when using PyQt5 and "Fusion" style:
When I set "Windows" style I can see:
I already tried to use styleSheet qtabbar button but it didn't work:
QTabBar::close-button {
image: url(close.png);
subcontrol-position: left;
}
This is my code:
#!/bin/python3
import sys
from PyQt5.QtWidgets import (QApplication, QVBoxLayout,
QTabBar, QFrame)
class App(QFrame):
def __init__(self):
super().__init__()
self.setWindowTitle("Web Browser")
self.setBaseSize(683, 384)
self.CreateApp()
def CreateApp(self):
self.layout = QVBoxLayout()
self.tab_Bar = QTabBar(movable=True, tabsClosable=True)
self.tab_Bar.tabCloseRequested.connect(self.CloseTab)
self.tab_Bar.addTab("Tab 1")
self.tab_Bar.addTab("Tab 2")
self.tab_Bar.setCurrentIndex(0)
self.layout.addWidget(self.tab_Bar)
self.setLayout(self.layout)
self.show()
def CloseTab(self, i):
self.tab_Bar.removeTab(i)
if __name__ == "__main__":
QApplication.setStyle('Fusion')
app = QApplication(sys.argv)
window = App()
sys.exit(app.exec_())
I'm using Python version 3.6.2 and PyQt5 version 5.10.
What could be the root cause of this problem? Maybe my system is lacking some icons in Fusion style?
Similar question can be found here. Though it does not have an official answer, there are some suggestions in comments. Do check them. Since it is working for "Windows" and not for "Fusion", can be a bug in QT5.
Related
I am currently exploring the possibilities of displaying and working with PowerPoint presentations in a GUI using PyQt5/PyQt6 and Python. For that I found the most promising solution to be using a QAxWidget. Loading and displaying the pptx-file works fine, but unfortunately I noticed glitches when resizing the window of the GUI.
As a minimal example I used the following tutorial from the official Qt docs:
https://doc.qt.io/qtforpython/examples/example_axcontainer__axviewer.html?highlight=qaxwidget
After the QAxWidget()-initialization i just added the following line:
self.axWidget.setControl(r"C:\path\to\file\presentation.pptx")
Full code (taken from: https://doc.qt.io/qtforpython/examples/example_axcontainer__axviewer.html?highlight=qaxwidget):
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""PySide6 Active Qt Viewer example"""
import sys
from PyQt5.QtWidgets import qApp
from PySide6.QtAxContainer import QAxSelect, QAxWidget
from PySide6.QtGui import QAction
from PySide6.QtWidgets import (QApplication, QDialog,
QMainWindow, QMessageBox, QToolBar)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
toolBar = QToolBar()
self.addToolBar(toolBar)
fileMenu = self.menuBar().addMenu("&File")
loadAction = QAction("Load...", self, shortcut="Ctrl+L", triggered=self.load)
fileMenu.addAction(loadAction)
toolBar.addAction(loadAction)
exitAction = QAction("E&xit", self, shortcut="Ctrl+Q", triggered=self.close)
fileMenu.addAction(exitAction)
aboutMenu = self.menuBar().addMenu("&About")
aboutQtAct = QAction("About &Qt", self, triggered=qApp.aboutQt)
aboutMenu.addAction(aboutQtAct)
self.axWidget = QAxWidget()
self.axWidget.setControl(r"C:\path\to\file\presentation.pptx")
self.setCentralWidget(self.axWidget)
def load(self):
axSelect = QAxSelect(self)
if axSelect.exec() == QDialog.Accepted:
clsid = axSelect.clsid()
if not self.axWidget.setControl(clsid):
QMessageBox.warning(self, "AxViewer", f"Unable to load {clsid}.")
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
availableGeometry = mainWin.screen().availableGeometry()
mainWin.resize(availableGeometry.width() / 3, availableGeometry.height() / 2)
mainWin.show()
sys.exit(app.exec())
When resizing the window of the GUI, there appear some glitches underneath:
An animation that shows the result while resizing:
Unfortunately I haven't found many resources I could use where a QAxWidget is used in combination with Python to figure this out myself. That's why I'm here to ask if anyone out there might have a solution for getting rid of those glitches.
I got rid of the glitches by installing an event filter to the QAxWidget using self.axWidget.installEventFilter(self).
This will call the eventFilter()-method of the QMainWindow which I set up like this: (ReportDefinitionTool is the subclass of QMainWindow here.)
def eventFilter(self, widget: QWidget, event: QEvent):
if event.type() == QEvent.Resize and widget is self.pptx_axwidget:
self.pptx_axwidget.setFixedHeight(int(self.pptx_axwidget.width() / 16 * 9))
return super(ReportDefinitionTool, self).eventFilter(widget, event)
Since the PowerPoint-presentation is displayed in a 16:9 format, this will make sure the QAxWidget does only occupy this space. The glitchy space from the initial question came from the unused space of the QAxWidget.
I am trying to create a GUI for my python program. One of the tools that I need is a text input box.
Now, I want a text label for this box saying "Please insert texts." Is there a function to add a label that shows inside the input textbox as default and disappear when user click the box to type?
I don't mind to use qt designer or pyqt5 coding.
Thank you guys.
placeholderText : QString
This property holds the line edit's placeholder text
import sys
from PyQt5.QtWidgets import QLineEdit, QVBoxLayout, QApplication, QWidget
class Test(QWidget):
def __init__(self):
super().__init__()
self.lineEdit = QLineEdit(placeholderText="Please insert texts.") # <---
vbox = QVBoxLayout(self)
vbox.addWidget(self.lineEdit)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec_())
I am begginer like you and my English is not so good. But I recommend you use Qt Designer. It's easier, fastter for you draw your app. I am using pyside2 project and recommend you read docummentatio each widgets you wanna use in PySide2 project and Qt Project. Try code below
enter image description here
import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog
from PySide2.QtWidgets import QTextEdit
from PySide2.QtWidgets import QVBoxLayout
from PySide2.QtCore import Qt
class MainDialog(QDialog):
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
# Create Widget TextEdit
self.text = QTextEdit()
# I think that you wanna this function in your program
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setPlaceholderText
# http://doc.qt.io/qt-5/qlineedit.html#placeholderText-prop
self.text.setPlaceholderText('''Yes! this is exactly what I want!
Thank you, what if you have a big text box (more than 10 lines) and
you want to scale up the place holder and align it in center?? ''')
# https://doc.qt.io/qtforpython/PySide2/QtWidgets/QLineEdit.html?highlight=qlineedit#PySide2.QtWidgets.PySide2.QtWidgets.QLineEdit.setAlignment
# http://doc.qt.io/qt-5/qlineedit.html#alignment-prop
self.text.setAlignment(Qt.AlignCenter)
# Layout
layout = QVBoxLayout()
layout.addWidget(self.text)
self.setLayout(layout)
def main():
app = QApplication()
mainDialog = MainDialog()
mainDialog.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I've just came across QDockWidgets. And I am blown away with the flexibility these widgets offer. But it appears they do require a proper planning ahead.
I put a simple example here:
import sys
from PyQt4 import QtCore, QtGui
class GUI(QtGui.QMainWindow):
def __init__(self):
super(GUI, self).__init__()
mainWidget=QtGui.QWidget()
self.setCentralWidget(mainWidget)
mainLayout = QtGui.QVBoxLayout()
mainWidget.setLayout(mainLayout)
DockA = QtGui.QDockWidget('DockA')
DockB = QtGui.QDockWidget('DockB')
mainLayout.addWidget(DockA)
mainLayout.addWidget(DockB)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
dialog = GUI()
dialog.show()
dialog.raise_()
sys.exit(app.exec_())
First I am subclassing QMainWindow. Then QWidget is created. Then assigning it as central via .setCentralWidget(). Next QVBoxLayout() is created and set to mainWidget.
Now creating DockA and DockB. Dialog shows up. But docks are not movable.
What I am doing wrong here?
From the official documentation:
QDockWidget provides the concept of dock widgets, also know as tool palettes or
utilitywindows. Dock windows are secondary windows placed in the
"dock widget area" around the central widget in a QMainWindow
Please refer to the detailed description here and an example here. It is in C++ but you can get an idea of how to do things.
You should use the addDockWidget method of QMainWindow to get fully functional movable dock windows.
Example:
from PySide import QtCore, QtGui
app = QtGui.QApplication([])
window = QtGui.QMainWindow()
window.setCentralWidget(QtGui.QLabel('MainWidget'))
window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, QtGui.QDockWidget('DockA'), QtCore.Qt.Vertical)
window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, QtGui.QDockWidget('DockB'), QtCore.Qt.Vertical)
window.show()
app.exec_()
is there a way in PySide to style the tab buttons on the QtabWidget? I'm right now trying to make a costum styled widget, and I've styled every other element, but I can't seem to figure out how to style the QtabWidget...
I was trying:
self.tabWidget = QtGui.QtabWidget(Form)
self.tabWidget.tab.setStyleSheet("some style goes here")
but I now know I cant reference the tab like that. any help on this would be greatly appreciated.
You are looking for the QTabBar::tab subcontrol.
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtGui, QtCore
class MyWindow(QtGui.QTabWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.setStyleSheet("""
QTabBar::tab {
color: #FF0000;
}
""")
for tabNumber in range(3):
widget = QtGui.QLabel(self)
widget.setText("This is widget #{0}".format(tabNumber))
self.addTab(widget, "Tab {0}".format(tabNumber))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
I am creating a custom widget my_widget inheriting from QWidget.
Here, I have a label to which I would like to apply QGraphicsDropShadowEffect however it does not seem to be working since I don't see any shadows.
My code is in Python and it's:
eff = QGraphicsDropShadowEffect()
self.my_widget_label.setGraphicsEffect(eff)
I tried various alterations to this code to no avail.
After doing a through search on Google, I came across many similar questions without answers.
What might be the cause? How can I get the shadow?
Works for me in C++. I did the following in a QDialog containing a QLabel object named titleLabel. I'm using Qt 4.8.4 on a Windows XP computer.
QGraphicsDropShadowEffect* eff = new QGraphicsDropShadowEffect(this);
eff->setBlurRadius(5);
titleLabel->setGraphicsEffect(eff);
See if this works for you:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class testShadow(QWidget):
def __init__(self, parent=None):
super(testShadow, self).__init__(parent)
self.resize(94, 35)
self.verticalLayout = QVBoxLayout(self)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QLabel(self)
self.label.setText("Text Label")
self.shadow = QGraphicsDropShadowEffect(self)
self.shadow.setBlurRadius(5)
self.label.setGraphicsEffect(self.shadow)
self.verticalLayout.addWidget(self.label)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = testShadow()
main.show()
sys.exit(app.exec_())
I have only every tried to use this (and used it successfully) in QGraphicsScene situations. This works for me, while trying to set it on a normal QWidget actually crashes the entire application:
from PyQt4 import QtGui
class Graphics(QtGui.QWidget):
def __init__(self):
super(Graphics, self).__init__()
layout = QtGui.QVBoxLayout(self)
layout.setMargin(0)
shad = QtGui.QGraphicsDropShadowEffect(self)
shad.setBlurRadius(5)
self.scene = QtGui.QGraphicsScene(self)
self.view = QtGui.QGraphicsView(self)
self.view.setScene(self.scene)
text = self.scene.addText("Drop Shadow!")
text.setGraphicsEffect(shad)
layout.addWidget(self.view)
if __name__ == "__main__":
app = QtGui.QApplication([])
main = Graphics()
main.show()
main.raise_()
app.exec_()