使用PyQt5创建时间轴

问题描述 投票:0回答:1

我正在用Python和PyQt5开始一个项目。我想有一个这样的时间线小部件

所以将来我希望每个矩形都是一个按钮,但我现在的主要问题是让时间轴坚持我的窗口宽度。

目前,我的时间轴继承自QFrame,每个矩形也是QFrame。那么它是一个很好的方法吗?有没有更好的方法呢?

这是我尝试过的:

main.朋友

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt5.QtGui import QColor
from Timeline import *
from Job import *

class FreelanceAssistant(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.resize(1080, 720)
        self.move(300, 300)
        self.setWindowTitle("Freelance Assistant")
        p = self.palette()
        p.setColor(self.backgroundRole(), QColor(32, 47, 60))
        self.setPalette(p)

        timeline = Timeline(self)

        timeline.addJob(Job(QDate(2017, 11, 21), QDate(2018, 1, 12), "Red Knuckles", 200, QColor(140, 67, 67)))
        timeline.addJob(Job(QDate(2018, 1, 15), QDate(2018, 1, 26), "ETC", 200, QColor(67, 76, 140)))

        window_layout= QVBoxLayout()
        print(self.getContentsMargins())
        self.setLayout(window_layout)
        window_layout.addWidget(timeline)

        self.show()

def main():
    app = QApplication(sys.argv)
    window = FreelanceAssistant()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

timeline.朋友

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtCore import QDate
from PyQt5.QtWidgets import QFrame, QLabel
from PyQt5.QtGui import QColor

class Timeline(QFrame):
    def __init__(self, parent):
        super().__init__(parent)

        self.jobs_number = 0

        self.setGeometry(0, 0, parent.width(), 200)
        self.setStyleSheet("QWidget { background-color: %s }" %  QColor(26, 36, 45).name())

        self.__invoice_pos = self.height() * 0.5
        self.__invoice_height = 13
        self.__job_top_pos = self.height() * 0.5 + self.__invoice_height
        self.__job_height = (self.height() - self.__job_top_pos)/2
        self.__job_bottom_pos = self.__job_top_pos + self.__job_height

        line1 = QFrame(parent)
        line1.setGeometry(0, self.height() * 0.5, self.width(), 1)
        line1.setStyleSheet("QWidget { background-color: %s }" %  QColor(66, 76, 85).name())

        line2 = QFrame(parent)
        line2.setGeometry(0, self.height(), self.width(), 1)
        line2.setStyleSheet("QWidget { background-color: %s }" %  QColor(66, 76, 85).name())

        self.__starts_on = QDate.currentDate().addMonths(-1)
        self.__ends_on = QDate.currentDate().addMonths(5)
        self.__days_range = self.__starts_on.daysTo(self.__ends_on)

        current_year = QLabel(str(self.__starts_on.year()), parent)
        current_year.move(5, self.height() + 5)
        current_year.setStyleSheet("QWidget { color: %s }" %  QColor(245, 245, 245).name())

        for year in range(self.__starts_on.year() + 1, self.__ends_on.year() + 1):
            days_to_new_year = self.__starts_on.daysTo(QDate(year, 1, 1))
            new_year_line_pos = days_to_new_year/self.__days_range * self.width()

            new_year_line = QFrame(parent)
            new_year_line.setGeometry(int(new_year_line_pos), 0, 1, self.height() + 20)
            new_year_line.setStyleSheet("QWidget { background-color: %s }" %  QColor(245, 245, 245).name())

            current_year = QLabel(str(year), parent)
            current_year.move(int(new_year_line_pos) + 5, self.height() + 5)
            current_year.setStyleSheet("QWidget { color: %s }" %  QColor(245, 245, 245).name())

        invoice_start = QDate(2017, 11, 21)
        invoice_end = QDate(2017, 12, 13)

        invoice_start_pos = self.__starts_on.daysTo(invoice_start)/self.__days_range * self.width()
        invoice_width = invoice_start.daysTo(invoice_end)/self.__days_range * self.width()

        invoice_frame = QFrame(self)
        invoice_frame.setGeometry(invoice_start_pos, self.__invoice_pos, invoice_width, self.__invoice_height)
        invoice_frame.setStyleSheet("QWidget { background-color: %s }" %  QColor(50, 200, 50).name())

        invoice_end_date = QLabel(invoice_end.toString("dd MMM"), invoice_frame)
        invoice_end_date.move(invoice_frame.width() - 40, 0)
        invoice_end_date.setStyleSheet("QWidget { color: %s }" %  QColor(0, 0, 0).name())

    def addJob(self, job):
        start_pos = self.__starts_on.daysTo(job.starts_on)/self.__days_range * self.width()
        width = job.days_range/self.__days_range * self.width()

        job_frame = QFrame(self)
        if self.jobs_number % 2 == 0:
            job_frame.setGeometry(start_pos, self.__job_bottom_pos, width, self.__job_height)
        else:
            job_frame.setGeometry(start_pos, self.__job_top_pos, width, self.__job_height)
        job_frame.setStyleSheet("QWidget { background-color:" + job.color.name() + " } QWidget:hover{background-color: " + job.color.darker(125).name() + "}")

        company_name = QLabel(job.company, job_frame)
        company_name.move(5, 5)
        company_name.setStyleSheet("QWidget { color: %s }" %  QColor(245, 245, 245).name())

        start_date = QLabel(job.starts_on.toString("dd MMM"), job_frame)
        start_date.move(5, job_frame.height() - 20)
        start_date.setStyleSheet("QWidget { color: %s }" %  QColor(245, 245, 245).name())

        end_date = QLabel(job.ends_on.toString("dd MMM"), job_frame)
        end_date.move(job_frame.width() - 40, job_frame.height() - 20)
        end_date.setStyleSheet("QWidget { color: %s }" %  QColor(245, 245, 245).name())

        self.jobs_number += 1

job.朋友

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtCore import QDate
from PyQt5.QtGui import QColor

class Job():
    def __init__(self, start, end, company, rate, color):
        self.starts_on = start
        self.ends_on = end
        self.company = company
        self.rate = rate
        self.color = color
        self.days_range = self.starts_on.daysTo(self.ends_on)
python pyqt pyqt5 timeline
1个回答
0
投票

这种情况的一个简单解决方案是覆盖resizeEvent()方法,每次窗口小部件调整大小时调用该方法,因此我们利用该方法更改line1line2的宽度,但是这样可以从该方法访问这些QLabel必须是班级的成员,为此你必须将line1line2改为self.line1self.line2

class Timeline(QFrame):
    def __init__(self, parent):
        super().__init__(parent)

        [...]

        self.line1 = QFrame(self)
        self.line1.setGeometry(0, self.height() * 0.5, self.width(), 1)
        self.line1.setStyleSheet("QWidget { background-color: %s }" %  QColor(66, 76, 85).name())

        self.line2 = QFrame(self)
        self.line2.setGeometry(0, self.height(), self.width(), 1)
        self.line2.setStyleSheet("QWidget { background-color: %s }" %  QColor(66, 76, 85).name())

        [...]

    def resizeEvent(self, event):
        for line in [self.line1, self.line2]:
            line.resize(self.width(), line.size().height())
        QFrame.resizeEvent(self, event)
© www.soinside.com 2019 - 2024. All rights reserved.