2021-8-9-Holiday4
第四周日志
这周的重点在了QT的三国杀上,希望自己可以一周左右写完
8.9
QT Creator 和clion
clion单独用各种问题,如Qt5Config.cmake找不到啥的
但是QT Creator太不好用 太丑
所以解决方案就是先在QTCreator里生成cmake项目
但是之前生成一直有问题,说一个编译器都用不上,但是检查过不是编译器的问题,最后发现是cmake没装(以前的话cmake clion有带)
特殊情况:仍然解决不了Qt5Config.cmake找不到
set(CMAKE_PREFIX_PATH "E:/Qt/Qt5.12.11/5.12.11/mingw73_64/lib/cmake/Qt5")
找到Qt5Config.cmake路径,添加上面这句
然后clion里快乐写程序就好了,在creator或者designer里设计,也不用去creator里编译来让.ui转为.h,在cmakelist里有这个转换。当然clion有个小问题,它找不到./ui_mainwindow.h,其实它在一个固定的目录cmake内的目录和项目文件夹在同一层。所以
- 假设生成的目标为
Test,在CMakeLists.txt文件的最后一行添加:
target_include_directories(Test PRIVATE "${CMAKE_BINARY_DIR}/Test_autogen/include")#Test_autogen文件夹名字注意,Test要改成项目名!!
https://blog.csdn.net/weixin_43669941/article/details/108921714
QT0xC0000135错误
编译成功后无法运行缺依赖

里出来了
代码是没问题的,是环境的问题石锤了
解决方案是
编译完成后,在qt里找到windeployqt.exe 运行
windeployqt.exe xxxx.exe
#XXXX.exe就是你编译后的exe
它会把依赖文件复制到编译文件夹内
然后再运行
小插曲是,庭凯教我用release编译后再用windeployqt.exe,反而不行了
然后我把clion对exe的处理方式改为直接运行,发现运行时弹出错误QTGuid.dll缺失,那就复制一个过去就好
(原来直接运行就有缺失dll提示了,其实没必要不断观察少了啥)
(不过windeployqt.exe需要补全很多依赖库,还是先运行一次windeployqt.exe为上策)
编译错误
E:\GitProject\QTPlayer\mainwindow.cpp: In constructor 'MainWindow::MainWindow(QWidget*)':
E:\GitProject\QTPlayer\mainwindow.cpp:6:18: error: invalid use of incomplete type 'class Ui::MainWindow'
, ui(new Ui::MainWindow)
^~~~~~~~~~
In file included from E:\GitProject\QTPlayer\mainwindow.cpp:1:0:
E:\GitProject\QTPlayer\mainwindow.h:7:22: note: forward declaration of 'class Ui::MainWindow'
namespace Ui { class MainWindow; }
^~~~~~~~~~
E:\GitProject\QTPlayer\mainwindow.cpp:8:7: error: invalid use of incomplete type 'class Ui::MainWindow'
ui->setupUi(this);
^~
In file included from E:\GitProject\QTPlayer\mainwindow.cpp:1:0:
E:\GitProject\QTPlayer\mainwindow.h:7:22: note: forward declaration of 'class Ui::MainWindow'
namespace Ui { class MainWindow; }
^~~~~~~~~~
E:\GitProject\QTPlayer\mainwindow.cpp:8:9: error: invalid use of incomplete type 'class Ui::MainWindow'
ui->setupUi(this);
^~~~~~~
In file included from E:\GitProject\QTPlayer\mainwindow.cpp:1:0:
E:\GitProject\QTPlayer\mainwindow.h:7:22: note: forward declaration of 'class Ui::MainWindow'
namespace Ui { class MainWindow; }
^~~~~~~~~~
E:\GitProject\QTPlayer\mainwindow.cpp: In destructor 'virtual MainWindow::~MainWindow()':
E:\GitProject\QTPlayer\mainwindow.cpp:13:12: warning: possible problem detected in invocation of delete operator: [-Wdelete-incomplete]
delete ui;
^~
E:\GitProject\QTPlayer\mainwindow.cpp:13:12: warning: invalid use of incomplete type 'class Ui::MainWindow'
In file included from E:\GitProject\QTPlayer\mainwindow.cpp:1:0:
E:\GitProject\QTPlayer\mainwindow.h:7:22: note: forward declaration of 'class Ui::MainWindow'
namespace Ui { class MainWindow; }
^~~~~~~~~~
E:\GitProject\QTPlayer\mainwindow.cpp:13:12: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
delete ui;
^~
mingw32-make.exe[3]: *** [CMakeFiles\QTPlayer.dir\build.make:122: CMakeFiles/QTPlayer.dir/mainwindow.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:95: CMakeFiles/QTPlayer.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:102: CMakeFiles/QTPlayer.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:136: QTPlayer] Error 2
问题在于我改窗口名字改错地方了,不是下面这里!!

