我有一个网格布局,可以毫无问题地创建网格。
我从A-J创建了与网格重合的按钮。
当前显示为:
我想布置A-J按钮以与网格相对应。
如何在PyQt5中实现此布局?
import sys
from PyQt5.QtWidgets import QLabel, QStyle, QApplication, QWidget, QPushButton, QHBoxLayout, QGroupBox, QDialog, QVBoxLayout, QGridLayout
from PyQt5.QtGui import QPen, QPainter, QFont, QIcon, QPixmap, QPalette, QLinearGradient, QColor, QBrush, QCursor
from PyQt5.QtCore import pyqtSlot, Qt
grid = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]
BTN ='font-weight: bold; color: {};font-size: 14px; background-color: {}; padding: 20px;border-width: 2px; border-radius: 50px;'
class _QPushButton(QPushButton):
def __init__(self, parent=None):
super(_QPushButton, self).__init__(parent)
self.setCursor(QCursor(Qt.PointingHandCursor))
class App(QDialog):
def __init__(self):
super().__init__()
self.left = 10
self.top = 10
self.width = 1200
self.height = 800
self.initUI()
def initUI(self):
# Background
p = QPalette()
gradient = QLinearGradient(0, 0, 0, 400)
gradient.setColorAt(0.0, QColor('#f1f1f1'))
gradient.setColorAt(1.0, QColor('#00a1de'))
p.setBrush(QPalette.Window, QBrush(gradient))
self.setPalette(p)
self.setGeometry(self.left, self.top, self.width, self.height)
self.btnA = _QPushButton('A')
self.btnB = _QPushButton('B')
self.btnC = _QPushButton('C')
self.btnD = _QPushButton('D')
self.btnE = _QPushButton('E')
self.btnF = _QPushButton('F')
self.btnG = _QPushButton('G')
self.btnH = _QPushButton('H')
self.btnI = _QPushButton('I')
self.btnJ = _QPushButton('J')
self.createGridLayout()
windowLayout = QHBoxLayout()
for i in range(len(grid[0])):
print(i)
lbl = QLabel()
lbl.setText(str(i+1))
windowLayout.addWidget(lbl)
windowLayout.addWidget(self.btnA)
windowLayout.addWidget(self.btnB)
windowLayout.addWidget(self.btnC)
windowLayout.addWidget(self.btnD)
windowLayout.addWidget(self.btnE)
windowLayout.addWidget(self.btnF)
windowLayout.addWidget(self.btnG)
windowLayout.addWidget(self.btnH)
windowLayout.addWidget(self.btnI)
windowLayout.addWidget(self.btnJ)
windowLayout.addWidget(self.horizontalGroupBox)
self.setLayout(windowLayout)
self.center_widget()
self.show()
def createGridLayout(self):
font = QFont("Sans Serif", )
font.setPixelSize(18)
self.horizontalGroupBox = QGroupBox()
self.horizontalGroupBox.setFont(font)
layout = QGridLayout()
for i in range(0, len(grid)):
for j in range(0, len(grid[1])):
try:
btn = _QPushButton(str(grid[i][j][0]))
if grid[i][j][1] == 'GREEN':
btn.setStyleSheet(BTN.format('white', 'green'))
layout.addWidget(btn, i, j)
elif grid[i][j][1] == 'RED':
btn.setStyleSheet(BTN.format('white', 'red'))
layout.addWidget(btn, i, j)
except Exception as e:
btn = _QPushButton(str(grid[i][j]))
btn.setStyleSheet(BTN.format('black', 'white'))
layout.addWidget(btn, i, j)
# print(grid[i][j][0], e)
self.horizontalGroupBox.setLayout(layout)
def center_widget(self):
self.window().setGeometry(
QStyle.alignedRect(
Qt.LeftToRight,
Qt.AlignCenter,
self.window().size(),
QApplication.desktop().availableGeometry())
)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
答案 0 :(得分:2)
技巧是使用QFrame
作为基础,并在其中放置按钮:
from PyQt5 import QtWidgets, QtCore, QtGui
import string
grid = [[["text", "GREEN"], 0, ["text", "RED"], 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]
BTN = """QPushButton{{font-weight: bold; color: {};
font-size: 14px; background-color: {};
border-width: 2px; border-radius: 100px}}"""
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.initUI()
self.createLayout()
self.center_widget()
def initUI(self):
p = self.palette()
gradient = QtGui.QLinearGradient(0, 0, 0, 400)
gradient.setColorAt(0.0, QtGui.QColor('#f1f1f1'))
gradient.setColorAt(1.0, QtGui.QColor('#00a1de'))
p.setBrush(QtGui.QPalette.Window, QtGui.QBrush(gradient))
self.setPalette(p)
def createLayout(self):
hlay = QtWidgets.QHBoxLayout(self)
frameL = QtWidgets.QFrame()
vlay = QtWidgets.QVBoxLayout(frameL)
frame = QtWidgets.QFrame()
frame.setObjectName("principal")
frame.setStyleSheet("#principal{border: 2px solid white;}")
hlay.addWidget(frameL)
hlay.addWidget(frame)
gridLayout = QtWidgets.QGridLayout(frame)
h = 60 # height
for i, row in enumerate(grid):
frameButton = QtWidgets.QFrame()
frameButton.setFixedHeight(h)
frameButton.setContentsMargins(0, 0, 0, 0)
lay = QtWidgets.QVBoxLayout(frameButton)
button = QtWidgets.QPushButton("{}".format(string.ascii_uppercase[i]))
button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
lay.addWidget(button)
vlay.addWidget(frameButton)
for j, val in enumerate(row):
gridButton = QtWidgets.QPushButton()
gridButton.setFixedSize(h, h)
if isinstance(val, list):
gridButton.setText(val[0])
if val[1] == "GREEN":
gridButton.setStyleSheet(BTN.format('white', 'green'))
elif val[1] == "RED":
gridButton.setStyleSheet(BTN.format('white', 'red'))
else:
gridButton.setStyleSheet(BTN.format('black', 'white'))
gridButton.setText("{}".format(val))
gridLayout.addWidget(gridButton, i, j)
for ix in range(j + 1):
label = QtWidgets.QLabel("{}".format(ix + 1))
label.setAlignment(QtCore.Qt.AlignCenter)
gridLayout.addWidget(label, i + 1, ix)
vlay.addWidget(QtWidgets.QLabel())
def center_widget(self):
self.window().setGeometry(
QtWidgets.QStyle.alignedRect(
QtCore.Qt.LeftToRight,
QtCore.Qt.AlignCenter,
self.window().size(),
QtWidgets.QApplication.desktop().availableGeometry())
)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())