2

I am trying to make my first program. I'm hoping for custom dark mode design, and that requires me to make a custom title bar. I copied the code for the title bar from someone else, it worked perfectly - custom movable window. I have carefully merged it with my previous code, though title bar doesn't appear. Now my guess is I have to call it at the end of my code, but it ends up with errors, as I'm not sure how to properly call it.

Note: removing the QtCore.Qt.FramelessWindowHint part is NOT the answer, as it just brings back the stock Win title bar, that's supposed to be hidden and replaced by dark title bar.

Part of code copied from: https://stackoverflow.com/a/44249552/12221725

Image:

IMAGE _ THE look im aiming at

import sys
from PyQt5 import QtGui, QtCore
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QTextEdit

#fCol = "#e0e0e0"
#bCol = "#212121"

class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.layout = QHBoxLayout()
        self.textArea = QTextEdit("Lorem ipsum...")
        self.layout.addWidget(self.textArea)
        self.textArea.setStyleSheet("QTextEdit {color:white;background-color:#212121;border-radius:+16px;}")
        self.sans = QFont("Segoe UI",20)
        self.textArea.setFont(self.sans)
        self.btnLayout = QVBoxLayout()
        self.btnLayout.addWidget(QPushButton("Open"))
        self.btnLayout.addWidget(QPushButton("Setup"))
        self.btnLayout.addWidget(QPushButton("Find"))
        self.setStyleSheet("QPushButton {max-width:200px;color:#4fc3f7;background-color:#424242;border:2px solid #4fc3f7;border-radius:16px;font-size:35px;font-weight:bold;}" + "QPushButton:hover {color:#212121;background-color:#4fc3f7;}" + "QPushButton:pressed {color:white;background-color:#212121;border-color:white;}")
        self.status = QTextEdit()
        self.status.insertPlainText("Successfully loaded" + "\nOpen a file...")
        self.status.setReadOnly(1)
        self.status.setStyleSheet("QTextEdit {color:white;background-color:#212121;border-radius:+16px;font-size:14px;max-width:200px;}")
        self.btnLayout.addWidget(self.status)
        self.layout.addLayout(self.btnLayout)
        self.setLayout(self.layout)
        #self.setFixedSize(650, 320)
        self.setFixedSize(800, 400)
        self.setWindowTitle("Py Program")
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)# | QtCore.Qt.WindowStaysOnTopHint)
        #self.layout.setContentsMargins(0,0,0,0)
        #self.layout.addStretch(-1)
        #self.pressing = False
        print("MainWindow Loaded")
        #self.show()



class MyBar(QWidget):

    def __init__(self, parent):
        super(MyBar, self).__init__()
        self.parent = parent
        print(self.parent.width())
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.title = QLabel("My Own Bar")

        btn_size = 35

        self.btn_close = QPushButton("x")
        self.btn_close.clicked.connect(self.btn_close_clicked)
        self.btn_close.setFixedSize(btn_size,btn_size)
        self.btn_close.setStyleSheet("background-color: red;")

        self.btn_min = QPushButton("-")
        self.btn_min.clicked.connect(self.btn_min_clicked)
        self.btn_min.setFixedSize(btn_size, btn_size)
        self.btn_min.setStyleSheet("background-color: gray;")

        self.btn_max = QPushButton("+")
        self.btn_max.clicked.connect(self.btn_max_clicked)
        self.btn_max.setFixedSize(btn_size, btn_size)
        self.btn_max.setStyleSheet("background-color: gray;")

        self.title.setFixedHeight(35)
        self.title.setAlignment(Qt.AlignCenter)
        self.layout.addWidget(self.title)
        self.layout.addWidget(self.btn_min)
        self.layout.addWidget(self.btn_max)
        self.layout.addWidget(self.btn_close)

        self.title.setStyleSheet("background-color: black;color: white;")
        self.setLayout(self.layout)

        self.start = QPoint(0, 0)
        self.pressing = False
        print("MyBar Loaded")


    def resizeEvent(self, QResizeEvent):
        super(MyBar, self).resizeEvent(QResizeEvent)
        self.title.setFixedWidth(self.parent.width())

    def mousePressEvent(self, event):
        self.start = self.mapToGlobal(event.pos())
        self.pressing = True

    def mouseMoveEvent(self, event):
        if self.pressing:
            self.end = self.mapToGlobal(event.pos())
            self.movement = self.end-self.start
            self.parent.setGeometry(self.mapToGlobal(self.movement).x(),
                                self.mapToGlobal(self.movement).y(),
                                self.parent.width(),
                                self.parent.height())
            self.start = self.end

    def mouseReleaseEvent(self, QMouseEvent):
        self.pressing = False


    def btn_close_clicked(self):
        self.parent.close()

    def btn_max_clicked(self):
        self.parent.showMaximized()

    def btn_min_clicked(self):
        self.parent.showMinimized()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setWindowIcon(QtGui.QIcon("icon.png"))
    app.setStyleSheet("QWidget {background-color:#424242;border-radius:12px;}")
    app.setFont(QFont("Consolas"))
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 1) do not create a new post with the same question, 2) You must use `@username` to notify me of your message, 3) be patient, if I did not reopen it I would reopen the community. – eyllanesc Aug 03 '20 at 18:49
  • Since it took little time to mark this as a duplicate, and long time to get additional response, I thought this post was buried. I took my time to make sure the second post would contain more information to differentiate from the "original" post. Thx for reopening – bielo vymaľovaná stena Aug 03 '20 at 18:53

