鱼C论坛

 找回密码
 立即注册
查看: 975|回复: 11

[已解决]关于QT5的:副窗口QWidget和QPainter的层次问题

[复制链接]
发表于 2021-11-25 23:40:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x


微信截图_20211125232956.png




如图所示,我的QPainter没有工作在副QWidget窗口,工作在主窗口上面,导致被遮挡,请问应该如何解决这个问题,让QPainter工作与顶部不被遮挡,一下是我的代码demo


  1. # -*- coding: utf-8 -*-

  2. # Form implementation generated from reading ui file 'untitled.ui'
  3. #
  4. # Created by: PyQt5 UI code generator 5.15.6
  5. #
  6. # WARNING: Any manual changes made to this file will be lost when pyuic5 is
  7. # run again.  Do not edit this file unless you know what you are doing.


  8. from PyQt5.QtGui import QPainter, QPen, QColor, QRadialGradient, QBrush
  9. from PyQt5.QtCore import Qt, QPoint
  10. from PyQt5 import QtCore, QtGui, QtWidgets


  11. class Ui_MainWindow(object):
  12.     def setupUi(self, MainWindow):
  13.         MainWindow.setObjectName("MainWindow")
  14.         MainWindow.resize(800, 600)
  15.         self.centralwidget = QtWidgets.QWidget(MainWindow)
  16.         self.centralwidget.setObjectName("centralwidget")
  17.         self.widget = QtWidgets.QWidget(self.centralwidget)
  18.         self.widget.setGeometry(QtCore.QRect(250, 70, 301, 261))
  19.         self.widget.setObjectName("widget")
  20.         self.widget.setStyleSheet("background-color:green;")
  21.         MainWindow.setCentralWidget(self.centralwidget)
  22.         self.menubar = QtWidgets.QMenuBar(MainWindow)
  23.         self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
  24.         self.menubar.setObjectName("menubar")
  25.         MainWindow.setMenuBar(self.menubar)
  26.         self.statusbar = QtWidgets.QStatusBar(MainWindow)
  27.         self.statusbar.setObjectName("statusbar")
  28.         MainWindow.setStatusBar(self.statusbar)

  29.         self.retranslateUi(MainWindow)
  30.         QtCore.QMetaObject.connectSlotsByName(MainWindow)

  31.     def retranslateUi(self, MainWindow):
  32.         _translate = QtCore.QCoreApplication.translate
  33.         MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

  34. class Gomoku(QtWidgets.QMainWindow, Ui_MainWindow):

  35.     def __init__(self, parent=None, *args, **kwargs):
  36.         super().__init__(parent, *args, **kwargs)
  37.         self.setupUi(self)
  38.         #self.paintEvent = self.widget.paintEvent

  39.     def paintEvent(self, e):
  40.         def draw_map():
  41.             """绘制棋盘"""
  42.             qp.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine))  # 棋盘的颜色为黑色
  43.             # 绘制横线
  44.             for x in range(15):
  45.                 qp.drawLine(40 * (x + 1), 40, 40 * (x + 1), 600)
  46.             # 绘制竖线
  47.             for y in range(15):
  48.                 qp.drawLine(40, 40 * (y + 1), 600, 40 * (y + 1))
  49.             # 绘制棋盘中的黑点
  50.             qp.setBrush(QColor(0, 0, 0))
  51.             key_points = [(4, 4), (12, 4), (4, 12), (12, 12), (8, 8)]
  52.             for t in key_points:
  53.                 qp.drawEllipse(QPoint(40 * t[0], 40 * t[1]), 5, 5)

  54.         qp = QPainter()
  55.         qp.begin(self)
  56.         draw_map()  # 绘制棋盘


  57. if __name__ == '__main__':
  58.     import sys
  59.     from PyQt5.QtWidgets import QApplication

  60.     app = QApplication(sys.argv)

  61.     game = Gomoku()

  62.     game.show()

  63.     sys.exit(app.exec_())

