Search code examples
pythonpyqt5focusborder

How can I remove the dotted border around the tab in focus in a multi-tabbed PyQt5 window?


I have built a multi-tab window using PyQt5. Each tab has a thin dotted border when in focus:

enter image description here

How do I remove this dotted border? (My operating system is Windows 10 if that matters.)

Here is the Python code that generates the above window:

from PyQt5.QtWidgets import QTabWidget, QWidget, QVBoxLayout, QApplication
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from numpy.random import rand
from sys import argv, exit

class mainWindow(QTabWidget):
    def __init__(self, parent = None):
        super(mainWindow, self).__init__(parent)

        # Create tab1
        self.tab1 = QWidget()
        self.addTab(self.tab1,"Tab 1")
        self.figure = plt.figure()
        self.canvas = FigureCanvasQTAgg(self.figure)
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        self.tab1.setLayout(layout)
        self.plot()

        # Create tab2
        self.tab2 = QWidget()
        self.addTab(self.tab2,"Tab 2")
        self.figure = plt.figure()
        self.canvas = FigureCanvasQTAgg(self.figure)
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        self.tab2.setLayout(layout)
        self.plot()

    def plot(self):
        data = rand(10)
        ax = self.figure.add_subplot(111)
        ax.plot(data, '*-')
        self.canvas.draw()

app = QApplication(argv)
main = mainWindow()
main.show()
exit(app.exec_())

Several Stack Overflow questions like this, this, and this one seem to suggest that the border might be removed by adding a line like

self.tab1.setFocusPolicy(QtCore.Qt.NoFocus)

or

self.tab1.setStyleSheet("QTableView:{outline: 0;}")

somewhere in the above code. However, I have not yet found a way to do this that succeeds in removing the dotted border.


Solution

  • Migrating the solution OP found useful from a comment to an answer:

    Setting the focus policy should be enough, but you called it on the wrong widget: you need to clear the policy for the tab widget, not its content. You should also ensure that another widget properly gets the focus. So, change to self.setFocusPolicy(QtCore.Qt.NoFocus) and add something like self.tab1.setFocus().

    musicamante commented Jan 22 at 19:22

    Remember, though, that PyQt is a binding: it's quite important to separate what happens on the Python side and on the "C++" (Qt) side. In this case, the problem had nothing to do with Python, but with how Qt works. Specifically, the self refers not only to the mainWindow instance, but also to the wrapped QTabWidget object in Qt (the Python binding will automatically try to "forward" the calls of its API to the related Qt object). Similarly, self.tab1 also refers to the actual QWidget added to the tab widget. Understanding that relation is very important.

    musicamante commented Jan 24 at 3:33