事件绑定connect
https://blog.csdn.net/shenjiecsdn/article/details/50332327
mainwindow.cpp
connect(ui->pushButton,SIGNAL(clicked()), this,SLOT(Quit()));
其中Quit()记得加括号,即使没有括号甚至Quit()函数不存在也只是运行时warning,编译前和编译中没有提示
同时Quit()这个slot信号所绑定的函数,必须在private slots中声明,而不是public。
mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void Quit();
private:
Ui::MainWindow *ui;
};
然后重新定义该函数
mainwindow.cpp
void MainWindow::Quit()
{
ui->pushButton->hide();
}
控件并行动画,动画结束绑定槽
总结性的(没有说明如何写,但是给了启发):https://blog.csdn.net/weixin_42347660/article/details/113314656
先看把串行的记录了:https://www.cnblogs.com/senior-engineer/p/8125300.html
并行动画看看pyqt的例子:https://blog.csdn.net/weixin_30604651/article/details/97860171
并行和串行都要经历两个过程
一是QPropertyAnimation的改变
mainwindow.cpp
QPropertyAnimation *pScaleAnimation1 = new QPropertyAnimation(ui->pushButton, "geometry");//geometry大小位置,pos角度,透明度后面说,见https://blog.csdn.net/weixin_42347660/article/details/113314656
pScaleAnimation1->setDuration(1000);//时间
pScaleAnimation1->setStartValue(QRect(190, 230, 0, 0));//初状态
pScaleAnimation1->setEndValue(QRect(120, 160, 140, 140));//末状态
二是加入组里,然后选择是并行执行还是串行执行,所使用的类也不同
并行的:
mainwindow.h
private:
Ui::MainWindow *ui;
QParallelAnimationGroup *m_group;
mainwindow.cpp
animeGroup = new QParallelAnimationGroup(this);
animeGroup->addAnimation(pScaleAnimation1);
connect(animeGroup, SIGNAL(finished()),this, SLOT(PrepareRoundOfGame()));
animeGroup->start();
已经测试可以多次start,原先按钮位置状态直接移动到初状态
参考:
- https://blog.csdn.net/qq_43401552/article/details/105931242
- https://blog.csdn.net/qq_45662588/article/details/118187201
git分支保留
构建时错误:error: 'QParallelAnimationGroup' does not name a type
#include <QParallelAnimationGroup>
虽然不报错,但是要导入对应模块
8.10
clion日常使用
实施、重写或生成定义
通过 Implement(实现) 函数 (Ctrl+I)、Override (重载)函数 (Ctrl+O) 和 Generate Definitions (成员函数实现)(Shift+Ctrl+D) 感受代码生成的强大威力。
样式表
ui->progressBar->setStyleSheet("border:1px solid #FFFFFF;"
"height:30;"
"background: red;"
"color:rgb(255,255,0);");
用法:
在QT Creator里改样式表的时候,样式代码是:
QProgressBar::chunk //进度条的颜色
{
border-radius:11px;
background:qlineargradient(spread:pad,x1:0,y1:0,x2:1,y2:0,stop:0 #01FAFF,stop:1 #26B4FF); //第一个色号是左端,第二个色号是右端
}
QProgressBar#progressBar //这个控件的背景色
{
height:22px;
text-align:center;/*文本位置*/
font-size:14px;
color:white;
border-radius:11px;
background: #1D5573 ;
}
而在代码里面不能就用setStyleSheet()框主,还要按要求加" "
同时官方的写法是
progressBar->setStyleSheet(QString::fromUtf8("QProgressBar::chunk\n"
"{\n"
"border-radius:11px;\n"
"background:qlineargradient(spread:pad,x1:0,y1:0,x2:1,y2:0,stop:0 #01FAFF,stop:1 #26B4FF);\n"
"}\n"
"QProgressBar#progressBar\n"
"{\n"
"height:22px;\n"
"text-align:center;/*\346\226\207\346\234\254\344\275\215\347\275\256*/\n"
"font-size:14px;\n"
"color:white;\n"
"border-radius:11px;\n"
"background: #1D5573 ;\n"
"}"));
用了QString::fromUtf8保证兼容。
不过建议就在QT Creator里改样式表算了
属性:
border 边框 1像素 填充 白色
height高
background背景色
color progressBar那个百分比数字的颜色
其他的属性:
"border-radius:10px;" // 圆角
text-align: center;" // 控制文本位置left center right
background:qlineargradient线性渐变
对于本次的任务嘛,就主打还原吧,用utools取个色
参考:https://www.codenong.com/cs109445914/
进度条渲染
https://blog.csdn.net/Agou_66/article/details/51259783
https://blog.csdn.net/The_perfect_world/article/details/89526404
void MainWindow::start() {
qtimer->start(100);
ui->progressBar->setValue(100);
}
void MainWindow::timeout() {
temp--;
ui->progressBar->setValue(temp);
if (temp == 0) {
qtimer->stop();
}
}
undefined reference to ’xxx‘
编译时报错,编译前检查没错
这句话的本意就是没有找到定义,有声明
可能性有很多
就说这次的
在4个小时的检查,把include_directories 、add_library、target_link_libraries和link_directories都试了个遍
在jy师兄的观察下终于把问题缩小到
不是头文件没加载,没被引用,没被包含
而是对应的cpp文件没包含



https://www.cnblogs.com/xl2432/p/11225276.html#2-搜索指定目录的所有的cpp文件
上面的博文描述了如何包含cpp(是需要单独来写包含的)
aux_source_directory(./interactive_buttons SRC_LIST) #搜索当前目录下的所有.cpp文件
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(QTCMake
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
else()
if(ANDROID)
add_library(QTCMake SHARED
${PROJECT_SOURCES}
)
else()
add_executable(QTCMake
${PROJECT_SOURCES}
${SRC_LIST}#我们项目是加载最下面这个add_executable
)
endif()
endif()
问题解决
include_directories 、add_library、target_link_libraries和link_directories
https://blog.csdn.net/bigdog_1027/article/details/79113342
include_directories 包含头文件(目录)
add_library 把自己的cpp在编译时生成lib
target_link_libraries 使自己的程序链接链接库
8.11
下面正式开始编程
全系统的设计
本系统设计时已经最大程度考虑后继兼容性
即不需要改变主代码框架也可以实现增加手牌种类,增加英雄及其技能,增加游戏人数和玩法
但是该作品只是demo
所以
本游戏只允许选择一个固定英雄郭嘉(47),其他武将视为白板
对手直接选择刘备,对手会做能做的,桃自己出闪,不会出杀(除非南蛮),会出无懈可击
每次摸两张牌弃两张牌
游戏初始化流程
开始游戏->选择武将->武将技能注册->监听系统注册->开始回合
关于手牌渲染系统
三个状态
在手里,准备打出,打出
关于把鼠标移动上去手牌有效果,两个办法,一是QButton,二是QWeight渲染
两个都可以,特别是前者找到一个继承QButton的库
https://github.com/iwxyi/Qt-InteractiveButtons
MainWindow成员函数无法访问ui下的控件Member access into incomplete type 'Ui::MainWindow'

其实只要#include "./ui_mainwindow.h"即可

产生[a,b]的随机数,可以使用 (rand() % (b-a+1))+a;
画窗口背景
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawPixmap(this->rect(),QPixmap("resource/wallpaper/background.png"));
}
里面那个图片的路径,要求是相对路径
不用怀疑是
./resource/wallpaper/background.png 还是 resource/wallpaper/background.png
因为两个都可以
也不用怀疑这个函数是否没有被加载,只要右侧出现那个重写的符号都可以(不放心就cout一下)
还是显示不出来,就该怀疑一下
资源文件的相对路径,是相对于可执行文件的相对,不是项目目录的相对
换而言之对我项目目录,该图片在
cmake-build-debug-qt/resource/wallpaper/background.png
8.12
按钮的图标
QPixmap icon1(tr("resource/hero/1.png"));
ui->hero1->setIcon(icon1);
ui->hero1->setIconSize(QSize(250, 292));
鼠标移入事件触发自定义函数
虽然最后考虑到所需要的时间没有用该方案,但也记录一下
https://blog.csdn.net/xiezhongyuan07/article/details/80676047
https://www.cnblogs.com/liuruoqian/p/12044571.html
如果只是要按钮的小提示用这个tooltips
https://blog.csdn.net/forchoosen/article/details/103267110
如果只是要移入后按钮图标改变,直接css就好
https://blog.csdn.net/goforwardtostep/article/details/53464925
connect后的slot函数传参问题,用lamba表达式解决
https://blog.csdn.net/qq_38188725/article/details/80686793
表达式基本概念
- [capture]:方括号,其内容是捕捉列表,总是出现在Lambda函数的开始处,是Lambda的引出符。它能够捕捉上下文中的变量供函数体使用。这里可以填入具体的变量名,也可以使用“=”,代表以值传递方式捕捉所有父作用域的变量,还可以使用“&”代表以引用传递方式捕捉所有父作用域的变量。
- (parameters):参数列表,表示传递给函数体的参数。如果不需要参数传递,可以省略这一部分。
mutable:修饰符,默认情况下,Lambda函数是一个const函数,使用mutable可以取消其常量性。比如使用引用传递的时候就可以修改参数值等。使用它时参数列表不可省略,即使无参数传递。 - ->return-type:返回类型。不需要返回或返回类型明确时可以省略这一部分。
- {statement}:函数体,可以使用所有捕获与传递的变量。
connect(ui->card3,&QPushButton::clicked,this,[=]{
cout<<heronum[1];
});
控件透明度
https://blog.csdn.net/WU9797/article/details/78722396
ui->tips->setWindowOpacity(0.3);
对Qlabel我试着不太有效
那就css!
background-color: rgba(255, 255, 255,70);
博客维护
没错,今天花了一个下午和晚上
把博客升级到了4.1.0
跟上了上游仓库的进度
但是事实证明人工手动版本合并
还不如拿自己仓库和上游仓库用beyond compare比较
8.13~8.15
这三天都在练车,能写程序的时间很少
moc_mainwindow.cpp:99: undefined reference to ‘imp
CMakeFiles\QTPlayer.dir/objects.a(mainwindow.cpp.obj): In function `MainWindow::MainWindow(QWidget*)':
E:/GitProject/QTPlayer/mainwindow.cpp:7: undefined reference to `__imp__ZN10QWebSocketC1ERK7QStringN18QWebSocketProtocol7VersionEP7QObject'
E:/GitProject/QTPlayer/mainwindow.cpp:7: undefined reference to `__imp__ZN10QWebSocketD1Ev'
CMakeFiles\QTPlayer.dir/objects.a(mainwindow.cpp.obj): In function `MainWindow::connectServer()':
E:/GitProject/QTPlayer/mainwindow.cpp:16: undefined reference to `__imp__ZN10QWebSocket9connectedEv'
E:/GitProject/QTPlayer/mainwindow.cpp:18: undefined reference to `__imp__ZN10QWebSocket4openERK4QUrl'
CMakeFiles\QTPlayer.dir/objects.a(mainwindow.cpp.obj): In function `MainWindow::onConnected()':
E:/GitProject/QTPlayer/mainwindow.cpp:23: undefined reference to `__imp__ZN10QWebSocket15sendTextMessageERK7QString'
CMakeFiles\QTPlayer.dir/objects.a(mainwindow.cpp.obj): In function `MainWindow::~MainWindow()':
E:/GitProject/QTPlayer/mainwindow.cpp:36: undefined reference to `__imp__ZN10QWebSocketD1Ev'

三类问题,第一是在头文件声明的函数没写定义
(我不是这个问题,而且我觉得这不会导致编译直接过不了)
第二个是编译链同时装了msvc和mingw的库,混合编译了
https://stackoverflow.com/questions/39063110/lots-of-undefined-reference-in-qt-creator
第三种问题和用了websocket等插件类(它是这么描述的)的类功能,需要进行如下修改
find_package(QT NAMES Qt6 Qt5 COMPONENTS WebSockets Widgets REQUIRED)
target_link_libraries(QTPlayer PRIVATE Qt5::Widgets Qt5::WebSockets)
这类似于qt的pro文件里的
QT+=WebSockets
QT调试不能?
QT编译链不能同时装msvc和mingw的
qt 进程已结束,退出代码为 -1073741819 (0xC0000005)

排查后是这句话的问题,也检查过是不是要先设定icon再设置其大小
for(auto & i : HandCardGroup)i->setIconSize(QSize(250, 292));
//或者这个也不行
for(int i=0;i<5;i++)HandCardGroup[i]->setIconSize(QSize(250, 292));
在重装编译链之后终于把不能调试的问题给处理好,然后查了一下这个问题

实际的指针是

很不正常,然后发现声明和定义我写在头文件里,有没有可能当时
还没有初始化按钮new出空间来,程序执行到这里访问野指针了呢
果然是的撒
所以就写在setupUi后就行了
附8.15在车上抽空写的笔记


浙公网安备 33010602011771号