复制代码
最佳答案
2021-11-26 12:12:13
  1. # -*- coding: utf-8 -*-

  2. # Form implementation generated from reading ui file 'untitled.ui'
  3. #
  4. # Created by: PyQt5 UI code generator 5.15.6
  5. #
  6. # WARNING: Any manual changes made to this file will be lost when pyuic5 is
  7. # run again.  Do not edit this file unless you know what you are doing.


  8. from PyQt5.QtGui import QPainter, QPen, QColor, QRadialGradient, QBrush
  9. from PyQt5.QtCore import Qt, QPoint
  10. from PyQt5 import QtCore, QtGui, QtWidgets


  11. class Ui_MainWindow(object):
  12.     def setupUi(self, MainWindow):
  13.         MainWindow.setObjectName("MainWindow")
  14.         MainWindow.resize(800, 600)
  15.         self.centralwidget = QtWidgets.QWidget(MainWindow)
  16.         self.centralwidget.setObjectName("centralwidget")

  17.         MainWindow.setCentralWidget(self.centralwidget)
  18.         self.menubar = QtWidgets.QMenuBar(MainWindow)
  19.         self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
  20.         self.menubar.setObjectName("menubar")
  21.         MainWindow.setMenuBar(self.menubar)
  22.         self.statusbar = QtWidgets.QStatusBar(MainWindow)
  23.         self.statusbar.setObjectName("statusbar")
  24.         MainWindow.setStatusBar(self.statusbar)

  25.         self.retranslateUi(MainWindow)
  26.         QtCore.QMetaObject.connectSlotsByName(MainWindow)

  27.     def retranslateUi(self, MainWindow):
  28.         _translate = QtCore.QCoreApplication.translate
  29.         MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


  30. class PWidget(QtWidgets.QWidget):
  31.     def __init__(self, parent=None, *args, **kwargs):
  32.         super().__init__(parent, *args, **kwargs)

  33.     def paintEvent(self, e):
  34.         def draw_map():
  35.             """绘制棋盘"""
  36.             qp.drawRect(self.rect())
  37.             qp.setBackground(QColor("green"))
  38.             qp.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine))  # 棋盘的颜色为黑色
  39.             # 绘制横线
  40.             for x in range(15):
  41.                 qp.drawLine(40 * (x + 1), 40, 40 * (x + 1), 600)
  42.             # 绘制竖线
  43.             for y in range(15):
  44.                 qp.drawLine(40, 40 * (y + 1), 600, 40 * (y + 1))
  45.             # 绘制棋盘中的黑点
  46.             qp.setBrush(QColor(0, 0, 0))
  47.             key_points = [(4, 4), (12, 4), (4, 12), (12, 12), (8, 8)]
  48.             for t in key_points:
  49.                 qp.drawEllipse(QPoint(40 * t[0], 40 * t[1]), 5, 5)

  50.         qp = QPainter()
  51.         qp.begin(self)
  52.         qp.fillRect(self.rect(), QColor("green"))  # 用此绘制背景
  53.         draw_map()  # 绘制棋盘


  54. class Gomoku(QtWidgets.QMainWindow, Ui_MainWindow):
  55.     def __init__(self, parent=None, *args, **kwargs):
  56.         super().__init__(parent, *args, **kwargs)
  57.         self.setupUi(self)
  58.         # self.paintEvent = self.widget.paintEvent
  59.         self.setwidget()  # 调用

  60.     def setwidget(self):
  61.         # 具体的绘制区域有待优化
  62.         # 最好self.centralwidget添加一个布局,此布局添加self.widget
  63.         self.widget = PWidget(self.centralwidget)
  64.         self.widget.setGeometry(QtCore.QRect(250, 70, 301, 261))
  65.         # self.widget.setStyleSheet("background-color:green;")


  66. if __name__ == "__main__":
  67.     import sys
  68.     from PyQt5.QtWidgets import QApplication

  69.     app = QApplication(sys.argv)

  70.     game = Gomoku()

  71.     game.show()

  72.     sys.exit(app.exec_())
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-26 02:14:37 | 显示全部楼层
因为已经放弃PyQt5,转用PySide2了,所以没办法测试代码,盲猜一下吧
根据这个文档https://blog.csdn.net/jia666666/article/details/81566599
  方法                描述
begin()        开始在目标设备上绘制
begin方法要传入一个参数,这个参数就是painter对象工作的控件,所以如果你是想在图中绿色的方块上绘制图像,试试把qp.begin(self)改为qp.begin(self.widget)