1 Answers1

1

The problem is that you have not created or placed a Bar() inside the window. You must also restructure your layout so that the titlebar is displayed at the top and your content at the bottom using a QVBoxLayout.

On the other hand I have improved the original titleBar so that it is not necessary to set the parent directly but instead use the window():

import sys
from PyQt5.QtGui import QFont, QIcon
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QTextEdit, QLabel

class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowFlags(Qt.FramelessWindowHint)

        hlayout = QHBoxLayout()
        self.textArea = QTextEdit("Lorem ipsum...")
        hlayout.addWidget(self.textArea)
        self.textArea.setStyleSheet("QTextEdit {color:white;background-color:#212121;border-radius:+16px;}")
        self.sans = QFont("Segoe UI",20)
        self.textArea.setFont(self.sans)
        self.btnLayout = QVBoxLayout()
        self.btnLayout.addWidget(QPushButton("Open"))
        self.btnLayout.addWidget(QPushButton("Setup"))
        self.btnLayout.addWidget(QPushButton("Find"))
        self.setStyleSheet("QPushButton {max-width:200px;color:#4fc3f7;background-color:#424242;border:2px solid #4fc3f7;border-radius:16px;font-size:35px;font-weight:bold;}" + "QPushButton:hover {color:#212121;background-color:#4fc3f7;}" + "QPushButton:pressed {color:white;background-color:#212121;border-color:white;}")
        self.status = QTextEdit()
        self.status.insertPlainText("Successfully loaded" + "\nOpen a file...")
        self.status.setReadOnly(1)
        self.status.setStyleSheet("QTextEdit {color:white;background-color:#212121;border-radius:+16px;font-size:14px;max-width:200px;}")
        self.btnLayout.addWidget(self.status)
        self.setFixedSize(800, 400)
        self.setWindowTitle("Py app")
        hlayout.addLayout(self.btnLayout)
        
        custom_titlebar = TitleBar()

        lay = QVBoxLayout(self)
        lay.addWidget(custom_titlebar)
        lay.addLayout(hlayout)



class TitleBar(QWidget):
    def __init__(self, parent=None):
        super(TitleBar, self).__init__(parent)
 
        self.title = QLabel("My Own Bar")

        btn_size = 35

        self.btn_close = QPushButton("x")
        self.btn_close.clicked.connect(self.btn_close_clicked)
        self.btn_close.setFixedSize(btn_size,btn_size)
        self.btn_close.setStyleSheet("background-color: red;")

        self.btn_min = QPushButton("-")
        self.btn_min.clicked.connect(self.btn_min_clicked)
        self.btn_min.setFixedSize(btn_size, btn_size)
        self.btn_min.setStyleSheet("background-color: gray;")

        self.btn_max = QPushButton("+")
        self.btn_max.clicked.connect(self.btn_max_clicked)
        self.btn_max.setFixedSize(btn_size, btn_size)
        self.btn_max.setStyleSheet("background-color: gray;")

        self.title.setFixedHeight(35)
        self.title.setAlignment(Qt.AlignCenter)
        self.title.setStyleSheet("background-color: black;color: white;")

        lay = QHBoxLayout(self)
        lay.setContentsMargins(0,0,0,0)

        lay.addWidget(self.title)
        lay.addWidget(self.btn_min)
        lay.addWidget(self.btn_max)
        lay.addWidget(self.btn_close)

        self.pressing = False
        self.dragPosition = QPoint()

    def resizeEvent(self, QResizeEvent):
        super(TitleBar, self).resizeEvent(QResizeEvent)
        self.title.setFixedWidth(self.window().width())

    def mousePressEvent(self, event):
        self.start = event.globalPos()
        self.pressing = True

    def mouseMoveEvent(self, event):
        if self.pressing:
            self.end = event.globalPos()
            delta = self.end - self.start
            self.window().move(self.window().pos() + delta)
            self.start = self.end

    def mouseReleaseEvent(self, QMouseEvent):
        self.pressing = False


    def btn_close_clicked(self):
        self.window().close()

    def btn_max_clicked(self):
        self.window().showMaximized()

    def btn_min_clicked(self):
        self.window().showMinimized()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon("icon.png"))
    app.setStyleSheet("QWidget {background-color:#424242;border-radius:12px;}")
    app.setFont(QFont("Consolas"))
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thanks, this is a solution that I'll probably end up using, however, it doesn't answer what went wrong while merging my code with the one from StackOv. As I said in my post, it seems that in my code, the title bar class doesn't get called at all. I'm curious why. – bielo vymaľovaná stena Aug 03 '20 at 19:05
  • 2
    @bielovymaľovanástena mmm, I don't understand you, have you used my code? Have you read my answer ?, I point there because your code does not work and how it should be solved: *The problem is that you have not created or placed a Bar() inside the window* – eyllanesc Aug 03 '20 at 19:09
  • Thanks, I looked at your code but I focused on the bottom part of the code... Now I see you've written Bar() in your post, I must have read it simply as bar. With that, this is finally solved, much thanks – bielo vymaľovaná stena Aug 03 '20 at 19:20