但是,从你的描述上,个人理解,你并不是想把棋盘绘制在绿色块上,只是想绘制的棋盘黑线要在绿色方块上方而不是被绿色方块覆盖。如果是这样,看看这篇
https://blog.csdn.net/qq_27061049/article/details/109391064
个人未尝试,因为PyQt5和PySide2同时装的时候用pyinstaller打包时会有莫名其妙的找不到依赖库的错误,所以,我现在基本上已经完全放弃装PyQt5库了
希望以上回答~~对你有所帮助~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-26 07:56:01 | 显示全部楼层
lightninng 发表于 2021-11-26 02:14
因为已经放弃PyQt5,转用PySide2了,所以没办法测试代码,盲猜一下吧
根据这个文档https://blog.csdn.net/ ...

不管是在绿色工作区绘制,还是修改层都已经尝试过了,非常感谢,有其他的方法吗?
  1. self.widget.lower()
  2. self.widget.stackUnder(self.centralwidget)

  3. qp.begin(self.widget)
  4. #这个似乎不会触发事件,尝试过在子类重载,也不行
  5. #self.paintEvent = self.widget.paintEvent
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 09:27:52 | 显示全部楼层
写一个类PWidget,继承QWidget,在里面实现paintEvent,Gomoku里使用该PWidget控件,删除Ui_MainWindow里的QWidget。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 12:12:13 | 显示全部楼层    本楼为最佳答案   
  1. # -*- coding: utf-8 -*-

  2. # Form implementation generated from reading ui file 'untitled.ui'
  3. #
  4. # Created by: PyQt5 UI code generator 5.15.6
  5. #
  6. # WARNING: Any manual changes made to this file will be lost when pyuic5 is
  7. # run again.  Do not edit this file unless you know what you are doing.


  8. from PyQt5.QtGui import QPainter, QPen, QColor, QRadialGradient, QBrush
  9. from PyQt5.QtCore import Qt, QPoint
  10. from PyQt5 import QtCore, QtGui, QtWidgets


  11. class Ui_MainWindow(object):
  12.     def setupUi(self, MainWindow):
  13.         MainWindow.setObjectName("MainWindow")
  14.         MainWindow.resize(800, 600)
  15.         self.centralwidget = QtWidgets.QWidget(MainWindow)
  16.         self.centralwidget.setObjectName("centralwidget")

  17.         MainWindow.setCentralWidget(self.centralwidget)
  18.         self.menubar = QtWidgets.QMenuBar(MainWindow)
  19.         self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
  20.         self.menubar.setObjectName("menubar")
  21.         MainWindow.setMenuBar(self.menubar)
  22.         self.statusbar = QtWidgets.QStatusBar(MainWindow)
  23.         self.statusbar.setObjectName("statusbar")
  24.         MainWindow.setStatusBar(self.statusbar)

  25.         self.retranslateUi(MainWindow)
  26.         QtCore.QMetaObject.connectSlotsByName(MainWindow)

  27.     def retranslateUi(self, MainWindow):
  28.         _translate = QtCore.QCoreApplication.translate
  29.         MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


  30. class PWidget(QtWidgets.QWidget):
  31.     def __init__(self, parent=None, *args, **kwargs):
  32.         super().__init__(parent, *args, **kwargs)

  33.     def paintEvent(self, e):
  34.         def draw_map():
  35.             """绘制棋盘"""
  36.             qp.drawRect(self.rect())
  37.             qp.setBackground(QColor("green"))
  38.             qp.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine))  # 棋盘的颜色为黑色
  39.             # 绘制横线
  40.             for x in range(15):
  41.                 qp.drawLine(40 * (x + 1), 40, 40 * (x + 1), 600)
  42.             # 绘制竖线
  43.             for y in range(15):
  44.                 qp.drawLine(40, 40 * (y + 1), 600, 40 * (y + 1))
  45.             # 绘制棋盘中的黑点
  46.             qp.setBrush(QColor(0, 0, 0))
  47.             key_points = [(4, 4), (12, 4), (4, 12), (12, 12), (8, 8)]
  48.             for t in key_points:
  49.                 qp.drawEllipse(QPoint(40 * t[0], 40 * t[1]), 5, 5)

  50.         qp = QPainter()
  51.         qp.begin(self)
  52.         qp.fillRect(self.rect(), QColor("green"))  # 用此绘制背景
  53.         draw_map()  # 绘制棋盘


  54. class Gomoku(QtWidgets.QMainWindow, Ui_MainWindow):
  55.     def __init__(self, parent=None, *args, **kwargs):
  56.         super().__init__(parent, *args, **kwargs)
  57.         self.setupUi(self)
  58.         # self.paintEvent = self.widget.paintEvent
  59.         self.setwidget()  # 调用

  60.     def setwidget(self):
  61.         # 具体的绘制区域有待优化
  62.         # 最好self.centralwidget添加一个布局,此布局添加self.widget
  63.         self.widget = PWidget(self.centralwidget)
  64.         self.widget.setGeometry(QtCore.QRect(250, 70, 301, 261))
  65.         # self.widget.setStyleSheet("background-color:green;")


  66. if __name__ == "__main__":
  67.     import sys
  68.     from PyQt5.QtWidgets import QApplication

  69.     app = QApplication(sys.argv)

  70.     game = Gomoku()

  71.     game.show()

  72.     sys.exit(app.exec_())
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2021-11-26 12:50:45 | 显示全部楼层
本帖最后由 Stubborn 于 2021-11-26 12:55 编辑
hrpzcf 发表于 2021-11-26 09:27
写一个类PWidget,继承QWidget,在里面实现paintEvent,Gomoku里使用该PWidget控件,删除Ui_MainWindow里的 ...


平常都不接触qt5,想写一个界面的人机五子棋对战,非常感谢大佬的帮助,,对知识并不熟

另外还有一个小疑问,因为后期需要绘制“黑白棋子,”看代码情况,是不是应该在PWidget实现我的绘制棋子的功能
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 12:51:34 | 显示全部楼层
本帖最后由 lightninng 于 2021-11-26 12:55 编辑


赞一个~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 12:56:33 | 显示全部楼层
Stubborn 发表于 2021-11-26 12:50
平常都不接触qt5,想写一个界面的人机五子棋对战,非常感谢大佬的帮助,,对知识并不熟

另 ...

楼主,想问一下。那个绿色块是干嘛的,哈哈哈哈。好像和你的问题无关~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 13:22:59 | 显示全部楼层
本帖最后由 hrpzcf 于 2021-11-26 13:24 编辑
Stubborn 发表于 2021-11-26 12:50
平常都不接触qt5,想写一个界面的人机五子棋对战,非常感谢大佬的帮助,,对知识并不熟

另 ...


在PWidget里实现相关的函数,比如在PWidget写个在某坐标绘制棋子函数def dropChessman(self, t, x, y): ...,主窗口Gomoku里这么调用: self.widget.dropChessman("黑", 1, 2)。如果用到动作信号,主窗口某信号也可以这么连接这个函数(比如按钮xxx):btn_xxx.click.connect(lambda: self.widget.dropChessman("黑", 1, 2))

乍一看比较乱,也许大概应该就是这个样子了,好久不看QT5了,可能有写错的
PS: 也许PWidget里可以把QPainter实例qp保存成实例属性
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 13:26:15 | 显示全部楼层
lightninng 发表于 2021-11-26 12:56
楼主,想问一下。那个绿色块是干嘛的,哈哈哈哈。好像和你的问题无关~~

啊这个,主要是楼主画的背景,我也跟着画了,如果不画背景不好看出来棋盘已经画在widget上了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-26 14:18:09 | 显示全部楼层
本帖最后由 Stubborn 于 2021-11-26 14:19 编辑
lightninng 发表于 2021-11-26 12:56
楼主,想问一下。那个绿色块是干嘛的,哈哈哈哈。好像和你的问题无关~~


五子棋棋盘呐,上面话格子的
1121.png

主窗口还有其他功能
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 16:52:27 | 显示全部楼层
Stubborn 发表于 2021-11-26 14:18
五子棋棋盘呐,上面话格子的

原来如此,是绿色板子上画棋盘~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 17:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表